Skip to content

消息流与工具调用 ​

本文引用的源码文件

本文引用的文件

更新摘要 ​

变更内容

  • 增强了工具预筛选器的 JSON 信封恢复机制,新增 recoverAnswerEnvelopeData 和 looksLikePreselectEnvelope 函数
  • 改进了对 AI 模型响应不一致的容错处理能力
  • 更新了工具预筛选算法以支持新的 JSON 格式并增强向后兼容性
  • 完善了错误处理和降级策略

目录 ​

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能与并发优化
  8. 故障排查指南
  9. 结论
  10. 附录:协议与状态定义

引言 ​

本文面向"从用户输入到 LLM 响应"的完整消息流转,重点解释 Chrome 扩展端(Manifest V3 Service Worker)与独立本地 Agent 服务之间的 HTTP/WebSocket 通信契约、ReAct 推理循环中的思考-行动-观察序列、工具参数校验与结果聚合、工具预筛选算法、并行执行优化、超时控制、消息去重、重试策略与性能监控指标。文档同时给出时序图、工具调用状态图和错误传播路径,帮助读者在理解整体架构的同时定位具体实现位置。

项目结构 ​

本项目采用双进程架构:

  • Chrome 扩展端(src/):Service Worker 入口 background/index.js,负责 ReAct 循环、工具调度、侧边栏 UI 状态、保活与自动续跑。
  • 本地 Agent 端(agent/src/):Node.js 服务 agent/src/server.js,提供文件系统、命令执行、MCP 工具注册、RAG 等能力,并通过 WebSocket 推送命令输出。
graph TB
subgraph "Chrome 扩展端"
SW["Service Worker<br/>background/index.js"]
RL["ReAct 循环<br/>background/react-loop.js"]
TE["工具执行器<br/>background/tool-executor.js"]
PS["工具预筛选<br/>background/tool-preselector.js"]
SC["流式控制器<br/>background/stream-controller.js"]
AC["Agent 客户端<br/>background/local-agent-client.js"]
SP["侧边栏 UI<br/>side_panel/chat-manager.js / chat-streaming.js"]
end
subgraph "本地 Agent 端"
AGS["HTTP + WebSocket 服务器<br/>agent/src/server.js"]
EXE["命令执行器<br/>agent/src/executor.js"]
end
SP --> SW
SW --> RL
RL --> PS
RL --> TE
TE --> AC
AC --> AGS
AGS --> EXE
RL --> SC
SC --> SP

图示来源

章节来源

核心组件 ​

  • ReAct 推理循环:background/react-loop.js 维护多轮迭代、流式解析、工具调用、循环检测、子任务计划与恢复。
  • 工具执行器:background/tool-executor.js 统一工具定义、动态 MCP/RAG 工具注入、并行执行、确认门控、审计日志。
  • 工具预筛选:background/tool-preselector.js 通过轻量模型调用判断是否需要工具及选择哪些工具,减少上下文压力,新增 JSON 信封恢复机制。
  • Agent 客户端:background/local-agent-client.js 封装 HTTP/WebSocket 认证、请求超时、可达性缓存、MCP/RAG API。
  • 流式控制器:background/stream-controller.js 解析 SSE、节流发送、tool_calls 累积、usage 提取、空闲超时保护。
  • 侧边栏 UI:side_panel/chat-manager.js 与 chat-streaming.js 负责消息渲染、流式更新、工具卡片、执行日志面板。
  • Agent 服务端:agent/src/server.js 提供 REST 路由、CORS、认证、文件上传、命令执行、MCP/RAG 集成。
  • 命令执行器:agent/src/executor.js 管理子进程、流式 stdout/stderr、超时策略、进程组终止。

章节来源

架构总览 ​

下图展示一次典型请求从侧边栏发起,经过 Service Worker、ReAct 循环、工具执行、Agent 服务、命令执行,再返回流式响应的完整链路。

sequenceDiagram
participant UI as "侧边栏 UI<br/>chat-manager.js / chat-streaming.js"
participant SW as "Service Worker<br/>index.js"
participant RL as "ReAct 循环<br/>react-loop.js"
participant PS as "工具预筛选<br/>tool-preselector.js"
participant TE as "工具执行器<br/>tool-executor.js"
participant AC as "Agent 客户端<br/>local-agent-client.js"
participant AGS as "Agent 服务器<br/>server.js"
participant EXE as "命令执行器<br/>executor.js"
UI->>SW : 发送 CALL_API / 启动 ReAct
SW->>RL : reactLoop(messages, model, tools, ...)
RL->>PS : preselectTools(可选)
PS-->>RL : 直接回答 或 选定工具集
RL->>TE : executeTool(toolName, args)
TE->>AC : agentRequest('/api/...') 或 createExecWebSocket()
AC->>AGS : HTTP POST /api/fs|/api/exec|/api/mcp/call
AGS->>EXE : spawn 子进程 / 流式输出
EXE-->>AGS : stdout/stderr/exit
AGS-->>AC : JSON 响应 或 WS 事件
AC-->>TE : {success, content/error}
TE-->>RL : 工具结果
RL->>SC : StreamController.feedLine()
SC-->>UI : STREAM_START / STREAM_CHUNK / STREAM_TOOL_CALL / STREAM_DONE

