Skip to content

Agent 服务架构 ​

本文引用的源码文件

本文引用的文件

目录 ​

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能与资源管理
  8. 故障排查指南
  9. 结论

引言 ​

本文件面向“AI Helper”的双进程架构中的独立本地代理端(Agent),版本为 2.3.1。Agent 是独立的 Node.js 服务,提供 HTTP 与 WebSocket 接口,供 Chrome 扩展端调用本地文件系统、系统命令执行、长期记忆、RAG 知识库、MCP 工具与技能系统。文档重点解释:

  • 独立 Node.js 服务的设计模式与请求处理管道;
  • HTTP/WebSocket 服务器实现;
  • 认证机制、Token 验证流程与权限控制;
  • 命令执行引擎的安全分级、进程树管理与资源隔离;
  • 配置管理、环境变量与运行时参数注入;
  • 服务启动、优雅重启、监控日志与错误处理;
  • 与 Chrome 扩展端的通信契约、协议版本兼容性与错误传播策略。

项目结构 ​

Agent 源码位于 agent/src,入口为 server.js,通过 bin/agent.js 暴露 CLI 命令(start/stop/status)。扩展端通过 src/background/local-agent-client.js 封装 HTTP/WebSocket 调用,并通过 tool-executor.js 将命令执行纳入 ReAct 工具链。

graph TB
subgraph "Chrome 扩展端"
BG["background/local-agent-client.js"]
TE["background/tool-executor.js"]
end
subgraph "Agent 服务Node.js"
BIN["bin/agent.js"]
SRV["server.js"]
AUTH["auth.js"]
SEC["security.js"]
EXEC["executor.js"]
CFG["config.js"]
PT["process-tree.js"]
end
BG --> |"HTTP /api/*"| SRV
BG --> |"WebSocket /ws/exec/:id"| SRV
TE --> BG
BIN --> SRV
SRV --> AUTH
SRV --> SEC
SRV --> EXEC
SRV --> CFG
EXEC --> PT

图示来源

章节来源

核心组件 ​

  • HTTP 路由与中间件:统一解析 body、CORS、国际化语言、认证校验、业务路由分发。
  • 认证模块:配对码轮换、Token 生成与持久化、活跃连接判定。
  • 安全网关:路径沙箱、白名单/硬阻止、命令黑白灰名单分级。
  • 命令执行器:子进程管理、流式输出、超时策略、跨平台终止。
  • 配置管理:内存缓存、写锁、敏感字段加密落盘。
  • 进程树工具:npm 等子进程整树终止,避免孤儿进程。
  • 扩展端客户端:多代理管理、可达性缓存、HTTP/WebSocket 封装。

章节来源

架构总览 ​

Agent 服务采用“单进程 + 模块化子系统”的架构:

  • server.js 作为 HTTP 路由器与 WebSocket 升级入口;
  • auth.js 负责配对与 Token 生命周期;
  • security.js 提供路径与命令安全策略;
  • executor.js 管理子进程与流式输出;
  • config.js 提供带缓存与写锁的配置读写;
  • process-tree.js 提供进程树终止能力;
  • 扩展端 local-agent-client.js 封装所有 API 调用,并维护多代理状态。
sequenceDiagram
participant Ext as "扩展端"
participant Client as "local-agent-client.js"
participant Server as "server.js"
participant Auth as "auth.js"
participant Sec as "security.js"
participant Exec as "executor.js"
Ext->>Client : 发起命令执行请求
Client->>Server : POST /api/exec {command,cwd,force,timeoutMs}
Server->>Auth : verifyToken(Bearer)
Auth-->>Server : extId
Server->>Sec : checkCommand(command, force)
Sec-->>Server : level=allow|confirm|deny
alt deny
Server-->>Client : {success : false,level : "deny"}
else confirm
Server-->>Client : {success : true,level : "confirm",reason}
Ext->>Client : 用户确认后重试 force=true
Client->>Server : POST /api/exec {force : true,...}
Server->>Exec : executeCommand(...)
Exec-->>Server : execId, wsUrl
Server-->>Client : {execId, wsUrl}
else allow
Server->>Exec : executeCommand(...)
Exec-->>Server : execId, wsUrl
Server-->>Client : {execId, wsUrl}
end

