以下为本文档的中文说明
Agent Signal 是 LobeHub 开发的一个事件驱动型后台任务技能,用于在不阻塞前台对话的情况下实现 Agent 的异步处理。它的核心架构遵循一个一致的数据流模式:从信号源(Source)捕获事件、信号解释(Signal Interpretation)、执行动作(Action Execution)、产生内置结果信号。这个流水线允许 Agent 处理各种事件源,定义信号和动作类型,配置策略规则,使用中间件进行数据转换,以及实现工作流交接和去重功能。关键入口点包括:使用 emitAgentSignalSourceEvent() 让服务端拥有的生产者立即执行流水线,以及使用 executeAgentSignal() 等 API 手动触发信号处理。该技能还内置了可观测性支持,包括追踪、指标收集、调试和工作流快照可视化。Agent Signal 适用于需要将后台处理与前端对话解耦的场景,比如长时间运行的数据处理、定时任务触发、事件驱动的自动化工作流等。它的设计理念是将 Agent 的能力从单一的对话式交互扩展到持续运行的后台服务,让 Agent 能够在无人值守的情况下自主响应事件和执行任务,是构建自主 AI 系统的关键基础设施。
Agent Signal
Use this skill to implement event-driven background work for agents without coupling the work to the foreground chat request.
Agent Signal has one consistent shape:
source event->signal interpretation->action execution-> built-in result signals
Start Here
- Read
references/architecture.mdto map the package boundary, runtime queue, scope model, and async workflow handoff. - Read
references/handlers.mdbefore writing any new policy, source handler, signal handler, or action handler. - Read
references/observability.mdwhen you need tracing, metrics, debugging, or workflow snapshot visibility.
Use The Right Entry Point
- Use
emitAgentSignalSourceEvent(...)when a server-owned producer should execute the pipeline immediately. - Use
executeAgentSignalSourceEvent(...)when a worker or controlled backend path already owns execution timing and may inject a runtime guard backend. - Use
enqueueAgentSignalSourceEvent(...)when the caller should return quickly and let Upstash Workflow process the event out-of-band. - Use
emitAgentSignalSourceEventWithStore(...)for isolated tests or evals that should avoid ambient Redis state.
Read:
apps/server/src/services/agentSignal/index.tsapps/server/src/workflows/agentSignal/index.tsapps/server/src/workflows/agentSignal/run.ts
Core Model
source: A normalized fact that happened. Sources come from producers such as runtime lifecycle events, user messages, or bot ingress.signal: A semantic interpretation derived from one source or from another signal. Signals express meaning, routing, or policy state.action: A concrete side effect planned from one signal. Actions do the work.policy: An installable middleware bundle that registers source, signal, and action handlers.procedure: Not a distinct runtime node. Treat “procedure” as the end-to-end flow for one use case: ingress source, matching handlers, planned actions, execution result, and observability.
Keep the boundaries strict:
- Add a new
sourcewhen the outside world produced a new event. - Add a new
signalwhen the system needs a reusable semantic interpretation. - Add a new
actionwhen the runtime needs a concrete side effect. - Add or update a
policywhen you are wiring those pieces together.
Implementation Workflow
- Decide whether the use case is synchronous or quiet background work.
- Define or reuse a source type in
apps/server/src/services/agentSignal/sourceTypes.ts. - Define or reuse signal and action types in
apps/server/src/services/agentSignal/policies/types.ts. - Implement handlers with
defineSourceHandler,defineSignalHandler, ordefineActionHandler. - Bundle handlers with
defineAgentSignalHandlers(...). - Register the policy in
apps/server/src/services/agentSignal/policies/index.tsand pass it into the runtime factory if needed. - Add or update ingress code that emits or enqueues the source event.
- Add observability and tests before considering the flow complete.
Default Reading Set
- Shared semantic core:
packages/agent-signal/src/index.tspackages/agent-signal/src/base/builders.tspackages/agent-signal/src/base/types.ts - Server-owned runtime and middleware:
apps/server/src/services/agentSignal/runtime/AgentSignalRuntime.tsapps/server/src/services/agentSignal/runtime/AgentSignalScheduler.tsapps/server/src/services/agentSignal/runtime/middleware.tsapps/server/src/services/agentSignal/runtime/context.ts - Existing policy example:
apps/server/src/services/agentSignal/policies/analyzeIntent/index.tsapps/server/src/services/agentSignal/policies/analyzeIntent/feedbackSatisfaction.tsapps/server/src/services/agentSignal/policies/analyzeIntent/feedbackDomain.tsapps/server/src/services/agentSignal/policies/analyzeIntent/feedbackAction.tsapps/server/src/services/agentSignal/policies/analyzeIntent/actions/userMemory.ts - Observability:
apps/server/src/services/agentSignal/observability/projector.tsapps/server/src/services/agentSignal/ob servability/traceEvents.tspackages/observability-otel/src/modules/agent-signal/index.ts
Implementation Rules
- Reuse existing source, signal, and action types before adding new ones.
- Keep source handlers focused on interpretation and fan-out, not heavy side effects.
- Keep action handlers responsible for side effects, idempotency, and executor-style result reporting.
- Use stable ids and idempotency keys when the same source can arrive more than once.
- Preserve scope discipline. The runtime uses
scopeKeyto serialize related background work. - Prefer the dedicated shared package types and builders from
@lobechat/agent-signalfor normalized nodes and result contracts. - Add focused tests near the touched runtime, policy, or store module. Existing tests under
apps/server/src/services/agentSignal/**/__tests__are the reference pattern.
References
- Architecture and boundaries:
references/architecture.md - Writing handlers and policies:
references/handlers.md - Observability, metrics, and debugging:
references/observability.md
3e:[“","","","L41”,null,{“content”:“$42”,“frontMatter”:{“name”:“agent-signal”,“description”:“Build or extend LobeHub Agent Signal pipelines. Use for signal sources, signal/action types, policies, middleware, workflow handoff, dedupe, scope behavior, or observability.”}}]
3f:[“KaTeX parse error: Expected '}', got 'EOF' at end of input: …,"children":[["”,“div”,null,{“className”:“flex items-center justify-between border-b border-border bg-muted/30 px-4 py-2.5”,“children”:[[“KaTeX parse error: Expected '}', got 'EOF' at end of input: …","children":["”,“span”,null,{“className”:“truncate text-xs font-medium text-muted-foreground”,“children”:“同仓库更多 Skills”}]}],[“KaTeX parse error: Expected 'EOF', got '}' at position 88: …ldren":"同仓库"}]]}̲],["”,“div”,null,{“className”:“p-4 sm:p-5”,“children”:[[“","h2",null,"id":"related−skills−heading","className":"text−2xlfont−semiboldtracking−normaltext−foreground","children":"同仓库更多Skills"],["","h2",null,{"id":"related-skills-heading","className":"text-2xl font-semibold tracking-normal text-foreground","children":"同仓库更多 Skills"}],["","h2",null,"id":"related−skills−heading","className":"text−2xlfont−semiboldtracking−normaltext−foreground","children":"同仓库更多Skills"],["”,“div”,null,{“className”:“mt-4 grid gap-3 sm:grid-cols-2”,“children”:[“L43","L43","L43","L44”,“L45","L45","L45","L46”,“L47","L47","L47","L48”]}]]}]]}]
49:I[206516,[“/_next/static/chunks/051aanbhrv4br.js”,“/_next/static/chunks/0mizr60h7ayzt.js”,“/_next/static/chunks/0v9lm1dmbdoo-.js”,“/_next/static/chunks/0rxr1j1j3j-.r.js”,“/_next/static/chunks/02ftybezfvqjd.js”,“/_next/static/chunks/0.v9ksvnnj8ia.js”,“/_next/static/chunks/0bn6id96nx3k.js",“/_next/static/chunks/13ybnhn37c.tc.js”,“/_next/static/chunks/0_fnrdtruz8uf.js”,“/_next/static/chunks/0r6l15utt1mwb.js”,“/_next/static/chunks/0dm9a5into854.js”,"/_next/static/chunks/07k6hqoibtcn.js”,“/next/static/chunks/0b4cao.4y…j.js”,“/_next/static/chunks/02i-n28z7kjd0.js”],“default”]