图示来源

详细组件分析 ​

ReAct 推理循环:思考-行动-观察 ​

ReAct 循环是消息流的核心编排器:

  • 每轮先构建系统提示与历史,调用 LLM 获取内容增量或 tool_calls。
  • 若检测到 tool_calls,立即通知前端显示工具卡片,随后按顺序或并行执行工具,将结果作为 observation 回注消息。
  • 支持子任务 plan_task 拆分、循环检测、反思评估、checkpoint 持久化与自动续跑。
flowchart TD
Start(["进入 reactLoopImpl"]) --> BuildCtx["构建消息上下文<br/>含历史/压缩/引用"]
BuildCtx --> CallLLM["调用 LLMSSE 流式"]
CallLLM --> HasTool{"是否包含 tool_calls?"}
HasTool --> |否| EmitContent["输出文本/推理内容"]
EmitContent --> NextIter["下一轮迭代"]
HasTool --> |是| ExecTools["执行工具串行/并行"]
ExecTools --> Observe["收集工具结果并追加为 tool 消息"]
Observe --> NextIter
NextIter --> LoopCheck{"达到最大迭代/超时/循环检测?"}
LoopCheck --> |是| Finish(["结束并保存 checkpoint/清理"])
LoopCheck --> |否| CallLLM

图示来源

章节来源

工具预筛选算法 ​

当工具数量超过固定阈值时,预筛选会调用轻量模型决定"直接回答"还是"需要工具",并返回候选工具名列表;若无法解析或结果为空,则回退为全量工具。新增的 JSON 信封恢复机制显著提升了容错能力。

flowchart TD
A["收到 messages/tools"] --> B{"工具数 > PRESELECT_MIN_TOOL_COUNT?"}
B --> |否| Skip["跳过预筛选,使用全部工具"]
B --> |是| Extract["提取最近用户问题与历史上下文"]
Extract --> Prompt["构建预筛选 prompt"]
Prompt --> ModelCall["调用模型response_format=json_object"]
ModelCall --> Parse["解析 JSON:answer 或 tools"]
Parse --> |answer| Direct["直接回答,不二次调用"]
Parse --> |tools| Match["按名称匹配工具集合"]
Match --> Fallback{"匹配为空?"}
Fallback --> |是| AllTools["回退为全部工具"]
Fallback --> |否| Selected["返回筛选后的工具集"]

更新 新增了 JSON 信封恢复机制,包括 recoverAnswerEnvelopeData 和 looksLikePreselectEnvelope 函数,用于处理 AI 模型响应不一致的情况。

图示来源

章节来源

JSON 信封恢复机制 ​

新增功能 工具预筛选器现在具备强大的 JSON 信封恢复能力,能够处理 AI 模型响应中的格式错误:

flowchart TD
RawText["原始模型响应"] --> TryParse["尝试 JSON.parse"]
TryParse --> |成功| ValidJSON["有效 JSON 对象"]
TryParse --> |失败| CheckEnvelope["检查是否为预筛选信封"]
CheckEnvelope --> |是| RecoverData["recoverAnswerEnvelopeData 恢复数据"]
CheckEnvelope --> |否| Fallback["回退到旧格式提取"]
RecoverData --> |成功| AnswerType["返回 answer 类型"]
RecoverData --> |失败| Malformed["标记为畸形信封"]
ValidJSON --> ProcessType["处理 type/data 字段"]
ProcessType --> AnswerOrTools["answer 或 tools 类型"]

新增的关键函数:

  • looksLikePreselectEnvelope(text):检测文本是否像 {type,data} 预筛选信封但 JSON.parse 已失败
  • recoverAnswerEnvelopeData(text):从格式错误的信封中提取 data 字符串内容,支持反转义常见序列

章节来源