图示来源

详细组件分析 ​

认证机制与 Token 验证流程 ​

  • 配对码生成与轮换:使用密码学安全的随机数生成 6 位配对码,支持定时刷新;当存在已配对且最近活跃的扩展时暂停轮换。
  • 配对请求:校验失败次数限制,达到阈值后临时锁定并立即轮换配对码;成功后保存扩展 ID 与 Token,再次轮换配对码。
  • Token 验证:每次请求从 Bearer Token 中解析扩展 ID,更新 lastAuthTime 以维持“插件在线”状态。
flowchart TD
Start(["开始"]) --> GenCode["生成配对码<br/>crypto.randomBytes"]
GenCode --> RotateTimer["定时轮换配对码"]
RotateTimer --> PairReq{"收到配对请求?"}
PairReq --> |否| RotateTimer
PairReq --> |是| CheckLock{"是否处于锁定窗口?"}
CheckLock --> |是| Deny["拒绝:tooFrequent"]
CheckFailCount{"失败计数 >= 阈值?"}
CheckLock --> |否| CheckFailCount
CheckFailCount --> |是| LockAndRotate["锁定 + 立即轮换配对码"]
CheckFailCount --> |否| ValidateCode{"配对码正确?"}
ValidateCode --> |否| IncFail["失败计数+1"]
ValidateCode --> |是| SavePairing["保存扩展ID与Token"]
IncFail --> RotateTimer
SavePairing --> RotateTimer

图示来源

章节来源

权限控制系统与安全网关 ​

  • 路径沙箱:
    • 硬阻止目录:Agent 系统目录、配置文件、日志、回收站等不可访问;
    • 工作目录永远放行;
    • allowedPaths 白名单前缀匹配;
    • realpath 防符号链接绕过;
    • 对新建/不存在路径做父目录递归探测。
  • 命令分级管控:
    • 黑名单:绝对禁止(如 rm -rf /、格式化磁盘、fork bomb、shebang 直接执行、curl/wget | sh 等);
    • 灰名单:需用户确认(sudo、rm -rf、git push -f、npm i -g、eval、kill、systemctl、脚本执行等);
    • 白名单:普通命令直接放行;
    • 链式命令拆分、包装器剥壳、解释器内联载荷、命令替换 $( ) 与反引号均送检。
flowchart TD
A["输入命令"] --> B["collectCommandScopes<br/>原始串 + 链式拆分 + 内联载荷"]
B --> C{"命中黑名单?"}
C --> |是| D["deny不可绕过"]
C --> |否| E{"force 模式?"}
E --> |是| F["allow跳过灰名单"]
E --> |否| G{"命中灰名单?"}
G --> |是| H["confirm需用户确认"]
G --> |否| I["allow"]

图示来源

章节来源

命令执行引擎与进程树管理 ​

  • 子进程选择:根据平台与环境变量选择 bash/zsh/fish/cmd/powershell,确保 shell 真实存在。
  • 流式输出:stdout/stderr 实时广播给 WebSocket 客户端,缓冲区上限 5MB,超限标记 truncated。
  • 超时策略:
    • 旧语义:commandTimeout 到期直接杀进程;
    • 受管模式:根据 decideTimeoutAction 决策 extend/kill,期内有输出才延长,静默即杀;
    • 最大延长次数与总预算封顶。
  • 进程终止:
    • Unix:SIGTERM 到进程组,5s 后 SIGKILL;
    • Windows:taskkill /T /PID,必要时 /F 强制;
    • process-tree.js 提供通用整树终止能力,用于 npm 安装等场景。
