主题
消息处理管道
本文引用的源码文件
本文引用的文件
目录
引言
本文面向“从用户输入到 LLM 响应”的完整消息处理管道,覆盖以下关键主题:
- 消息类型系统:用户消息、系统消息、工具调用消息与结果消息的结构与流转。
- 意图识别与工具预筛选:如何根据上下文选择候选工具集合。
- 工具执行协调:参数校验、并行执行、超时控制、错误重试与确认门控。
- 消息路由:本地工具、远程 Agent 请求与浏览器 API 调用的分发策略。
- 状态管理:待发送、执行中、完成、失败等状态转换规则。
- 审计日志:执行时间追踪、Token 统计与调试信息收集。
- 压缩与优化:上下文截断、重复消息去重与缓存机制。
本项目的双进程架构为 Chrome 扩展端(Manifest V3)+ 独立本地代理端 Agent;扩展端通过 HTTP/WebSocket 调用 Agent 的文件读写、命令执行、长期记忆与 RAG 能力。Agent 源码修改后必须重启进程新接口才生效。
项目结构
围绕消息处理管道的核心代码集中在 background 层:
- index.js:Service Worker 入口、侧边栏与面板生命周期、保活端口、自动续跑与 checkpoint 恢复。
- react-loop.js:ReAct 推理循环、API 调用、流式响应、循环检测、子任务编排与检查点持久化。
- tool-executor.js:工具定义、动态注册(MCP/RAG)、工具执行、网络访问安全门控、审计记录。
- agent-dispatcher.js:子 Agent 调度,派生会话隔离、深度限制与结果截断。
- local-agent-client.js:与 Agent 的 HTTP/WebSocket 通信封装、认证、超时与可达性缓存。
- stream-controller.js:SSE 流式读取与空闲超时控制。
- token-recorder.js:Token 用量统计。
- activity-store.js:活动存储与审计日志写入。
- shared/tools.js:默认 ReAct 配置与模型常量。
graph TB UI["侧边栏/面板"] --> BG["Background Service Worker<br/>index.js"] BG --> RL["ReAct 推理循环<br/>react-loop.js"] RL --> TE["工具执行器<br/>tool-executor.js"] RL --> SC["流控制器<br/>stream-controller.js"] RL --> TR["Token 记录器<br/>token-recorder.js"] RL --> AS["活动存储/审计<br/>activity-store.js"] TE --> AC["本地 Agent 客户端<br/>local-agent-client.js"] TE --> AD["子 Agent 调度器<br/>agent-dispatcher.js"] AC --> AG["本地 Agent 服务"]
图表来源
- src/background/index.js#L1-L120
- src/background/react-loop.js#L734-L752
- src/background/tool-executor.js#L547-L651
- src/background/local-agent-client.js#L399-L443
章节来源
- src/background/index.js#L1-L120
- src/background/react-loop.js#L734-L752
- src/background/tool-executor.js#L547-L651
- src/background/local-agent-client.js#L399-L443
核心组件
- Background 入口(index.js)
- 负责 SW 保活、侧边栏可见性、自动续跑闹钟、checkpoint 清理与恢复。
- 维护 keepalive 端口,用于定向消息与面板实例身份上报。
- ReAct 推理循环(react-loop.js)
- 对外入口 reactLoop 包装心跳与自动续跑;内部实现 reactLoopImpl 驱动多轮对话、工具调用、流式响应、循环检测、子任务计划与进度。
- 负责消息清洗、上下文预算、Token 估算与截断、检查点持久化与恢复。
- 工具执行器(tool-executor.js)
- 统一工具定义与执行映射;支持 MCP/RAG 工具动态注册;内置网络访问白名单与安全提示。
- 提供 executeTool、fetchWithRetry、审计记录 recordToolStats、appendAuditLog 等能力。
- 本地 Agent 客户端(local-agent-client.js)
- 封装 /api/* 与 WebSocket 通信;认证、超时、可达性缓存、MCP/RAG 相关接口。
- 子 Agent 调度器(agent-dispatcher.js)
- 基于 sessionId 派生子会话,限制嵌套深度,构建系统提示词并调用 ReAct 或直连非流式 API。
- 流控制器(stream-controller.js)
- SSE 流读取、空闲超时、流式中断与结束信号。
- Token 记录器(token-recorder.js)
- 统计每次 API 调用的输入/输出 Token 用量。
- 活动存储(activity-store.js)
- 追加审计日志、记录工具执行统计,供前端展示与诊断。
章节来源
- src/background/index.js#L56-L120
- src/background/react-loop.js#L734-L800
- src/background/tool-executor.js#L547-L651
- src/background/local-agent-client.js#L399-L443
- src/background/agent-dispatcher.js#L100-L218
- src/background/stream-controller.js#L1-L120
- src/background/token-recorder.js#L1-L120
- src/background/activity-store.js#L1-L120
架构总览
下图展示一次典型请求从用户输入到 LLM 响应的端到端流程,包括工具预筛选、意图识别、工具执行、流式响应与审计记录。
sequenceDiagram participant User as "用户" participant Panel as "侧边栏/面板" participant BG as "Background(index.js)" participant RL as "ReAct循环(react-loop.js)" participant TE as "工具执行器(tool-executor.js)" participant AC as "本地Agent(local-agent-client.js)" participant Stream as "流控制器(stream-controller.js)" participant Store as "活动存储(activity-store.js)" participant Token as "Token记录(token-recorder.js)" User->>Panel : 输入消息 Panel->>BG : 发起 CALL_API/REACT 请求 BG->>RL : reactLoop(messages, model, tools, ...) RL->>TE : getTools()/preselectTools() RL->>Stream : 发起流式 API 调用 Stream-->>RL : 增量片段(SSE) RL->>Store : appendAuditLog(执行节点) RL->>Token : recordTokenUsage(输入/输出统计) RL->>TE : executeTool(工具名, 参数) alt 本地工具 TE-->>RL : 工具结果 else 远程Agent/MCP TE->>AC : agentRequest/callMcpTool AC-->>TE : 返回结果 TE-->>RL : 工具结果 end RL-->>Panel : 最终内容/执行日志
图表来源
- src/background/index.js#L1-L120
- src/background/react-loop.js#L734-L800
- src/background/tool-executor.js#L547-L651
- src/background/local-agent-client.js#L399-L443
- src/background/stream-controller.js#L1-L120
- src/background/activity-store.js#L1-L120
- src/background/token-recorder.js#L1-L120
详细组件分析
消息类型系统与数据流
- 用户消息(role=user)
- 由侧边栏/面板构造,携带用户输入与可选附件(如截图、URL)。
- 在 ReAct 循环中作为当前消息序列的一部分发送给 LLM。
- 系统消息(role=system)
- 包含全局提示、技能注入、子 Agent 系统提示词等。
- 由 react-loop 与 agent-dispatcher 构建,影响模型行为与工具使用策略。
- 工具调用消息(assistant.tool_calls)
- LLM 返回的工具调用列表,包含工具名与参数(可能为字符串或对象)。
- react-loop 解析参数、进行参数校验与确认门控,再交由 tool-executor 执行。
- 工具结果消息(role=tool)
- 工具执行结果回写至消息序列,供下一轮 LLM 决策。
- 同时写入活动存储与审计日志,附带执行时间与状态。
flowchart TD
Start(["开始"]) --> BuildUser["构建用户消息"]
BuildUser --> InjectSystem["注入系统提示/技能"]
InjectSystem --> SendLLM["发送到 LLM"]
SendLLM --> HasToolCalls{"是否包含工具调用?"}
HasToolCalls -- "否" --> ReturnContent["直接返回内容"]
HasToolCalls -- "是" --> ParseArgs["解析工具参数"]
ParseArgs --> Validate["参数校验与安全门控"]
Validate --> ConfirmGate{"是否需要用户确认?"}
ConfirmGate -- "需要" --> ShowConfirm["显示确认对话框"]
ShowConfirm --> Confirmed{"用户确认?"}
Confirmed -- "否" --> AbortTool["中止工具执行"]
Confirmed -- "是" --> ExecuteTool["执行工具"]
ConfirmGate -- "不需要" --> ExecuteTool
ExecuteTool --> Route{"路由类型"}
Route -- "本地工具" --> LocalExec["本地执行"]
Route -- "远程Agent/MCP" --> RemoteCall["HTTP/WebSocket 调用"]
Route -- "浏览器API" --> BrowserAPI["浏览器 API 调用"]
LocalExec --> AppendResult["追加工具结果消息"]
RemoteCall --> AppendResult
BrowserAPI --> AppendResult
AppendResult --> NextRound["进入下一轮推理"]
NextRound --> End(["结束"])
ReturnContent --> End
AbortTool --> End
图表来源
- src/background/react-loop.js#L242-L250
- src/background/react-loop.js#L285-L450
- src/background/tool-executor.js#L547-L651
- src/background/local-agent-client.js#L399-L443
章节来源
- src/background/react-loop.js#L242-L250
- src/background/react-loop.js#L285-L450
- src/background/tool-executor.js#L547-L651
- src/background/local-agent-client.js#L399-L443
意图识别与工具预筛选
- 工具预筛选(tool-preselector.js)
- 根据当前上下文与用户输入,从全量工具集中筛选候选工具,减少 LLM 的干扰项。
- 支持会话级强制下发的 MCP 工具补回(mergeForcedMcpTools),确保用户显式指定的工具不被丢弃。
- 意图识别
- 由 LLM 自身判断是否需要工具调用;若需要,则生成 assistant.tool_calls。
- react-loop 对 tool_calls 进行解析与校验,必要时触发用户确认。
flowchart TD
A["用户输入 + 历史消息"] --> Preselect["工具预筛选"]
Preselect --> ForcedMerge["合并会话强制 MCP 工具"]
ForcedMerge --> CandidateTools["候选工具集"]
CandidateTools --> LLM["LLM 意图识别"]
LLM --> ToolCalls{"是否产生工具调用?"}
ToolCalls -- "是" --> Execute["执行工具"]
ToolCalls -- "否" --> Content["直接生成内容"]
图表来源
章节来源
工具调用协调机制
- 参数验证
- react-loop 解析 tool_call.arguments(字符串或对象),tool-executor 对必填字段进行校验,缺失时返回结构化错误。
- 并行执行
- 标记为 parallelizable 的工具可并行执行;react-loop 在子任务层面支持 sequential/parallel/dependency 策略。
- 超时控制
- 工具执行超时(TOOL_TIMEOUT_MS)、ReAct 循环总超时(loopTimeout)、流式空闲超时(STREAM_IDLE_TIMEOUT_MS)。
- 错误重试
- fetchWithRetry 对网络请求进行重试;工具执行失败时记录审计日志并向上抛出异常。
- 确认门控
- 敏感工具(如 manage_tab、agent_exec)需用户确认;未确认或超时则 fail-closed。
flowchart TD
Start(["工具调用入口"]) --> Parse["解析参数"]
Parse --> Validate["参数校验"]
Validate --> Gate{"敏感操作?"}
Gate -- "是" --> Confirm["用户确认"]
Confirm --> Confirmed{"已确认?"}
Confirmed -- "否" --> Fail["返回失败"]
Confirmed -- "是" --> Exec["执行工具"]
Gate -- "否" --> Exec
Exec --> Timeout{"是否超时?"}
Timeout -- "是" --> Retry["重试/降级"]
Timeout -- "否" --> Result["返回结果"]
Retry --> Result
Result --> Audit["记录审计日志"]
Audit --> End(["结束"])
图表来源
- src/background/react-loop.js#L490-L501
- src/background/tool-executor.js#L547-L651
- src/background/constants.js#L1-L120
章节来源
- src/background/react-loop.js#L490-L501
- src/background/tool-executor.js#L547-L651
- src/background/constants.js#L1-L120
消息路由逻辑
- 本地工具调用
- 由 tool-executor 直接执行,如浏览器 API、内存查询、RAG 检索等。
- 远程 Agent 请求
- 通过 local-agent-client 调用 /api/* 接口,支持文件读写、命令执行、MCP 工具调用。
- 浏览器 API 调用
- 通过 chrome.* API 直接操作标签页、书签、历史记录等。
graph LR TE["工具执行器"] --> Local["本地工具"] TE --> Agent["远程 Agent"] TE --> Browser["浏览器 API"] Agent --> HTTP["HTTP/WebSocket"] Browser --> Chrome["Chrome 扩展 API"]
图表来源
章节来源
消息状态管理
- 状态定义
- processing:执行中
- success:成功
- error:失败
- cancelled:取消
- 状态转换规则
- 工具执行开始时标记为 processing;完成后转为 success 或 error;用户取消或超时转为 cancelled。
- 子任务计划(subtask_plan)豁免裁剪,确保历史视图可展示未执行的子任务。
- 检查点与恢复
- react-loop 定期保存 checkpoint(含 currentMessages、executionLog、subtaskPlan 等);SW 重启后可自动续跑。
stateDiagram-v2 [*] --> 待发送 待发送 --> 执行中 : "开始工具执行" 执行中 --> 完成 : "执行成功" 执行中 --> 失败 : "执行失败/超时" 执行中 --> 已取消 : "用户取消/确认拒绝" 完成 --> [*] 失败 --> [*] 已取消 --> [*]
图表来源
章节来源
代码示例路径
- 构建消息对象
- 参考 react-loop 中构建 system/user/assistant/tool 消息的路径。
- 调用工具
- 参考 tool-executor 中 executeTool 与 MCP/RAG 工具注册路径。
- 处理响应
- 参考 stream-controller 中 SSE 流式读取与 react-loop 中流式结果聚合路径。
章节来源
- src/background/react-loop.js#L734-L800
- src/background/tool-executor.js#L547-L651
- src/background/stream-controller.js#L1-L120
依赖关系分析
- 组件耦合
- react-loop 依赖 tool-executor、stream-controller、token-recorder、activity-store。
- tool-executor 依赖 local-agent-client、constants、config。
- agent-dispatcher 依赖 react-loop、local-agent-client、shared/agent-defaults。
- 外部依赖
- Chrome 扩展 API(tabs、sidePanel、storage、runtime)。
- Agent 服务(HTTP/WebSocket)。
- LLM 提供商(OpenAI 兼容 API)。
graph TB RL["react-loop.js"] --> TE["tool-executor.js"] RL --> SC["stream-controller.js"] RL --> TR["token-recorder.js"] RL --> AS["activity-store.js"] TE --> AC["local-agent-client.js"] TE --> CT["constants.js"] TE --> CFG["config.js"] AD["agent-dispatcher.js"] --> RL AD --> AC
图表来源
- src/background/react-loop.js#L1-L21
- src/background/tool-executor.js#L1-L23
- src/background/agent-dispatcher.js#L1-L12
章节来源
- src/background/react-loop.js#L1-L21
- src/background/tool-executor.js#L1-L23
- src/background/agent-dispatcher.js#L1-L12
性能与优化
- 上下文截断
- 使用 truncateByTokens、trimMessagesByBudget 控制消息长度,避免超出模型窗口。
- 重复消息去重
- 工具结果缓存(toolResultCache)在同一轮对话内避免重复执行相同工具。
- 缓存机制
- MCP 工具描述压缩(compressDescription、compressProperties、compressMcpSchema)减少上下文占用。
- Agent 可达性缓存(_agentReachability)避免频繁健康检查。
- 流式优化
- stream-controller 支持空闲超时与增量推送,降低长连接资源占用。
章节来源
- src/background/react-loop.js#L764-L767
- src/background/tool-executor.js#L464-L543
- src/background/local-agent-client.js#L100-L139
- src/background/stream-controller.js#L1-L120
故障排查指南
- SW 静默重启
- 通过 keepalive 端口检测 SW 重启,恢复 checkpoint 并通知面板。
- 工具执行超时
- 检查 TOOL_TIMEOUT_MS 与 fetchWithRetry 配置,查看审计日志中的执行时间。
- 确认对话框未弹出
- 检查 keepalive 端口是否建立,面板是否可见,确认超时是否触发。
- Agent 不可达
- 检查 _agentReachability 状态,确认配对与令牌配置,查看 health check 日志。
章节来源
- src/background/index.js#L140-L218
- src/background/react-loop.js#L490-L501
- src/background/local-agent-client.js#L100-L139
结论
本消息处理管道以 ReAct 推理循环为核心,结合工具预筛选、参数校验、并行执行、超时控制与确认门控,实现了从用户输入到 LLM 响应的完整闭环。通过本地工具、远程 Agent 与浏览器 API 的多路路由,以及审计日志与 Token 统计,系统在功能性与可观测性之间取得平衡。上下文截断、缓存与流式优化进一步提升了性能与稳定性。