工具参数验证与结果聚合 ​

  • 参数解析:工具 handler 中通过 tryParseToolArgs 等辅助函数解析 arguments,兼容字符串与对象两种格式。
  • 安全校验:网络访问受内网白名单限制;敏感操作需用户确认;命令执行走 Agent 端安全检查与安全环境变量白名单。
  • 结果聚合:工具执行结果以 tool 消息追加到当前会话;执行日志节点记录成功/失败、耗时、stdout/stderr 摘要;子任务失败时生成部分产出摘要供父任务继续。
flowchart TD
Args["工具入参arguments"] --> Parse["解析与类型转换"]
Parse --> Validate["业务校验/安全门控"]
Validate --> |通过| Execute["执行工具浏览器/Agent/MCP/RAG"]
Validate --> |拒绝| Error["返回错误结果"]
Execute --> Result["标准化结果content/error"]
Result --> Log["写入执行日志节点"]
Log --> Append["追加为 tool 消息"]

图示来源

章节来源

Chrome 扩展端与 Agent 服务的通信协议 ​

  • HTTP 认证:所有需认证的请求携带 Authorization: Bearer <token>,Token 由配对流程获得并加密存储。
  • 主要端点:/api/pair、/api/status、/api/fs/、/api/exec、/api/mcp/、/api/skill/、/api/rag/、/api/files/upload。
  • WebSocket:/api/exec 可建立 WS 连接,实时推送 stdout/stderr/exit;Token 通过查询参数传递。
  • CORS:仅允许 chrome-extension:// 来源跨域读取响应,防止恶意网页窃取无认证接口数据。
sequenceDiagram
participant AC as "Agent 客户端<br/>local-agent-client.js"
participant AGS as "Agent 服务器<br/>server.js"
AC->>AGS : POST /api/pair {code, extensionId}
AGS-->>AC : {success, token}
AC->>AGS : GET /api/status (无认证)
AGS-->>AC : {version, platform, ragAvailable}
AC->>AGS : POST /api/fs/read/write/list/delete/search (Bearer Token)
AGS-->>AC : {success, content/error}
AC->>AGS : POST /api/exec (Bearer Token)
AGS-->>AC : {execId}
AC->>AGS : ws : //host : port?token=...
AGS-->>AC : {type : stdout|stderr|exit|error}

图示来源

章节来源

工具调用状态图 ​

工具调用经历创建、等待确认(可选)、执行、流式输出、完成/失败、取消/超时等状态。

stateDiagram-v2
[*] --> 待执行
待执行 --> 等待确认 : requiresConfirmation=true
等待确认 --> 已确认 : 用户同意
等待确认 --> 已拒绝 : 用户拒绝/超时/面板关闭
待执行 --> 执行中 : 无需确认 或 已确认
执行中 --> 流式输出 : stdout/stderr 开始
流式输出 --> 已完成 : exitCode=0
流式输出 --> 已失败 : exitCode!=0 或异常
执行中 --> 已取消 : 用户停止/会话取消
执行中 --> 已超时 : 代理端预算耗尽/扩展端保险上限
已确认 --> 已取消
已拒绝 --> [*]
已完成 --> [*]
已失败 --> [*]
已取消 --> [*]
已超时 --> [*]

图示来源

章节来源

错误传播路径 ​

  • 扩展端 fetch 超时/网络错误:local-agent-client.js 返回 success=false 与本地化错误文案,并附加 httpStatus 区分 404 与离线。
  • Agent 端认证失败:server.js 返回 401/403,security 模块记录审计日志。
  • 命令执行失败:executor.js 广播 error/exit,扩展端根据 exitCode/killed/timedOut 构造用户可见结果。
  • 流式空闲超时:stream-controller.js 抛出 StreamIdleTimeout,react-loop.js 捕获后中断并提示重试。
  • 新增 工具预筛选 JSON 信封恢复失败:回退为全量工具,避免将畸形信封透传给 UI。
flowchart TD
NetErr["网络/超时错误"] --> ClientErr["local-agent-client 返回错误"]
AuthFail["认证失败"] --> ServerErr["server.js 返回 401/403"]
ExecErr["命令异常"] --> WSErr["WS 广播 error/exit"]
IdleTO["流式空闲超时"] --> StreamErr["stream-controller 抛出异常"]
MalformedJSON["预筛选 JSON 信封恢复失败"] --> Fallback["回退全量工具"]
ClientErr --> UI["侧边栏显示错误"]
ServerErr --> UI
WSErr --> UI
StreamErr --> UI
Fallback --> UI

图示来源

章节来源