classDiagram
class Executor {
+executeCommand(command, cwd, wsClient, onComplete, collectOutput, execOpts) string
+executeCommandSync(command, cwd, timeoutMs) Promise
+addWsClient(execId, wsClient) bool
+disconnectWsClient(execId, wsClient) bool
+killProcess(execId) bool
+detachProcess(execId) bool
+getRunningProcesses() Array
}
class ProcessTree {
+killProcessTree(child, signal) bool
+stopProcessTree(child, options) Promise
}
Executor --> ProcessTree : "使用整树终止"

图示来源

章节来源

配置管理系统与运行时参数注入 ​

  • 配置加载:内存缓存 + mtime 检测,首次启动写入默认配置;
  • 写锁:并发写保护,防止 TOCTOU;
  • 敏感字段:memoryEmbedding.apiKey 与 pairings.token 落盘前混淆,内存中保持明文;
  • 自动允许列表:skills 与 workspace 目录自动加入 allowedPaths;
  • 环境变量:executor 构建 SAFE_ENV_KEYS 白名单,过滤宿主敏感信息,强制 TERM=dumb、FORCE_COLOR=0。

章节来源

服务启动流程图 ​

flowchart TD
S["CLI bin/agent.js start"] --> L["loadConfig()"]
L --> M["setConsoleOutput(true)"]
M --> N["initSearchTools()"]
N --> O["detectRagAvailable()"]
O --> P["http.createServer(handleRequest)"]
P --> Q["WebSocketServer({noServer:true})"]
Q --> R["listen(port, host)"]
R --> T["startPairCodeRotation()"]
T --> U["startPeriodicCleanup()"]
U --> V["initializeMcpRegistry()"]
V --> W["initializeSkillRegistry()"]

图示来源

章节来源

请求处理时序图 ​

sequenceDiagram
participant C as "扩展端"
participant CL as "local-agent-client.js"
participant S as "server.js"
participant A as "auth.js"
participant X as "executor.js"
C->>CL : agentRequest('/api/exec', body)
CL->>S : POST /api/exec (Bearer token)
S->>A : verifyToken(token)
A-->>S : extId
S->>X : executeCommand(command, cwd, null, cb, false, {timeoutMs})
X-->>S : execId, wsUrl
S-->>CL : {success : true, execId, wsUrl}
CL->>S : WebSocket /ws/exec/{execId}?token=...
S->>X : addWsClient(execId, ws)
X-->>S : stdout/stderr/exit 事件
S-->>CL : 流式消息推送

图示来源

章节来源

权限验证流程图 ​

flowchart TD
Req["HTTP 请求"] --> CORS{"OPTIONS/CORS?"}
CORS --> |是| AllowCors["返回允许头"]
CORS --> |否| PathCheck{"路径免认证?"}
PathCheck --> |是| HandlePublic["处理公开接口"]
PathCheck --> |否| AuthCheck{"Authorization: Bearer ?"}
AuthCheck --> |否| Deny401["401 noToken"]
AuthCheck --> |是| Verify["verifyToken(token)"]
Verify --> |null| Deny403["403 invalidToken"]
Verify --> |extId| Route["路由分发"]

图示来源

章节来源

与 Chrome 扩展端的通信契约 ​

  • 认证:
    • 配对:POST /api/pair,返回 token;
    • 健康检查:GET /api/status(无认证,仅返回必要平台信息);
    • 详细状态:GET /api/status/detail(需认证,含 workdir、allowedPaths、runningProcesses 等)。
  • 文件系统:
    • /api/fs/read/write/list/delete/search_files/search_content/download/download-stream/mkdir/rename/move/preview-xlsx;
    • /api/files/upload(multipart/form-data);
    • /api/fs/upload-stream(raw binary,path 通过 query 传递)。
  • 命令执行:
    • /api/exec(异步/同步 wait)、/api/exec/stop、/api/exec/detach;
    • WebSocket /ws/exec/{execId},token 通过 Authorization 或 ?token= 传递。
  • MCP/Skill/RAG/Memory:
    • /api/mcp/、/api/skill/、/api/rag/、/api/memory/。

