remote-agents.md 6.1 KB

Remote Agents

文档维护规范

  1. 先改文档,再动代码
  2. 文档分层,链接代码 — 格式:module/file.py:function_name
  3. 简洁快照,日志分离 — 决策依据记录在 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::researchtool_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=<sub_trace_id>。服务器不维护 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

知识查询(Librarian + ask_strategy):

{
  "agent_type": "remote_librarian",
  "task": "ControlNet 相关的工具知识",
  "skills": ["ask_strategy"],
  "continue_from": null
}

知识上传(Librarian + upload_strategy;task 用 JSON 字符串承载结构化数据):

{
  "agent_type": "remote_librarian",
  "task": "{\"knowledge\": [...], \"tools\": [...], \"resources\": [...]}",
  "skills": ["upload_strategy"],
  "continue_from": null
}

深度调研remote_research 不接受 skill):

{
  "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_goalagent/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.pyresearch()
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

与知识处理流水线的关系

upload 提交的知识进入处理流水线(去重、工具关联分析)。逻辑在 server.py:KnowledgeProcessor 中。详见 processing-pipeline.md