依赖关系分析 ​

  • background/index.js 作为 Service Worker 入口,协调 keepalive、自动续跑、侧边栏可见性、定时任务与 checkpoint 清理。
  • background/react-loop.js 依赖 tool-executor.js 获取工具与执行工具,依赖 stream-controller.js 解析 SSE,依赖 local-agent-client.js 进行 Agent 通信。
  • background/tool-executor.js 动态注入 MCP/RAG 工具,维护 PARALLELIZABLE_TOOLS 与 CONFIRMATION_REQUIRED_TOOLS。
  • background/tool-preselector.js 提供增强的 JSON 信封恢复能力,处理 AI 模型响应不一致的情况。
  • side_panel/chat-manager.js 与 chat-streaming.js 消费 STREAM_* 消息,渲染思考过程、工具卡片与执行日志。
  • agent/src/server.js 作为 HTTP+WebSocket 网关,分发到 executor.js、mcp registry、skill registry、memory routes、rag detect/install。
graph LR
Index["background/index.js"] --> ReactLoop["background/react-loop.js"]
ReactLoop --> ToolExec["background/tool-executor.js"]
ReactLoop --> StreamCtrl["background/stream-controller.js"]
ToolExec --> LocalAgent["background/local-agent-client.js"]
LocalAgent --> AgentServer["agent/src/server.js"]
AgentServer --> Executor["agent/src/executor.js"]
ToolPreselector["background/tool-preselector.js"] --> Index
ChatMgr["side_panel/chat-manager.js"] --> ChatStream["side_panel/chat-streaming.js"]
ChatStream --> ReactLoop

图示来源

章节来源

性能与并发优化 ​

  • 工具预筛选:当工具数量超过 PRESELECT_MIN_TOOL_COUNT(默认 10)时触发,减少 LLM 上下文压力与无效工具调用。
  • 并行执行:PARALLELIZABLE_TOOLS 标记的工具可并行执行,提升吞吐;CONFIRMATION_REQUIRED_TOOLS 强制串行确认。
  • 流式节流:StreamController 的 streamChunkDelay 控制字符级渲染频率,避免 UI 抖动。
  • 空闲超时:STREAM_IDLE_TIMEOUT_MS 防止流式数据卡住;Agent 命令执行采用"有输出才延长"的策略,静默即杀。
  • 消息去重:tool_call.id 唯一键与 inFlightConfirmKeys 防止重复确认;completedProcesses 缓存回放避免重复输出。
  • 重试策略:fetchWithRetry 支持指数退避;preselectTools 与 react-loop 对 API 失败进行降级处理。
  • 新增 JSON 信封恢复:显著提升对 AI 模型响应不一致的容错能力,减少因格式错误导致的失败率。

章节来源

故障排查指南 ​

  • Service Worker 生命周期:keepalive port 用于保活;SW 重启后通过 SW_RESTARTED 通知侧边栏,支持从 checkpoint 恢复。
  • 配对与连通性:pair 失败、代理未配对、代理服务未连接等错误由 local-agent-client.js 本地化提示;可达性缓存避免频繁探测。
  • 命令执行超时:executor.js 的 decideTimeoutAction 基于输出心跳延长预算;扩展端 toolTimeout 为保险上限。
  • 流式卡顿:STREAM_IDLE_TIMEOUT_MS 触发空闲超时;检查网络与服务提供商稳定性。
  • 侧边栏不可见:isPanelVisibleToUser 与焦点镜像确保通知可见性;快捷键 toggle 需手势上下文。
  • 新增 工具预筛选 JSON 信封错误:检查 AI 模型响应格式,查看 recoverAnswerEnvelopeData 是否能成功恢复数据。

章节来源

结论 ​

本方案通过 ReAct 循环编排思考-行动-观察序列,结合工具预筛选、并行执行、流式输出与严格的超时控制,实现了从用户输入到 LLM 响应的稳定、可观测、可扩展的消息流。新增的 JSON 信封恢复机制显著提升了系统的鲁棒性,能够有效处理 AI 模型响应不一致的问题。Chrome 扩展端与 Agent 服务之间通过带认证的 HTTP/WebSocket 协议交互,支持文件、命令、MCP 工具与 RAG 能力。错误传播路径清晰,具备自动续跑、消息去重与重试机制,适合复杂自动化场景。

附录:协议与状态定义 ​

  • HTTP 端点:/api/pair、/api/status、/api/fs/、/api/exec、/api/mcp/、/api/skill/、/api/rag/、/api/files/upload。
  • WebSocket:/api/exec 建立连接,推送 stdout/stderr/exit/error。
  • 认证:Authorization: Bearer <token>;配对码一次性认证。
  • 工具状态:待执行 → 等待确认 → 执行中 → 流式输出 → 已完成/已失败/已取消/已超时。
  • 新增 预筛选响应格式:支持 {type: "answer", data: "..."} 和 {type: "tools", data: [...]} 新格式,以及向后兼容的旧格式。

章节来源