章节来源

依赖关系分析 ​

  • server.js 依赖 auth.js、security.js、executor.js、config.js、logger.js、search.js、rag/detect.js、memory/routes.js、mcp/registry.js、skill/registry.js、skill/loader.js、i18n.js。
  • executor.js 依赖 child_process、os、crypto、config.js、i18n.js。
  • security.js 依赖 path、fs/promises、os、config.js、i18n.js。
  • auth.js 依赖 crypto、config.js、i18n.js、sys-lang.js。
  • config.js 依赖 os、path、fs、i18n.js、crypto-lite.js。
  • process-tree.js 依赖 child_process。
  • local-agent-client.js 依赖 shared/logger、shared/i18n、shared/secret。
graph LR
SERVER["server.js"] --> AUTH["auth.js"]
SERVER --> SEC["security.js"]
SERVER --> EXEC["executor.js"]
SERVER --> CFG["config.js"]
EXEC --> PT["process-tree.js"]
CLIENT["local-agent-client.js"] --> SERVER

图示来源

章节来源

性能与资源管理 ​

  • 文件上传:
    • multipart/form-data 与 raw binary 流式上传,Content-Length 与实际接收大小双重校验;
    • 脚本文件写入后剥离执行权限(chmod 0o644)。
  • 下载优化:
    • 大文件使用 createReadStream 流式传输;
    • 目录打包为 zip,分块写入避免一次性 res.end(buffer)。
  • 命令输出缓冲:
    • stdout/stderr 缓冲区上限 5MB,超限标记 truncated 并广播提示;
    • completedProcesses 缓存已完成进程输出,支持延迟连接的 WS 客户端回放。
  • 超时与保活:
    • 命令执行超时策略支持 extend/kill;
    • WebSocket 心跳 ping/pong 检测半开连接,30s 未响应则 terminate。
  • 优雅关闭:
    • 停止配对码轮换、回收站清理、RAG 安装、运行进程、MCP 连接;
    • 强制断开所有 WebSocket 与活跃 HTTP socket;
    • 10s 超时兜底 process.exit(1)。

章节来源

故障排查指南 ​

  • 认证失败:
    • 401 noToken:缺少 Authorization 头或格式错误;
    • 403 invalidToken:Token 无效或未配对;
    • 检查 /api/pair 配对流程与 pairings.json 是否有效。
  • 命令被拦截:
    • deny:命中黑名单(破坏性目标);
    • confirm:命中灰名单,需在扩展端弹出用户确认框;
    • 使用 force=true 可跳过灰名单,但黑名单仍不可绕过。
  • 进程卡住:
    • 检查 commandTimeout 与 decideTimeoutAction 策略;
    • 使用 /api/exec/stop 或 detach 显式控制;
    • 查看 runningProcesses 列表定位 execId。
  • 文件操作失败:
    • 403 pathNotInAllowedDir:路径不在 allowedPaths;
    • 404 fileNotFound:文件不存在;
    • 400 contentTooLarge/fileTooLarge:超出大小限制。
  • 服务无法启动:
    • EADDRINUSE:端口占用;
    • 检查 bin/agent.js 启动逻辑与 server.js listen 回调。

章节来源

结论 ​

Agent 服务通过清晰的模块化设计实现了高内聚、低耦合的本地代理能力。其安全模型以路径沙箱与命令分级为核心,结合 Token 认证与 CORS 限制,有效防护恶意网页与横向攻击。命令执行引擎支持流式输出、超时策略与跨平台进程树管理,保障资源隔离与稳定性。配置管理提供内存缓存与写锁,敏感字段加密落盘,环境变量白名单过滤。扩展端客户端封装了完整的 HTTP/WebSocket 契约,支持多代理管理与可达性缓存。整体架构在安全性、性能与可维护性之间取得平衡,适合作为 Chrome 扩展的本地能力扩展层。