Hermes-Agent 源码架构分析报告
1. 项目总览
| 指标 |
数值 |
| Python 文件总数(排除测试) |
822 |
| Python 代码总行数(排除测试) |
~589,563 |
| 核心模块数 |
9 |
| 模型提供方(providers) |
29 个插件目录 |
| 内置技能(skills) |
18 个分类目录 |
| 可选技能(optional-skills) |
19 个分类目录 |
| 支持的消息平台 |
20+ |
核心模块:agent / hermes_cli / plugins / gateway / tools / acp_adapter / tui_gateway / providers / cron
2. 模块详细分析
2.1 agent/ — 核心智能体模块(134 文件,~82,905 行)
项目心脏,负责完整的 AI 智能体对话循环。
2.1.1 对话引擎
| 文件 |
核心功能 |
| conversation_loop.py (~4,800 行) |
对话主循环:一轮完整的 "模型调用→工具执行→重试→压缩" 循环 |
| agent_init.py (~1,845 行) |
AIAgent 初始化:60+ 参数的属性设置、供应商自动检测 |
| agent_runtime_helpers.py |
运行时辅助:模型切换等 |
| turn_context.py |
轮次上下文构建 |
| turn_retry_state.py |
轮次重试状态管理 |
| turn_finalizer.py |
轮次收尾逻辑 |
| iteration_budget.py |
迭代预算控制(防止无限循环) |
| error_classifier.py |
API 错误分类(FailoverReason 枚举) |
2.1.2 系统提示与上下文
| 文件 |
核心功能 |
| system_prompt.py |
系统提示组装:三层结构 stable/context/volatile |
| prompt_builder.py |
提示词构建器:SOUL.md 身份、工具引导、环境提示 |
| context_compressor.py |
上下文压缩器:接近上下文窗口时触发摘要 |
| context_engine.py |
上下文引擎抽象接口:可插拔,允许第三方替换 |
| context_references.py |
上下文引用解析 |
| coding_context.py |
编码场景上下文 |
| conversation_compression.py |
对话压缩触发与反馈管理 |
| memory_manager.py |
内存管理器 |
2.1.3 模型适配层
| 文件 |
核心功能 |
| anthropic_adapter.py |
Anthropic Messages API 适配 |
| gemini_native_adapter.py |
Gemini 原生 API 适配 |
| gemini_schema.py |
Gemini JSON Schema 转换 |
| bedrock_adapter.py |
AWS Bedrock 适配 |
| azure_identity_adapter.py |
Azure 身份认证适配 |
| codex_responses_adapter.py |
OpenAI Codex/Responses API 适配 |
| codex_runtime.py |
Codex 运行时配置 |
| moonshot_schema.py |
Moonshot/Kimi Schema 处理 |
| lmstudio_reasoning.py |
LM Studio 推理模型适配 |
| chat_completion_helpers.py |
Chat Completions API 辅助 |
| transports/ |
API 传输层:多传输协议统一抽象 |
| lsp/ |
LSP 语言服务协议集成 |
2.1.4 工具调度与安全
| 文件 |
核心功能 |
| tool_executor.py |
工具执行器 |
| tool_dispatch_helpers.py |
工具分发辅助:并行化判断、破坏性命令检测 |
| tool_guardrails.py |
工具护栏:安全检查、危险操作拦截 |
| tool_result_classification.py |
工具结果分类 |
2.1.5 多模态能力
| 文件 |
核心功能 |
| image_gen_provider.py / image_gen_registry.py |
图片生成提供方 |
| image_routing.py |
图片路由分发 |
| video_gen_provider.py / video_gen_registry.py |
视频生成提供方 |
| tts_provider.py / tts_registry.py |
TTS 语音合成 |
| transcription_provider.py / transcription_registry.py |
语音转写 |
| browser_provider.py / browser_registry.py |
浏览器引擎 |
| web_search_provider.py / web_search_registry.py |
网页搜索 |
2.1.6 其他重要模块
| 文件 |
核心功能 |
| moa_loop.py |
Mixture-of-Agents 混合智能体运行时 |
| curator.py |
摘要生成器(对话压缩时调用独立进程) |
| model_metadata.py |
模型元数据:上下文窗口长度估算 |
| usage_pricing.py |
用量统计与计价 |
| credential_pool.py / credential_sources.py |
凭证池管理与轮换 |
| rate_limit_tracker.py |
速率限制追踪 |
| prompt_caching.py |
提示缓存优化 |
| display.py |
显示控制 |
| onboarding.py |
首次使用引导 |
| i18n.py |
国际化 |
| pet/ |
Pet 伴侣系统(虚拟形象) |
2.2 hermes_cli/ — CLI 命令行模块(192 文件,~149,809 行)
终端交互界面的完整实现,是项目代码量最大的模块。
| 文件/子目录 |
核心功能 |
| main.py (~13,300 行) |
CLI 主入口:所有子命令调度中心和进程起点 |
| commands.py |
斜杠命令注册与补全 |
| banner.py |
启动横幅 |
| skin_engine.py |
皮肤引擎 |
| callbacks.py |
回调函数(审批确认等) |
| setup.py |
交互式配置向导 |
| doctor.py |
系统诊断 |
| providers.py / provider_catalog.py |
模型提供方浏览器 |
| model_catalog.py / model_setup_flows.py |
模型目录浏览与设置 |
| model_switch.py / model_cost_guard.py |
模型切换/费用保护 |
| mcp_config.py / mcp_picker.py |
MCP 服务器配置与选择 |
| memory_setup.py / memory_providers.py |
记忆系统配置 |
| kanban.py / kanban_db.py / kanban_swarm.py |
看板多智能体协调系统 |
| plugins_cmd.py |
插件管理命令 |
| gateway_enroll.py |
网关注册/部署 |
| pairing.py |
设备配对 |
| auth_commands.py / copilot_auth.py |
认证命令 |
| config.py |
统一配置管理 |
| tools_config.py |
工具集配置 |
| profiles.py |
配置 Profile 管理 |
| voice.py |
语音交互 |
| pty_bridge.py |
PTY 桥接 |
| curses_ui.py |
Curses TUI 渲染 |
| web_server.py |
内置 Web 服务器 |
| subcommands/ |
二级子命令:40+ 子命令 |
2.3 plugins/ — 插件系统(173 文件,~99,830 行)
通过目录结构实现的可插拔扩展体系。
2.3.1 模型提供方插件(29 个)
anthropic / openai-codex / deepseek / gemini / bedrock / azure-foundry / openrouter / xai / copilot / copilot-acp / custom / alibaba / alibaba-coding-plan / arcee / gmi / huggingface / kilocode / kimi-coding / minimax / nous / novita / nvidia / ollama-cloud / opencode-zen / qwen-oauth / stepfun / xiaomi / zai
2.3.2 其他插件类型
| 子目录 |
核心功能 |
| platforms/ |
平台适配器:teams / raft / whatsapp / matrix / email / photon |
| memory/ |
记忆提供方:mem0 / honcho / holographic / supermemory / retaindb / openviking / byterover / hindsight |
| image_gen/ |
图片生成后端:openai / fal / krea / xai / openai-codex |
| video_gen/ |
视频生成后端:fal / xai |
| browser/ |
浏览器后端:firecrawl / browserbase / browser_use |
| web/ |
网页搜索后端:tavily / brave_free / ddgs / exa / searxng |
| context_engine/ |
上下文引擎插件 |
| observability/ |
可观测性:langfuse / nemo_relay |
| cron_providers/ |
定时任务后端:chronos |
| dashboard_auth/ |
仪表盘认证 |
| security-guidance/ |
安全引导规则 |
| teams_pipeline/ |
Teams 会议管道 |
| spotify/ |
Spotify 音乐控制 |
| disk-cleanup/ |
磁盘清理 |
| kanban/ |
看板仪表盘 |
2.4 gateway/ — 网关/平台适配(65 文件,~71,234 行)
消息平台集成的核心,实现统一网关接入多个异构消息平台。
| 文件/子目录 |
核心功能 |
| run.py (~18,549 行) |
网关主入口:GatewayRunner 管理所有平台适配器生命周期 |
| session.py |
会话管理:消息序列化、状态持久化 |
| session_context.py |
会话上下文变量(contextvars) |
| config.py |
网关配置加载 |
| delivery.py |
消息投递:多渠道统一输出 |
| slash_commands.py / slash_access.py |
斜杠命令处理与权限控制 |
| stream_dispatch.py |
流式输出分发 |
| stream_consumer.py |
流式消费:SSE 事件解析 |
| platform_registry.py |
平台注册中心 |
| platforms/ |
平台适配器(20+):Telegram / Discord / WhatsApp / Slack / Signal / WeChat / Feishu / QQ / DingTalk 等 |
| relay/ |
中继层(ACP 远程代理) |
2.5 tools/ — 工具系统(106 文件,~84,715 行)
智能体可调用的全部工具实现。
| 文件 |
核心功能 |
| registry.py (~600 行) |
工具注册中心:所有工具自注册,模型侧查询 |
| terminal_tool.py |
终端工具:支持 local/Docker/SSH/Modal/Singularity/Daytona 后端 |
| file_tools.py / file_operations.py |
文件工具:读/写/搜索 |
| browser_tool.py |
浏览器工具:自动化网页交互 |
| computer_use_tool.py / computer_use/ |
Computer Use:桌面控制 |
| code_execution_tool.py |
代码执行沙箱 |
| delegate_tool.py / async_delegation.py |
子智能体委派 |
| mcp_tool.py |
MCP 协议工具:Model Context Protocol 客户端 |
| skills_tool.py / skills_hub.py |
技能系统:技能浏览/安装 |
| memory_tool.py |
记忆工具 |
| todo_tool.py |
任务规划工具 |
| clarify_tool.py |
澄清问题工具 |
| send_message_tool.py |
消息发送工具 |
| cronjob_tools.py |
定时任务工具 |
| kanban_tools.py |
看板协调工具 |
| image_generation_tool.py / video_generation_tool.py |
图片/视频生成 |
| feishu_doc_tool.py / feishu_drive_tool.py |
飞书文档/云盘工具 |
| environments/ |
执行环境后端:local / docker / ssh / modal / singularity / daytona |
| approval.py / write_approval.py |
安全审批 |
| tirith_security.py / threat_patterns.py |
安全检测 |
2.6 acp_adapter/ — ACP 适配器(11 文件,~5,291 行)
Agent Client Protocol 适配器,实现编辑器集成(VS Code / Zed / JetBrains)。
| 文件 |
核心功能 |
| entry.py |
ACP 启动入口 |
| server.py (~2,068 行) |
ACP 服务器:实现全部 RPC 方法 |
| session.py |
ACP 会话管理 |
| tools.py |
ACP 工具映射 |
| permissions.py |
权限控制 |
| edit_approval.py |
编辑审批流程 |
| auth.py |
ACP 认证 |
| provenance.py |
来源追踪 |
| events.py |
ACP 事件定义 |
2.7 tui_gateway/ — TUI 网关(10 文件,~15,508 行)
Terminal UI 网关,为桌面 GUI 客户端提供 JSON-RPC 服务。
| 文件 |
核心功能 |
| server.py (~13,479 行) |
TUI 网关核心:JSON-RPC 请求分发器 |
| entry.py |
TUI 启动入口 |
| transport.py |
传输层抽象 |
| ws.py |
WebSocket 传输 |
| event_publisher.py |
事件发布器 |
| render.py |
渲染辅助 |
| slash_worker.py |
斜杠命令工作线程 |
| git_probe.py |
Git 仓库探测 |
| project_tree.py |
项目目录树展示 |
2.8 其他模块
providers/(2 文件,~426 行)
| 文件 |
核心功能 |
| __init_.py |
提供方注册中心:懒加载发现提供方插件 |
| base.py |
ProviderProfile 基类:声明式配置模板 |
cron/(9 文件,~6,322 行)
| 文件 |
核心功能 |
| scheduler.py |
定时任务调度器:APScheduler 封装 |
| jobs.py |
定时任务定义与执行 |
| suggestions.py / suggestion_catalog.py |
定时任务建议与目录 |
3. 关键架构特征
3.1 多入口统一内核
项目有 4 个独立运行入口,共享同一个 AIAgent 核心:
| 入口 |
运行模式 |
主文件 |
| CLI 终端 |
hermes chat |
cli.py |
| TUI 桌面 GUI |
hermes tui |
tui_gateway/server.py |
| 消息平台网关 |
hermes gateway |
gateway/run.py |
| 编辑器集成 |
hermes acp |
acp_adapter/server.py |
3.2 声明式工具系统
- tools/registry.py:所有工具在模块导入时自注册
- toolsets.py:工具按功能分组为 30+ 工具集,支持组合复用
- model_tools.py:轻量调度层,负责发现→过滤→分发
3.3 可插拔提供方体系
- providers/base.py:ProviderProfile 声明式基类
- 双层发现机制:内置 + 用户自定义,后者覆盖前者
- 通过 api_mode 字段自动路由到对应传输层
3.4 上下文引擎抽象
- agent/context_engine.py:定义 ContextEngine 抽象接口
- 第三方可通过 plugins/context_engine/ 替换压缩策略
- 生命周期:on_session_start → update_from_response → should_compress → compress → on_session_end
3.5 多传输协议支持
| 传输层 |
服务商 |
| Chat Completions |
OpenAI / OpenRouter / 绝大多数提供方 |
| Anthropic Messages |
Anthropic Claude |
| Codex Responses |
OpenAI Codex / xAI |
| Bedrock |
AWS Bedrock |
3.6 消息平台统一适配
- gateway/platforms/base.py:平台基类定义统一接口
- gateway/platform_registry.py:平台注册中心
- 20+ 消息平台共享核心工具集,平台差异通过额外工具集体现
3.7 安全纵深防御
- agent/tool_guardrails.py:工具调用护栏
- tools/approval.py / write_approval.py:文件写入/危险操作审批流
- tools/path_security.py:路径安全检查
- tools/tirith_security.py / threat_patterns.py:威胁模式检测
- agent/redact.py / secret_scope.py:敏感信息脱敏与作用域控制
3.8 多智能体协作
- agent/moa_loop.py:Mixture-of-Agents(参考模型汇聚后聚合)
- tools/delegate_tool.py / async_delegation.py:子智能体委派
- tools/kanban_tools.py / hermes_cli/kanban_*.py:看板多智能体协调系统
3.9 延迟优化策略
- 懒加载:大量 from X import Y 放在函数内部,避免冷启动开销
- AIAgent 代理模式:延迟导入
- 自注册发现:工具和提供方在模块导入时自注册
4. 模块间依赖关系
4.1 逐层调用逻辑
对话引擎链:cli.py → run_agent.py → agent/conversation_loop.py → model_tools.py → tools/registry.py
用户输入经 cli.py 解析后,run_agent.py 构造 AIAgent 实例并调用 run_conversation()。conversation_loop 在主循环中调用 model_tools.py 获取可用工具列表(通过 registry.py 查询),将工具 schema 随消息一起发送给 LLM。LLM 返回 tool_calls 后,conversation_loop 再次通过 model_tools → registry → 具体 tool handler 执行。
工具调度链:model_tools.py ← toolsets.py ← tools/registry.py
model_tools 是轻量调度层,向 toolsets.py 查询当前启用的工具集名称,再从 registry.py 按名称获取工具 schema 和 handler。三层各司其职:model_tools 管接口、toolsets 管分组、registry 管注册。
Gateway 消息链:gateway/run.py → gateway/platforms/* → run_agent.py
平台适配器收到消息后,通过 gateway/run.py 的 handle_message() 查找或创建会话,获取 AIAgent 实例,最终调用 run_agent.py 的 run_conversation()。所有平台共享同一个对话入口,差异仅在平台适配层处理。
TUI 链:tui_gateway/server.py → run_agent.py
桌面 GUI 通过 WebSocket 发送 JSON-RPC 请求,server.py 解析后直接调用 run_agent.py,并注册 stream_callback 回调,将流式事件推回 GUI。
ACP 链:acp_adapter/server.py → run_agent.py
编辑器通过 stdio JSON-RPC 发送请求,acp_adapter 映射工具权限后调用 run_agent.py,执行结果通过 stream_event 流式推回编辑器。
插件发现链:providers/
init.py → plugins/model-providers/*
providers/
init.py 懒加载扫描 plugins/model-providers/ 目录,每个提供方的
init.py 通过 register_provider() 自注册。用户自定义插件(~/.hermes/plugins/)覆盖同名内置插件。
4.2 链间协同:所有路径汇聚到 conversation_loop
4 条独立入口链(CLI / TUI / Gateway / ACP)最终都经过 run_agent.py 调用同一个 conversation_loop。这意味着无论消息从哪个平台进入,核心对话逻辑(系统提示组装 → LLM 调用 → 工具执行 → 重试/压缩)完全一致。平台差异仅在:
| 差异维度 |
处理位置 |
举例 |
| 工具集 |
toolsets.py |
飞书用户有 feishu_doc 工具,CLI 用户有 terminal 工具 |
| 消息投递 |
delivery.py |
飞书回发到群,CLI 直接打印到终端 |
| 审批模式 |
approval.py |
CLI 60秒超时,Gateway 300秒超时 |
| 输出截断 |
delivery.py |
平台消息限 4000 字符,CLI 无限制 |
4.3 依赖关系类型说明
| 箭头类型 |
含义 |
示例 |
| 实线箭头 → |
运行时调用 |
conversation_loop → model_tools:主循环运行时调用工具调度 |
| 虚线箭头 ⇢ |
编译时导入(延迟加载) |
conversation_loop ⇢ tools/registry:通过函数内 import 延迟加载 |
| 双向箭头 ↔ |
数据流(双向) |
delivery ↔ platforms:消息进出都需要平台适配 |
5. 各模块核心作用与场景调用时序
5.1 agent/ — 对话引擎:一次用户请求的完整旅程
核心作用:接收用户消息,调用 LLM 生成回复,执行工具调用,管理上下文窗口,直至产出最终响应。
场景:用户说"帮我搜索最新的AI论文并总结"
| 步骤 |
模块 |
关键函数 |
说明 |
| 1 |
system_prompt.py |
build_system_prompt() |
组装三层系统提示(stable/context/volatile) |
| 2 |
context_engine.py |
should_compress() |
检查上下文是否接近窗口上限,若超则触发压缩 |
| 3 |
conversation_loop.py |
run_conversation() |
进入主循环:构建消息→调用LLM→解析工具调用 |
| 4 |
anthropic_adapter.py |
call_llm() |
适配 Anthropic Messages API 发送请求 |
| 5 |
tool_dispatch_helpers.py |
dispatch() |
LLM返回tool_calls,分发到对应工具 |
| 6 |
web_search_provider.py |
search() |
执行网页搜索,获取结果 |
| 7 |
tool_executor.py |
execute() |
将搜索结果格式化为tool result |
| 8 |
conversation_loop.py |
继续循环 |
LLM基于搜索结果生成总结回复 |
5.1.1 边界条件与默认策略
💡 提示
以下数值均为源码默认值,可通过 config.yaml 或启动参数覆盖
| 配置项 |
默认值 |
说明 |
| 主Agent最大迭代 |
90 |
单轮对话循环上限,防止无限工具调用 |
| API 最大重试次数 |
3 |
单次API调用失败后最大重试 |
| 压缩触发阈值 |
50% |
上下文使用率达 50% 时触发压缩;Codex gpt-5.5 自动提升至 85% |
| 压缩保护头部 |
3 条 |
压缩时保护头部3条非系统消息 |
| 压缩保护尾部 |
20 条 |
压缩时保护尾部20条最近消息 |
| 摘要目标比例 |
20% |
压缩后摘要占阈值上下文的比例 |
| 摘要 token 上限 |
min(5%, 12000) |
动态计算,不超过 12000 token |
| 摘要失败冷却 |
600 秒 |
摘要失败后 10 分钟内不再尝试压缩 |
| 反抖动抑制 |
连续 2 次压缩节省 < 10% |
跳过压缩并建议用户 /new 或 /compress |
| 凭证轮换策略 |
fill_first |
优先使用第一个可用凭证;可选 round_robin / random / least_used |
| 429 限流冷却 |
3600 秒 |
被限流的凭证冷却 1 小时 |
| 401 认证失败冷却 |
300 秒 |
瞬时 401 错误冷却 5 分钟 |
| 速率限制告警 |
80% |
RPM/RPH/TPM/TPH 任一维度使用率超 80% 警告 |
工具护栏策略:
| 场景 |
阈值 |
动作 |
| 相同参数相同工具失败 |
2 次 |
警告 |
| 相同参数相同工具失败 |
5 次 |
阻止执行 |
| 同工具不同参数失败 |
3 次 |
警告 |
| 同工具不同参数失败 |
8 次 |
终止(halt) |
| 幂等工具返回相同结果 |
2 次 |
警告(无进展) |
| 幂等工具返回相同结果 |
5 次 |
阻止执行 |
5.2 plugins/ — 插件系统:无缝切换模型提供方
5.2.1 边界条件与默认策略
| 配置项 |
默认值 |
说明 |
| 提供方发现优先级 |
用户自定义 > 内置 |
~/.hermes/plugins/ 覆盖 plugins/model-providers/ |
| api_mode 路由 |
自动检测 |
根据 ProviderProfile.api_mode 路由到对应传输层 |
| 懒加载 |
开启 |
providers/init.py 懒加载发现提供方插件 |
核心作用:声明式提供方注册与发现,让一条命令行参数就能切换底层模型后端。
场景:从 Claude 切换到 DeepSeek
| 步骤 |
模块 |
关键逻辑 |
说明 |
| 1 |
providers/init.py |
register_provider() |
启动时扫描 plugins/model-providers/*,每个__init__.py自注册 |
| 2 |
plugins/model-providers/deepseek/init.py |
DeepSeekProfile |
声明 api_mode、端点URL、认证方式 |
| 3 |
providers/base.py |
ProviderProfile |
基类统一接口,子类只描述差异 |
| 4 |
agent/anthropic_adapter.py |
build_api_kwargs() |
根据 api_mode 路由到 chat_completions 传输层 |
| 5 |
transports/chat_completions.py |
stream() |
使用 DeepSeek 端点发送请求 |
双层发现机制:
| 发现层 |
路径 |
优先级 |
| 内置 |
plugins/model-providers/ |
低(被覆盖) |
| 用户自定义 |
~/.hermes/plugins/ |
高(覆盖内置) |
5.3 gateway/ — 网关:一条飞书消息的处理旅程
核心作用:将20+异构消息平台统一适配为标准消息流,投递到同一个 AIAgent 内核。
场景:用户在飞书群里@机器人"帮我查一下明天日程"
| 步骤 |
模块 |
关键函数 |
说明 |
| 1 |
gateway/platforms/feishu/ |
on_message() |
飞书WebSocket收到消息回调 |
| 2 |
gateway/run.py |
handle_message() |
查找/创建会话,获取AIAgent实例 |
| 3 |
run_agent.py |
run_conversation() |
调用Agent核心对话循环 |
| 4 |
conversation_loop.py |
... |
LLM返回tool_calls: [calendar] |
| 5 |
tools/terminal_tool.py |
execute() |
执行日历查询 |
| 6 |
gateway/delivery.py |
deliver() |
将Agent回复通过DeliveryRouter投递 |
| 7 |
gateway/platforms/feishu/ |
send() |
将文本发回飞书群 |
5.3.1 边界条件与默认策略
| 配置项 |
默认值 |
说明 |
| 平台输出截断上限 |
4000 字符 |
单条消息超长时截断,防止平台 API 拒绝 |
| 静默叙述过滤 |
默认开启 |
过滤 LLM 输出中的「内心独白」(如 ) |
| 长文本静默检测上限 |
64 字符 |
超过 64 字的文本不匹配静默模式 |
| 投递重试 |
无通用重试 |
仅 Telegram "thread not found" 例外:刷新后重试一次 |
5.4 tools/ — 工具系统:注册、发现、执行
5.4.1 边界条件与默认策略
| 配置项 |
默认值 |
说明 |
| 同 toolset 内工具注册冲突 |
静默覆盖 |
最后一次注册生效 |
| 不同 toolset 工具注册冲突 |
拒绝注册 |
需显式传 override=True 才允许覆盖 |
| MCP 工具冲突 |
允许覆盖 |
双方均为 MCP 时自动允许 |
| check_fn 缓存 TTL |
30 秒 |
工具可用性检查结果缓存 |
| CLI 审批超时 |
60 秒 |
终端交互模式下的等待时间 |
| Gateway 审批超时 |
300 秒 |
网关模式 5 分钟超时 |
| Cron 审批模式 |
deny |
定时任务默认拒绝危险操作 |
| 容器环境审批 |
自动通过 |
Docker / Singularity / Modal / Daytona 隔离环境下免审批 |
| Hardline 强制阻止 |
无条件 |
rm -rf /、mkfs、dd、fork bomb 等,YOLO 模式也无法绕过 |
| Smart 审批模式 |
LLM 辅助判定 |
APPROVE→自动通过;DENY→自动拒绝;ESCALATE→转人工 |
核心作用:所有工具自注册到中央注册表,运行时按工具集过滤后暴露给LLM,LLM选择调用后由执行器统一执行。
场景:LLM决定执行一段Python代码
| 步骤 |
模块 |
关键逻辑 |
说明 |
| 1 |
tools/registry.py |
@register_tool装饰器 |
terminal_tool在导入时自注册schema+handler |
| 2 |
toolsets.py |
过滤 |
根据当前启用的工具集,筛选可用工具列表 |
| 3 |
model_tools.py |
get_tools_for_model() |
将过滤后的schema传给LLM |
| 4 |
tool_guardrails.py |
check() |
安全检查:代码是否包含危险操作 |
| 5 |
tools/environments/local.py |
execute() |
本地执行Python代码 |
| 6 |
approval.py |
request_approval() |
破坏性操作需用户确认 |
工具集组合复用示例:
| 工具集 |
包含工具 |
适用平台 |
| web |
web_search, browser |
所有平台 |
| terminal |
terminal_tool, file_tools |
CLI/TUI |
| coding |
terminal, file, browser, lsp |
CLI/TUI |
| hermes-telegram |
web + send_message + telegram特有 |
Telegram |
| hermes-feishu |
web + send_message + feishu_doc |
飞书 |
5.5 acp_adapter/ — 编辑器集成:VS Code中的AI编程助手
核心作用:实现 ACP (Agent Client Protocol),让编辑器通过 JSON-RPC 与 Hermes 交互。
场景:开发者在VS Code中选中代码,点击"Explain"
| 步骤 |
模块 |
关键函数 |
说明 |
| 1 |
acp_adapter/server.py |
prompt() |
接收JSON-RPC请求 |
| 2 |
acp_adapter/session.py |
load_session() |
加载/创建会话 |
| 3 |
acp_adapter/tools.py |
map_tools() |
将Hermes工具适配为ACP格式 |
| 4 |
run_agent.py |
run_conversation() |
执行对话循环 |
| 5 |
acp_adapter/permissions.py |
check() |
检查文件访问权限 |
| 6 |
acp_adapter/events.py |
stream_event() |
流式推送回复到编辑器 |
5.5.1 边界条件与默认策略
| 配置项 |
默认值 |
说明 |
| 事件队列容量 |
256 |
有界队列,超出时 put_nowait 丢弃事件 |
| WS 写入失败策略 |
标记 dead |
一次写入失败后短路返回 False,不再尝试 |
| WS 连接超时 |
2.0 秒 |
WebSocket 连接超时 |
| WS 关闭 join 超时 |
3.0 秒 |
关闭时等待线程结束 |
ACP 额外约束:ACP 通过 stdio 传输 JSON-RPC,工具权限由 acp_adapter 映射,不允许终端类工具。
| 边界条件 |
值 / 行为 |
说明 |
| tool_permission_map |
仅允许 read/write/search 等只读工具 |
禁止 terminal、approval 等交互式工具 |
| transport |
stdio JSON-RPC |
不支持 HTTP/WebSocket |
| stream_event |
通过 stderr 推送 |
stdout 保留给 JSON-RPC 响应 |
| coding_context platform |
"acp" |
区别于 cli/gateway/tui |
5.6 tui_gateway/ — 桌面GUI:实时交互体验
核心作用:实现 TUI (Terminal/Text UI) 网关,让桌面 GUI 客户端通过 WebSocket JSON-RPC 与 Hermes 交互,提供实时流式输出、审批确认、斜杠命令等交互体验。
场景:用户在桌面终端 UI 中输入自然语言,TUI 通过 WebSocket 推送流式响应,用户可中断、切换模型、审批危险操作。
| 步骤 |
模块 |
关键函数/方法 |
说明 |
| 1 |
tui_gateway/ws.py |
WebSocketHandler |
客户端通过WS连接,发送JSON-RPC请求 |
| 2 |
tui_gateway/server.py |
dispatch() → handle_request() |
RPC分发:解析method,路由到_methods注册的处理函数 |
| 3 |
server.py |
_methods["session.create"] |
创建新会话,初始化AIAgent实例和工作目录 |
| 4 |
run_agent.py |
run_conversation() |
调用Agent核心对话循环,处理用户消息 |
| 5 |
conversation_loop.py |
stream_loop() |
LLM流式返回token,通过event_publisher推送 |
| 6 |
tui_gateway/event_publisher.py |
publish() / enqueue() |
流式事件入队(上限256),WS端异步消费推送给客户端 |
| 7 |
server.py |
_methods["approval.respond"] |
危险操作审批:用户确认/拒绝,Agent继续或中止 |
| 8 |
server.py |
_methods["session.interrupt"] |
用户中断当前生成,取消进行中的LLM调用 |
💡 提示
5.6.1 边界条件与默认策略
TUI 网关与 ACP/CLI/Gateway 共享核心对话循环,通用边界条件同 5.1.1 节。TUI 额外约束:
| 边界条件 |
默认值 |
说明 |
| WS 心跳(ping interval) |
20.0 秒 |
uvicorn Config 配置,检测半开连接 |
| WS 心跳(ping timeout) |
20.0 秒 |
超时后判定连接断开 |
| WS 写超时 |
10.0 秒 |
事件循环刷帧最大等待,超时视作传输停滞 |
| WS 孤儿回收宽限 |
20.0 秒(HERMES_TUI_WS_ORPHAN_REAP_GRACE_S) |
断连后允许重连的窗口,0=永久挂起 |
| 空闲会话 TTL |
21600 秒 / 6 小时(HERMES_TUI_SESSION_TTL_S) |
超过后回收器清理 |
| 回收器扫描间隔 |
300 秒 / 5 分钟 |
定期扫描过期会话 |
| 事件发布队列上限 |
256 |
超出后静默丢弃(drop silently) |
| 事件发布连接超时 |
2.0 秒 |
Sidecar WS 建连超时 |
| Slash Worker 命令超时 |
45.0 秒(HERMES_TUI_SLASH_TIMEOUT_S) |
斜杠命令执行超时,最小 5 秒 |
| 主 Agent 最大迭代 |
90 轮 |
TUI 默认高于 CLI,保证桌面场景充分执行 |
| 后台 Agent 最大迭代 |
25 轮 |
tui_gateway/server.py _cfg_max_turns |
| 审批阻塞超时 |
300 秒 |
_block() 等待用户确认的最大时间 |
| sudo 请求超时 |
120 秒 |
提权操作确认窗口 |
| terminal.read 超时 |
30 秒 |
终端输入请求超时 |
| busy_input_mode |
"interrupt" |
可选 "queue" / "steer",控制用户输入与 Agent 并行策略 |
| TCP_NODELAY |
始终启用 |
禁用 Nagle 算法,确保流式帧即时发送 |
| 平台标识 |
"tui" |
区别于 cli/gateway/desktop |
6. 多Agent场景深度解析
6.1 三种多Agent模式
Hermes 支持三种多智能体协作模式,覆盖从简单到复杂的不同场景:
| 模式 |
入口文件 |
并发模型 |
适用场景 |
| Delegate(委派) |
tools/delegate_tool.py |
同步/异步线程池 |
父Agent拆分子任务,委派给子Agent执行 |
| MoA(混合智能体) |
agent/moa_loop.py |
并行线程池 |
多个参考模型独立回答,聚合器合成最优答案 |
| Kanban(看板协调) |
tools/kanban_tools.py |
异步+DB协调 |
多Agent分工协作,通过看板状态驱动 |
6.2 Delegate 模式详解
核心机制:父Agent通过 delegate_task 工具创建子Agent,子Agent在隔离上下文中执行任务,结果回传给父Agent。
关键约束:
| 约束 |
值 |
说明 |
| MAX_DEPTH |
1 |
默认最大委派深度:父(0)→子(1),orchestrator角色可达子(1)→孙(2) |
| MAX_CONCURRENT |
3 |
默认最大并发子Agent数 |
| BLOCKED_TOOLS |
delegate_task, clarify, memory, send_message |
子Agent禁止使用的工具(防递归/副作用) |
两种角色:
| 角色 |
说明 |
工具集 |
| leaf |
叶子节点,执行完即返回 |
继承父工具集(去除blocked) |
| orchestrator |
可继续委派,形成层级 |
继承父工具集 + delegation工具集 |
场景:用户说"重构这三个模块并写单元测试"
子Agent创建流程:
| 步骤 |
关键函数 |
说明 |
| 1 |
_normalize_role() |
决定子Agent角色(leaf/orchestrator) |
| 2 |
_build_child_agent() |
构建子AIAgent实例(继承凭证、工具集、模型) |
| 3 |
_build_child_system_prompt() |
生成子Agent专属系统提示(含目标、上下文、角色) |
| 4 |
_run_single_child() |
在ThreadPoolExecutor中运行子Agent |
| 5 |
_register_subagent() |
注册子Agent元数据(用于监控和中断) |
| 6 |
_heartbeat_loop() |
心跳线程:防止网关因"无活动"超时断连 |
| 7 |
_relay_child_text() |
将子Agent流式输出中继回父Agent |
凭证继承优先级:
| 优先级 |
来源 |
示例 |
| 1(最高) |
override参数 |
override_api_key="sk-xxx" |
| 2 |
父Agent继承 |
父Agent的credential_pool |
| 3(最低) |
全局配置 |
环境变量/配置文件 |
6.2.1 Delegate 边界条件与容错
🔴 提示
子Agent上下文完全隔离:禁止读取共享记忆、禁止与用户交互、禁止委派子任务
| 配置项 |
默认值 |
说明 |
| MAX_DEPTH |
1 |
父(0)→子(1);orchestrator 角色可达 子(1)→孙(2) |
| MAX_CONCURRENT |
3 |
最大并发子Agent数 |
| 子Agent最大迭代 |
50 |
独立于主Agent的90次迭代预算 |
| 子Agent超时 |
None (关闭) |
默认不设超时;若配置,最低 30 秒 |
| 心跳间隔 |
30 秒 |
idle 状态 15 周期(450秒)、in-tool 状态 40 周期(1200秒) 判定过期 |
| 审批回调(默认) |
auto_deny |
子Agent的危险命令自动拒绝 |
| 审批回调(YOLO) |
auto_approve |
需 delegation.subagent_auto_approve=true |
| 默认工具集 |
[terminal, file, web] |
子Agent默认可用工具集 |
| BLOCKED_TOOLS |
6 项 |
delegate_task, clarify, memory, send_message, execute_code, cronjob |
| 输出截断 |
8000 字符 / 12 条 |
overlay 层结果截断;单分支 600 字符 / 8 条 |
| 凭证继承 |
三级优先 |
override 参数 > 父Agent pool > 全局配置 |
6.3 MoA(Mixture-of-Agents)模式详解
核心机制:多个参考模型独立回答同一问题,聚合器模型综合所有参考答案生成最终回复。
场景:用户问"这个架构方案有什么风险?",需要多视角分析
MoA循环5步骤:
| 步骤 |
函数 |
说明 |
| 1 |
_reference_messages() |
过滤消息:只保留user/assistant文本,丢弃tool消息 |
| 2 |
_run_references_parallel() |
ThreadPoolExecutor并行调用所有参考模型 |
| 3 |
拼接参考输出 |
"Reference 1 — Claude: ...\n\nReference 2 — Gemini: ..." |
| 4 |
聚合器合成 |
call_llm(aggregator_model, 合成提示) |
| 5 |
返回MoA上下文 |
"[MoA context] Aggregator: GPT-4o\nReferences: Claude, Gemini, DeepSeek" |
6.3.1 MoA 边界条件与容错
| 配置项 |
默认值 |
说明 |
| 参考模型最大并发 |
8 |
ThreadPoolExecutor 最大工作线程 |
| 参考模型失败容错 |
标记 [failed] |
单个参考模型失败不中止,聚合器基于部分上下文继续 |
| MoA 递归保护 |
跳过 |
MoA 预设引用 MoA 预设 → 跳过并标记 [skipped] |
| 聚合器失败降级 |
拼接原始输出 |
聚合器调用失败时,降级为参考答案原样拼接 |
| 参考模型温度 |
0.6 |
参考模型回答的温度参数 |
| 聚合器温度 |
0.4 |
聚合器合成的温度参数(更低=更稳定) |
| 参考模型 max_tokens |
4096 |
每个参考模型回答的最大 token |
6.4 Kanban(看板协调)模式详解
Kanban 是 Hermes 中最复杂的多 Agent 协调模式,基于 SQLite 看板数据库实现跨进程的任务分配、状态跟踪和故障恢复。
6.4.1 Kanban Agent 生命周期
一次完整的 Kanban 任务生命周期:
- 创建:用户通过
/kanban create 命令或 API 创建任务。初始状态为 running(立即分配)或 blocked(等待依赖)。每个任务写入 tasks 表,同时创建一条 task_runs 记录。
- 分解:主 Agent 调用
/kanban decompose 将大任务拆分为子任务。子任务自动建立父子关系(task_links 表),子任务状态受父任务约束——若父任务 blocked,子任务自动设为 blocked。
- 分发:
dispatch_once() 在每个 tick 内:扫描 ready 状态任务 → 调用 spawn_fn 启动 Worker 进程 → 原子切换 ready → running 并写入 claim_lock + claim_expires。
- 执行:Worker 进程持有
claim_lock,定期心跳更新 claim_expires。每条 task_runs 记录追踪独立执行的 PID、心跳、运行时长。
- 完成/失败:Worker 调用
complete_task()(running|ready|blocked → done)或 block_task()(running|ready → blocked)。失败时根据退出码标记 crashed/timed_out/failed。
6.4.2 状态回退机制
Kanban 支持以下回退路径:
| 回退场景 |
状态转换 |
触发条件与处理 |
| 心跳过期 |
running → ready |
Worker 心跳超过 3600 秒未更新,dispatcher 触发 reclaim_task(),清除 claim_lock,任务回到 ready 可被重新分配 |
| Worker 崩溃 |
running → ready |
崩溃宽限期 DEFAULT_CRASH_GRACE_SECONDS=30秒,超时后回收;若 PID 仍存活则延迟回收(RECLAIM_DEFER_GRACE_SECONDS=120秒) |
| 任务阻塞 |
running → blocked |
Worker 主动调用 block_task(),需等待依赖解除后 unblock_task() → ready |
| 分配失败熔断 |
ready → blocked |
连续分配失败达到 DEFAULT_SPAWN_FAILURE_LIMIT 阈值,dispatcher 将任务设为 blocked 防止无限重试 |
| 子任务阻塞传播 |
子 blocked → 父 blocked |
子任务有任何 blocked,父任务自动调整为 blocked,子任务全部 ready 后父任务才可进入 ready |
| Review 回退 |
review → running |
审查不通过时 approve_task(reject) 触发 re-claim,重新分配 Worker 执行 |
6.4.3 多 Agent 竞态处理
Kanban 在三个层面防止竞态:
- 数据库层:SQLite WAL 模式提供单写者串行化。task_runs 表的
claim_lock 字段实现 CAS(Compare-And-Swap),两个 Worker 同时 claim 同一任务时,只有先写入 claim_lock 的成功。
- 进程间锁:
_dispatch_tick_lock() 基于文件锁实现跨进程互斥。同一个 kanban.db 不会有两个 dispatcher 并发 tick——孤儿 dispatcher 获取锁失败时返回 skipped_locked=True,不执行任何写操作。
- 声明式约束:
claim_task() 内部执行 ready → running 转换时,SQL WHERE 子句同时检查状态和 claim_lock 为空,确保原子性。索引 idx_tasks_assignee_status 加速同时查分配者和状态的场景。
6.4.4 三种模式对比
| 维度 |
Delegate |
MoA |
Kanban |
| 执行方式 |
进程内线程池 |
串行/并行 LLM 调用 |
跨进程 Worker |
| 通信机制 |
Python 函数调用 |
消息列表传递 |
Shared SQLite + CAS |
| 故障隔离 |
弱(线程异常可能影响主 Agent) |
弱(同一进程内 LLM 调用失败) |
强(独立进程,崩溃不影响主 Agent) |
| 并发上限 |
受线程池约束 |
受 API 并发限制 |
max_in_progress + max_spawn 可独立配置 |
| 状态持久化 |
无(内存) |
无(内存) |
SQLite WAL(崩溃恢复) |
| 子任务超时 |
child_timeout_seconds(默认无限制) |
受 LLM API 超时约束 |
claim_expires + DEFAULT_CLAIM_HEARTBEAT_MAX_STALE_SECONDS=3600秒 |
| 适用场景 |
简单子任务委派(1-3 个并行子 Agent) |
多模型投票/聚合(需要多个 LLM 视角) |
大规模任务分解(10+ 子任务,需要故障恢复和持久化) |
| 重试策略 |
Agent 循环内置重试 |
MoA loop 内置重试 |
reclaim + 熔断(DEFAULT_SPAWN_FAILURE_LIMIT) |
6.4.5 Kanban 边界条件
| 边界条件 |
默认值 |
说明 |
| 状态流转 |
triage→todo→ready→running→done/blocked/review |
9种合法状态,VALID_STATUSES 集合约束 |
| 合法初始状态 |
running / blocked |
VALID_INITIAL_STATUSES,任务创建时只能选其一 |
| 任务分配 |
claim_task() 原子 CAS |
SQL WHERE 同时检查 status=ready AND claim_lock IS NULL |
| max_in_progress |
无硬编码上限 |
dispatch_once 参数,按 board 粒度配置,限制同时 running 任务数 |
| max_spawn |
无硬编码上限 |
dispatch_once 参数,单次 tick 最多启动 Worker 数 |
| max_in_progress_per_profile |
无硬编码上限 |
按 Agent profile 维度限制并发,防止单种 Agent 过度占用 |
| DEFAULT_CLAIM_HEARTBEAT_MAX_STALE_SECONDS |
3600 秒(1小时) |
Worker 心跳超过此值视为僵死,触发 reclaim |
| DEFAULT_SPAWN_FAILURE_LIMIT |
5 |
连续分配失败达此阈值后任务进入 blocked(熔断) |
| DEFAULT_CRASH_GRACE_SECONDS |
30 秒(环境变量 HERMES_KANBAN_CRASH_GRACE_SECONDS 可覆盖) |
Worker 崩溃后等待的宽限期,避免误回收正在退出的进程 |
| RECLAIM_DEFER_GRACE_SECONDS |
120 秒 |
PID 仍存活时延迟回收的宽限期,防止回收正在处理 SIGTERM 的 Worker |
| DEFAULT_BUSY_TIMEOUT_MS |
120,000 毫秒(环境变量 HERMES_KANBAN_BUSY_TIMEOUT_MS) |
board 锁获取超时,防止单个 dispatcher 长时间持锁 |
| KANBAN_TERMINAL_TIMEOUT_GRACE_SECONDS |
30 秒 |
Worker 内 terminal 工具超时预留安全边界 |
| 持久化 |
SQLite WAL 模式 |
跨进程共享,崩溃后可通过 WAL 自动恢复 |
7. A2A 协议与 A2UI 协议说明
7.1 当前实现的Agent间通信机制
Hermes 目前
没有实现标准化的 A2A 协议,但通过以下机制实现了Agent间通信:
| 机制 |
实现方式 |
通信范围 |
| Delegate委派 |
进程内线程池 + 函数调用 |
父子Agent(同进程) |
| Kanban看板 |
共享SQLite数据库 |
多Agent(同进程) |
| Relay中继 |
WebSocket + CapabilityDescriptor |
跨进程Agent(如外部connector) |
| MCP协议 |
MCP客户端/服务器 |
Agent↔工具源 |
7.2 Relay 中继:当前最接近 A2A 的机制
gateway/relay/ 是当前最接近 Agent-to-Agent 通信的机制,实现了跨进程的Agent协作。
核心设计:
| 组件 |
职责 |
| RelayAdapter |
网关侧适配器,不包含平台特定代码,从connector接收CapabilityDescriptor |
| RelayTransport |
传输层抽象(WebSocket / 标准I/O) |
| CapabilityDescriptor |
握手时协商的能力描述(支持的命令、平台、身份) |
| Connector |
外部进程,知道"chat_id映射到Discord频道"等平台细节 |
Relay通信流程:
7.2.1 Relay 边界条件与容错
| 配置项 |
默认值 |
说明 |
| 连接/握手超时 |
30 秒 |
WebSocket 连接和握手共享同一超时 |
| Outbound RPC 超时 |
30 秒 |
出站 RPC 调用等待响应的超时 |
| 断线重连策略 |
指数退避 |
起始 1.0 秒,上限 30.0 秒,每次翻倍 |
| 4401 断连处理 |
区分阶段 |
握手后 4401 = 凭据吊销(终态,不再重连);握手前 4401 = 可重试 |
| going_idle 超时 |
10 秒 |
空闲状态检测超时 |
| 凭据吊销轮询 |
1 秒 |
adapter 层轮询凭据状态间隔 |
| 升级 token TTL |
300 秒 |
认证升级令牌有效期 5 分钟 |
| 签名时间偏移窗口 |
300 秒 |
允许的时钟偏移,防重放攻击 |
CapabilityDescriptor 字段:
| 字段 |
类型 |
说明 |
| contract_version |
int |
协议版本号,当前为 1 |
| platform |
str |
平台标识(如 discord、telegram) |
| label |
str |
平台显示名称 |
| max_message_length |
int |
单条消息最大长度(0 → 默认 4096) |
| supports_draft_streaming |
bool |
是否支持草稿流式输出 |
| supports_edit |
bool |
是否支持消息编辑 |
| supports_threads |
bool |
是否支持话题/线程 |
| markdown_dialect |
str |
平台支持的 Markdown 方言 |
| len_unit |
str |
长度单位:chars 或 utf16 |
| emoji |
str |
平台标识 emoji,默认 🔌 |
| pii_safe |
bool |
是否对 PII 敏感,默认 False |
7.3 A2A 协议设计建议(面向未来)
基于当前 Hermes 的架构,建议的 A2A 协议设计:
| 层级 |
协议 |
职责 |
当前Hermes对应 |
| 传输层 |
WebSocket / stdio |
可靠双向字节流 |
RelayTransport |
| 握手层 |
CapabilityDescriptor |
能力协商 |
relay/descriptor.py |
| 消息层 |
JSON-RPC / NDJSON |
结构化消息传递 |
acp_adapter/server.py |
| 语义层 |
AgentMessage |
任务委派/结果回传 |
delegate_tool.py |
A2A 消息类型建议:
| 消息类型 |
方向 |
说明 |
| task_delegate |
主→子 |
委派任务(含goal、context、toolsets) |
| task_result |
子→主 |
返回任务结果 |
| task_progress |
子→主 |
进度更新(流式) |
| task_cancel |
主→子 |
取消任务 |
| capability_query |
双向 |
查询对方能力 |
| heartbeat |
双向 |
保活/停滞检测 |
7.4 A2UI 协议:当前实现与设计建议
当前 UI 交互机制:
| 入口 |
传输方式 |
事件推送 |
说明 |
| TUI桌面端 |
WebSocket JSON-RPC |
WsPublisherTransport |
实时流式响应、工具进度 |
| ACP编辑器 |
stdio JSON-RPC |
stream_event |
代码建议、文件编辑 |
| 消息平台 |
平台SDK/Webhook |
无(请求-响应) |
飞书/Telegram/Discord |
A2UI 事件类型:
| 事件 |
触发时机 |
目标 |
| text_delta |
LLM流式输出token |
GUI实时显示 |
| tool_start |
工具开始执行 |
显示进度指示器 |
| tool_end |
工具执行完成 |
更新状态 |
| reasoning |
思考过程输出 |
显示推理 |
| status |
Agent状态变更 |
更新状态栏 |
| error |
发生错误 |
显示错误提示 |
Hermes 当前没有实现标准化 A2UI 协议,UI交互通过各入口的传输层直接处理(WebSocket JSON-RPC / stdio JSON-RPC / 平台SDK),不涉及Agent层协议设计。
7.5 三层协议边界总结
| 协议 |
通信双方 |
职责 |
数据格式 |
| A2UI |
前端 ↔ 主Agent |
UI渲染决策、用户交互传递 |
JSON-RPC + 事件流 |
| A2A |
主Agent ↔ 子Agent |
任务委派、结果回传、能力查询 |
函数调用/线程池(当前) → WebSocket(建议) |
| MCP |
所有Agent ↔ 工具源 |
工具调用、资源访问 |
JSON-RPC |
7.6 场景对照:不同协议在不同场景下的使用
| 场景 |
A2UI |
A2A |
MCP |
| 用户在飞书@机器人 |
飞书消息交互 |
无 |
搜索/文件操作 |
| VS Code代码补全 |
编辑器渲染 |
无 |
文件读写/LSP |
| 多Agent并行重构 |
进度展示 |
父子Agent委派 |
代码执行/文件操作 |
| MoA聚合分析 |
实时流式输出 |
参考模型并行调用 |
无 |
| 看板协调开发 |
看板状态展示 |
Agent间看板DB协调 |
代码/文件/搜索 |
| 跨进程Agent协作 |
无直连 |
Relay中继通信 |
中继侧工具调用 |
文章评论