ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

LobeHub Agent Signal 架构解析:从 source 到 action 的信号驱动运行时

LobeHub Agent Signal 架构解析:从 source 到 action 的信号驱动运行时 LobeHub Agent Signal 架构解析从 source 到 action 的信号驱动运行时【免费下载链接】lobehub LobeHub is your Chief Agent Operator, organizing your agents into 7×24 operations by hiring, scheduling, and reporting on your entire AI team.项目地址: https://gitcode.com/GitHub_Trending/lo/lobehubLobeHub 定位为「Chief Agent Operator」让 Agent 以 7×24 方式持续运转要支撑这一形态就必须把记忆写入、技能管理、夜间复盘等「后台工作」从前台聊天请求中解耦出来。Agent Signal 正是承担这一解耦的信号驱动运行时本文将完整解读其三层包边界共享语义核心 / 服务端实现层 / OTEL 归属层、source → signal → action 的队列式调度模型、scopeKey 去重与静默入队机制以及analyzeIntent参考链的端到端流程帮助读者理解并扩展 LobeHub 中任意事件驱动的 Agent 后台能力。一、整体 Pipeline先建立心智模型Agent Signal 的运行时形态只有一条固定链路。理解下面的三个流水线图是阅读后续所有章节的前提。1. 主链路生产者 → 结果信号 → 可观测投影producer - emitAgentSignalSourceEvent(...) or enqueueAgentSignalSourceEvent(...) - emitSourceEvent(...) - dedupe scope lock source normalization - runtime.emitNormalized(source) - source handlers - signal handlers - action handlers - built-in result signals - observability projection persistence即生产者producer负责发出一个「来源事件」source event入口先做去重dedupe与 scope 锁再完成来源归一化normalization随后进入运行时逐层分发来源处理器解释事实 → 信号处理器产生语义 → 动作处理器执行副作用 → 内置结果信号上报最终被可观测层投影并持久化。2. 异步自迭代分支记忆 / 技能 / 复盘写入对于持久记忆memory、技能skill与自我复盘self-review这类重写入action handler 不做同步落库而是入队一次异步的execAgent运行action.user-memory.handle | action.skill-management.handle | self-iteration source - stamp AgentSignal operation marker - enqueue execAgent - agent.execution.completed with selfIteration finalState - completion policy - buildSelfIterationReceipts(...) - receipt store关键纪律在于即时的运行时链路只为「入队结果」发出signal.action.applied | skipped | failed用户可见的记忆与技能回执receipt是从agent.execution.completed完成事件投影出来的而不是从入队动作本身投影出来的。这一设计避免了「入队成功 ≠ 写入成功」的语义混乱。3. 调度器是队列驱动的不为某一种策略硬编码source node - matching source handlers - dispatch signals/actions - matching signal handlers - dispatch more signals/actions - matching action handlers - ExecutorResult - signal.action.applied | signal.action.skipped | signal.action.failed从源码结构看调度器位于 AgentSignalScheduler.ts运行时主体在 AgentSignalRuntime.ts处理器返回RuntimeProcessorResult见 base/types.ts其中dispatch状态可以携带新的signals与actions继续派发这就是图中「dispatch more signals/actions」的实现基础——调度器本身是通用的行为完全由注册的 policy 决定。核心入口代码apps/server/src/services/agentSignal/index.tsapps/server/src/services/agentSignal/sources/index.tsapps/server/src/services/agentSignal/runtime/AgentSignalScheduler.ts二、包边界三层职责严格分离2.1packages/agent-signal共享语义核心把它当作「共享语义核心」只定义类型、builder 与契约不含任何服务端策略。它提供基础节点类型source、signal、action构建器createSource、createSignal、createAction共享的 source 类型与 payload 目录source-event 信封与 scope 辅助内置结果信号类型运行时结果契约如RuntimeProcessorResult与ExecutorResult。从源码可以确认这些声明base/builders.ts 中createSource/createSignal/createAction会生成带因果链元数据的规范节点——chain字段rootSourceId、parentNodeId、parentSignalId等贯穿三层节点保证任意 action 都能回溯到根 source。执行结果契约在 base/types.ts 中定义得很严格ExecutorResult是判别联合成功或跳过为status: applied | skipped不允许携带error失败为status: failed且必须携带结构化ExecutorError含code、message、retriable、retryAfterMsRuntimeProcessorResult是四态联合wait/dispatch/schedule/conclude分别表达「宿主等待」「继续派发新节点」「调度下一跳」「结束链路」去重结果EmitSourceEventResult同样为判别联合被去重时返回{ deduped: true, reason: duplicate | scope_locked }。推荐阅读顺序packages/agent-signal/src/base/types.tspackages/agent-signal/src/base/builders.tspackages/agent-signal/src/source/sourceTypes.tspackages/agent-signal/src/source/sourceEvent.tspackages/agent-signal/src/source/scopeKey.tspackages/agent-signal/src/types/events.tspackages/agent-signal/src/types/builtin.ts2.2apps/server/src/services/agentSignal服务端实现层这是「服务端自有实现层」拥有source 归一化、hydration 与 renderers策略专属的 signal 与 action 目录中间件注册运行时调度与 guard 后端基于 Redis 的去重、waypoint 与策略状态同步 / 异步执行的服务入口完成态自迭代运行的回执投影与持久化。从目录结构看这些职责对应清晰子目录sources/含buildSource.ts、renderers/、hydration/、runtime/含backend/redisGuard.ts与memoryGuard.ts两种 guard 后端、policies/、services/含selfIteration/completion/、observability/、store/等。2.3packages/observability-otel/src/modules/agent-signalOTEL 归属该模块是 Agent Signal 指标与 tracer 实例的共享 OTEL 归属层对应 packages/observability-otel/src/modules/agent-signal/index.ts保证指标/追踪在包之间的一致性。三、核心词汇Source / Signal / Action / Policy / Procedure3.1 Source被归一化的外部事实Source 是启动整条链路的「被归一化的外部事实」。文档示例包括agent.user.message、runtime.before_step、runtime.after_step、client.runtime.start、bot.message.merged。实际 source 目录比示例更完整。source/sourceTypes.ts 中的AGENT_SIGNAL_SOURCE_TYPES定义了 17 种 source 类型Source 类型典型触发场景agent.user.message用户消息进入反馈分类主入口agent.execution.completed一次 agent 运行完成携带selfIteration终态侧载agent.execution.failedagent 运行失败agent.nightly_review.requested夜间复盘请求agent.self_reflection.requested自我反思请求agent.self_feedback_intent.declaredAgent 主动声明反馈意图memory/skill/gapbot.message.merged外部 bot 平台消息合并runtime.before_step/runtime.after_step运行时步骤前后钩子client.runtime.start/client.runtime.complete客户端运行时生命周期client.gateway.stream_start/step_complete/runtime_end/error客户端网关事件tool.outcome.completed/tool.outcome.failed工具结果每种类型都有强类型 payloadAgentSignalSourcePayloadMap并提供isAgentUserMessageSource、isClientRuntimeStartSource、isToolOutcomeSource等类型收窄函数另外AGENT_SIGNAL_CLIENT_SOURCE_TYPES明确界定了哪些client.*类型可以经认证边缘由浏览器侧生产者发出。定义与构建位置类型与 payloadpackages/agent-signal/src/source/sourceTypes.ts归一化信封packages/agent-signal/src/source/sourceEvent.ts服务端构建apps/server/src/services/agentSignal/sources/buildSource.ts、apps/server/src/services/agentSignal/sources/renderers/builderpackages/agent-signal/src/base/builders.ts3.2 Signal可复用的语义解释Signal 是「语义解释」应当可复用、面向含义而非面向事件。analyzeIntent策略中的例子signal.feedback.satisfaction反馈满意度signal.feedback.domain.memory/signal.feedback.domain.prompt/signal.feedback.domain.skill反馈领域分类服务端自有的 signal 类型定义在 apps/server/src/services/agentSignal/policies/types.ts。3.3 Action具体的副作用Action 是运行时应当执行的「具体副作用」例如action.user-memory.handle。Action handler 通常做三件事检查幂等、调用工具/模型/服务、返回ExecutorResult。3.4 Policy可安装的处理程序束Policy 是一个「可安装的 handler bundle」是把通用运行时组装成功能单元的组合单位例如createAnalyzeIntentPolicy(...)。3.5 Procedure不是运行时类型「Procedure」在此运行时中不是一等类型。这个词只用于描述一个端到端用例定义入口 sourceemit 或 enqueue 该 source将 source 解释为 signals从 signals 规划 actions执行 actions持久化 trace 与 metrics。当有人问「这个流程procedure是什么」时应指向上面的链路并给出具体的 producer、handlers 与执行入口。四、Scope、去重与静默后台工作4.1scopeKey相关工作的串行化边界scopeKey是相关工作的串行化边界用于四处source 去重窗口source 生成期间的 scope 锁运行时 guard 状态队列化处理的 waypoint 持久化。推导规则在 source/scopeKey.ts 中非常明确AgentSignalScopeKey提供五类前缀topic:topicId # 主题级最高优先级 task:taskId # 异步任务级 bot:platform:applicationId:platformThreadId agent:agentId:user:userId user:userId # 最宽泛的认证范围fromProducerInput的推导优先级为topicIdtaskId bot 三元组 agentIduserIduserId全部缺失时返回fallback:global。服务端在 sources/index.ts 复用同一套键常量见 constants.ts运行时上下文见 runtime/context.ts。4.2enqueueAgentSignalSourceEvent让 UI 立即返回当工作应当「安静地」在带外执行时使用enqueueAgentSignalSourceEvent(...)。该路径分四步归一化 source 信封推导或复用scopeKey触发AgentSignalWorkflow之后由runAgentSignalWorkflow执行。从 emitter.ts 的源码可以看到这条链路的真实实现先通过assertAgentUsableBy做安全门防止工作区成员对他人私有 agent 入队事件再经isAgentSignalEnabledForUser特性门feature gate未开启的用户直接返回{ accepted: false }与推导出的scopeKey经createSourceEvent(input)生成规范信封最后AgentSignalWorkflow.triggerRun({ sourceEvent, agentId, userId, workspaceId })入队返回{ accepted: true, scopeKey, workflowRunId }。对比之下同步入口emitAgentSignalSourceEvent会在检查特性门后动态import(./orchestrator)——源码注释解释了原因orchestrator 会拖入 agent-execution / model-runtime 核心子系统其模块初始化即触碰服务端环境变量而 emitter 位于轻量请求路径上静态导入会污染所有导入方。4.3 投递模式由AGENT_RUNTIME_MODE决定queue 模式使用 Upstash Workflow 做持久化执行提供重试与流控local 模式用setTimeout延迟一次进程内运行返回合成的workflowRunId刻意不提供持久化与重试。local 模式使用进程级 source-event store 与运行时 guard 来维持去重、scope 锁、窗口与 action 幂等性——即在没有 Redis 的情况下仍然「可用」且这些保证在单个服务端进程生命周期内有效。workflow 入口apps/server/src/workflows/agentSignal/index.ts 与 apps/server/src/workflows/agentSignal/run.ts。选择准则很直接当 UI 请求应当立即结束、而策略可以在后台跑时这是首选路径。五、参考实例analyzeIntent完整链路以analyzeIntent作为参考链它示范了 source → signal → action → 结果信号的完整形态agent.user.message - feedback satisfaction source handler - signal.feedback.satisfaction - feedback domain signal handler - signal.feedback.domain.* - feedback action planner - action.user-memory.handle | action.skill-management.handle - signal.action.applied | skipped | failed当前策略还包含工具结果投影tool-outcome projection、技能管理skill management、延迟完成态技能合成deferred completion skill synthesis、夜间复盘nightly review与完成态扇出completion fan-outaction.user-memory.handle | action.skill-management.handle - enqueue execAgent with AgentSignal marker - agent.execution.completed - completion policy - buildSelfIterationReceipts(...) - memory | skill | review receipts一个值得注意的细节技能合成支持「停车—恢复」——入站用户消息候选可以在前台链路中被暂存parked等到agent.execution.completed之后再恢复处理此时完整轨迹与工具结果都可用合成质量显著高于只看到单条消息时。该策略的源码分布均位于apps/server/src/services/agentSignal/下策略入口policies/analyzeIntent/index.ts满意度源处理policies/analyzeIntent/feedbackSatisfaction.ts领域分类policies/analyzeIntent/feedbackDomain.ts动作规划policies/analyzeIntent/feedbackAction.ts动作实现policies/analyzeIntent/actions/userMemory.ts、policies/analyzeIntent/actions/skillManagement.ts完成态技能合成policies/analyzeIntent/completionSkillSynthesis.ts完成策略policies/completionPolicy.ts回执构建与投影services/selfIteration/completion/buildSelfIterationReceipts.ts、services/selfIteration/completion/selfIterationCompletionHandler.ts六、入口点选择与实现清单6.1 四个执行入口各司其职结合 SKILL.md 的约定emitAgentSignalSourceEvent(...)服务端生产者需要立即执行 pipeline 时使用executeAgentSignalSourceEvent(...)worker 或受控后端路径已拥有执行时机、可能需要注入自定义 runtime guard 后端时使用enqueueAgentSignalSourceEvent(...)调用方需要快速返回、把事件交给 Upstash Workflow 带外处理时使用emitAgentSignalSourceEventWithStore(...)隔离测试或 eval 中需要绕开环境级 Redis 状态时使用。6.2 新增一个流程的实现路径按架构文档与 SKILL 给出的顺序推进判断用例是同步还是静默后台工作在 source/sourceTypes.ts 定义或复用 source 类型在 policies/types.ts 定义或复用 signal / action 类型用defineSourceHandler、defineSignalHandler、defineActionHandler实现处理器如生产者 payload 需要整形在apps/server/src/services/agentSignal/sources/**增加归一化或 hydration用defineAgentSignalHandlers(...)打包处理器在apps/server/src/services/agentSignal/policies/index.ts注册 policy并在需要时传入运行时工厂增加或更新 emit / enqueue 的入口代码异步自迭代写入时打上 Agent Signal operation marker并从完成路径createSelfIterationCompletionHandler(...)agent.execution.completed的selfIterationfinalState投影用户可见回执补齐可观测性与测试后再视为完成。实现守则来自技能规范与源码契约的共同约束先复用已有 source / signal / action 类型再考虑新增source handler 只负责解释与扇出不放重副作用action handler 负责副作用、幂等与 executor 风格的结果上报同一 source 可能多次到达时使用稳定的 id 与幂等键保持 scope 纪律运行时用scopeKey串行化相关后台工作不要从入队动作投影 memory / skill 回执——必须走完成事件在触达的 runtime / policy / store 模块附近补测试apps/server/src/services/agentSignal/**/__tests__下现有用例如scopeKey.test.ts、triggerSourceEvent.test.ts、index.integration.test.ts是参照模式。七、延伸阅读地图围绕本文主题仓库中值得继续深入的位置语义核心导出packages/agent-signal/src/index.ts运行时与中间件runtime/AgentSignalRuntime.ts、runtime/middleware.tsguard 后端runtime/backend/redisGuard.ts、runtime/backend/memoryGuard.ts可观测投影observability/projector.ts、observability/traceEvents.ts配套技能文档handlers 写法参考、observability 参考、架构原文小结Agent Signal 用一个「source → signal → action → 结果信号」的固定形状把 LobeHub 中所有事件驱动的 Agent 后台工作统一为可组合、可去重、可幂等、可观测的队列式管道scopeKey保证相关工作的串行化纪律AGENT_RUNTIME_MODE决定持久化与重试的级别而 memory/skill 回执「只从完成事件投影」的规则则保证了用户可见状态的最终一致性。掌握这套词汇与边界即可在 LobeHub 中安全地扩展任何新的 Agent 后台能力。【免费下载链接】lobehub LobeHub is your Chief Agent Operator, organizing your agents into 7×24 operations by hiring, scheduling, and reporting on your entire AI team.项目地址: https://gitcode.com/GitHub_Trending/lo/lobehub创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进