# Remote Agents ## 文档维护规范 0. **先改文档,再动代码** 1. **文档分层,链接代码** — 格式:`module/file.py:function_name` 2. **简洁快照,日志分离** — 决策依据记录在 `knowhub/docs/decisions.md` --- ## 定位 KnowHub 服务器托管的远端 Agent,供客户端通过统一的 `agent` 工具(`agent_type="remote_xxx"`)调用。 目前部署: | agent_type | 职责 | 允许的 skills | 核心实现 | |------------|------|---------------|---------| | `remote_librarian` | 知识库查询整合 / 知识上传图谱编排 | `ask_strategy`(默认)/ `upload_strategy` | `knowhub/agents/librarian.py::run_librarian` | | `remote_research` | 深度调研,全网搜集 + 总结 | —(不支持动态 skill) | `knowhub/agents/research.py::research` | **一个 Agent,多种模式**:Librarian 是同一个 AgentRunner,调用方通过 `skills` 参数选择当前的策略——这比通过 task 内容或独立 agent_type 区分模式更显式、更可靠。 **skills 的语义**: - 由 caller 指定(`agent` 工具的 `skills` 参数透传到 HTTP body) - 服务器按每个 agent_type 的 `ALLOWED_SKILLS` 白名单过滤(非法 skill 被忽略并打 warning) - 不在白名单的 skill 不会影响 Agent 行为,也不会导致请求失败 所有 agent 调用同步执行——服务器处理完成后才返回结果。 --- ## 远端 Agent 的安全约束 新增远端 Agent 时,handler 构造的 `RunConfig` 必须显式满足三条: | 约束 | 如何配置 | |------|---------| | **禁止调用 `agent` / `evaluate` 工具** | 用 `tools=[...]` 精确列表不含它们;或 `tool_groups + exclude_tools=["agent","evaluate"]` | | **关闭自动知识提取 / 复盘** | `knowledge=KnowledgeConfig(enable_extraction=False, enable_completion_extraction=False, ...)` | | **关闭自动知识注入** | `knowledge=KnowledgeConfig(enable_injection=False, ...)` | 原因: - 递归 `agent`:remote agent 在服务器上再派生子 Agent 会污染服务器 trace;调 `remote_*` 则 HTTP 回调自己 - 自动知识操作:`enable_injection=True` 会在 focus goal 时调 `remote_librarian` → 服务器自己调自己 → 递归 当前实现参考:`knowhub/agents/librarian.py::get_librarian_config`(显式 tool 列表 + knowledge 全关)、`knowhub/agents/research.py::research`(`tool_groups + exclude_tools` + knowledge 全关)。 新增远端 Agent 只需:在 `knowhub/agents/` 下写实现 + prompt + 定义 `ALLOWED_SKILLS`,在 `knowhub/server.py::_get_remote_agent_dispatch` 的分发表里登记 `agent_type`。客户端零改动。 --- ## 架构 ``` 端侧 Agent └── agent 工具(统一入口,按 agent_type 路由) ↓ HTTP POST /api/agent → 服务器按 agent_type 分发到对应 AgentRunner ``` 远端 Agent 不是常驻进程。每次 HTTP 请求触发一次 `AgentRunner.run()`,状态持久化到服务器本地的 `.trace/`。 **续跑**:客户端显式传 `continue_from=`。服务器不维护 caller → sub_trace 映射,caller 自己记住并回传。 **知识上传**和查询用同一个 `remote_librarian`,靠 `skills=["upload_strategy"]` 切换到上传模式。`task` 此时是 JSON 字符串 `{knowledge, tools, resources}`。服务器同步跑完图谱编排后返回——不再是独立的 `/api/knowledge/upload` 端点。 --- ## 调用示例 统一端点 `POST /api/agent`,详见 [api.md § POST /api/agent](api.md#post-apiagent)。 **知识查询**(Librarian + ask_strategy): ```json { "agent_type": "remote_librarian", "task": "ControlNet 相关的工具知识", "skills": ["ask_strategy"], "continue_from": null } ``` **知识上传**(Librarian + upload_strategy;`task` 用 JSON 字符串承载结构化数据): ```json { "agent_type": "remote_librarian", "task": "{\"knowledge\": [...], \"tools\": [...], \"resources\": [...]}", "skills": ["upload_strategy"], "continue_from": null } ``` **深度调研**(`remote_research` 不接受 skill): ```json { "agent_type": "remote_research", "task": "深度调研 Nano Banana 多图融合", "continue_from": null } ``` 所有调用同步返回标准 Agent 结果 `{sub_trace_id, status, summary, stats}`。`summary` 是 Agent 最终产出的 message 文本——结构化信息(引用来源、ID 列表等)由 Agent 的 prompt 约定写进文本,由调用方 parse。不定义 per-agent 的强 schema。 ### 审计与运维 知识上传请求会在服务器 `.cache/.knowledge/buffer/` 下写一份 buffer 文件(审计用)。处理失败的文件可通过运维端点查询与重跑: - `GET /api/knowledge/upload/pending` — 列出 pending 或 failed 的 buffer - `POST /api/knowledge/upload/retry` — 同步重跑所有 failed ### 知识注入(框架级) `inject_knowledge_for_goal`(`agent/trace/goal_tool.py`)在 Goal 开始时自动通过 `agent_type="remote_librarian"` 调用 `/api/agent`,把返回的 summary 作为 cognition_log 的 `query` 事件记录(详见 `agent/docs/cognition-log-plan.md`)。 --- ## 实现位置 | 组件 | 位置 | |------|------| | Librarian 核心 | `knowhub/agents/librarian.py::run_librarian`(skill 决定模式;`ALLOWED_SKILLS` 定义白名单) | | Research 核心 | `knowhub/agents/research.py`(`research()`) | | Prompt | `knowhub/agents/librarian_agent.prompt` / `research_agent.prompt` | | Server 端点 | `knowhub/server.py::agent_api`(`/api/agent`)+ 运维 `/api/knowledge/upload/{pending,retry}` | | 客户端入口 | `agent/tools/builtin/subagent.py::agent`(按 `remote_` 前缀路由) | | SDK / CLI | `agent.invoke_agent()` (`agent/client.py`);Claude Code skill 脚本 `~/.claude/skills/agent/invoke.py` 透传参数 | --- ## 与 Cognition Log 的关系 每次 `remote_librarian` 调用在 Agent 侧产生一个 `query` 事件,记录查询和整合回答。后续评估以 query 为单位。详见 [cognition-log-plan.md](cognition-log-plan.md)。 ## 与知识处理流水线的关系 upload 提交的知识进入处理流水线(去重、工具关联分析)。逻辑在 `server.py:KnowledgeProcessor` 中。详见 [processing-pipeline.md](processing-pipeline.md)。