Files
social-app/docs/protocols/agent/tool-protocol.md
T
qzl d060962a5f feat(agent): redesign project_cli with module/method/input protocol
- Replace command/subcommand/args with module/method/input envelope
- Calendar handler uses discriminated union (mode) for read operations
- Strict Pydantic models with extra='forbid' for all calendar methods
- Worker max_iters=7, router prompt simplified (removed project_cli_defaults)
- Skill index cards + per-action files for progressive disclosure
- Frontend/AG-UI aligned to module/method dispatch
- Protocol docs updated to module/method/input contract

WIP: action cards need envelope fix, 2 tests need update, memory
handler needs Pydantic models.
2026-04-24 13:24:13 +08:00

8.8 KiB
Raw Blame History

Agent Tool Protocol

本文件定义当前项目中 AgentScope tool、项目 CLI、tool post-processor、SSE/history/persistence 之间的协议边界。

1. Scope

本协议覆盖:

  • AgentScope tool wrapper
  • 项目内受限 CLI tool
  • runtime tool post-processor
  • ToolResponse
  • ToolAgentOutput
  • tool message content
  • tool 结果的 SSE/history/persistence 表达

本协议不覆盖:

  • 前端视觉实现细节
  • worker answer 文案格式
  • 非 tool 的普通 assistant 文本输出

2. Core Principles

  1. 项目 CLI 是受限工具执行边界,不是通用 shell。
  2. agent 只暴露一个 AgentScope toolproject_cli
  3. skills 只负责向 agent 披露如何使用 project_cli,不承担执行 transport、分发或权限决策。
  4. Router 是 CLI 的唯一动作分发核心,只允许白名单 module + method
  5. 每个 CLI method 绑定 Python handler 或 action dispatcher。
  6. handler 只能调用允许的内部能力,不开放任意系统命令执行。 6.1 project_cli 权限由 runtime 的 module 白名单与 CLI router 白名单共同约束,不能由 skills 可见性隐式放开。
  7. ToolAgentOutput.result 是 canonical machine-oriented tool result。
  8. ToolResponse 不承载完整 ToolAgentOutput,只承载给 agent 使用的文本投影。
  9. tool UI 只来自 ToolAgentOutput.ui_hints,不再经过 worker ui_hints -> ui_schema 链路。

3. Execution Flow

一次 tool 调用按如下顺序执行:

  1. AgentScope tool project_cli 接收到模型生成的 tool call。
  2. wrapper 将 module + method + input 映射为项目 CLI 输入。
  3. runtime 将受控认证凭证通过环境变量注入 CLI 子进程。
  4. CLI router 将 (module, method) 分发给对应 Python handler。
  5. handler 执行业务逻辑并返回结构化 result
  6. wrapper 将 result 投影为文本,写入 ToolResponse.content
  7. runtime tool post-processor 基于 result 和 runtime 上下文生成完整 ToolAgentOutput
  8. ToolAgentOutput 进入:
    • TOOL_CALL_RESULT
    • metadata.tool_agent_output
    • history replay
    • context rebuild

4. Input Channels

Agent -> project_cli 的结构化入参:

{
  "module": "calendar",
  "method": "read",
  "input": {
    "mode": "range",
    "start_at": "2026-04-21T00:00:00+08:00",
    "end_at": "2026-04-22T00:00:00+08:00"
  }
}

补充说明:

  • project_cli 对模型暴露的 schema 保持薄封装,只保证存在 modulemethodinput 三层。
  • method 级别的严格字段校验由服务端 dispatch 到对应 Pydantic model 后执行。
  • 对日期/时间字段使用强类型约束:date 使用 Pydantic date,时间区间使用带时区的 datetime
  • 不再把完整 action matrix 直接注入工具 schema,以保留渐进式披露和较低 token 成本。

CLI 运行时输入通道采用“两者结合”:

  • argv 为主:
    • module
    • method
    • mode / formatting flags
  • stdin 为辅:
    • 较大的 JSON payload
    • 复杂对象参数
    • 多步批量操作负载
  • environment variables
    • controlled credential
    • runtime-only internal context

约束:

  • 模型不可见的认证信息不得进入 tool args。
  • CLI 不接受来自自然语言/模型参数的任意 token 字符串。
  • backend runtime 只能通过受控环境变量注入认证凭证。

权限边界:

  • enabled_skills 仅控制 skill 文档可见性与注册。
  • runtime 白名单控制 project_cli 可执行的 module/method 集合。
  • 两者职责解耦,避免“技能可见即动作授权”的隐式耦合。

5. CLI Output Contract

CLI handler 的原始成功输出必须是统一结构化结果。

示例:

{
  "ok": true,
  "module": "calendar",
  "method": "read",
  "data": {
    "items": [
      {
        "id": "evt_123",
        "title": "Project sync",
        "startAt": "2026-04-21T10:00:00+08:00"
      }
    ],
    "count": 1
  }
}

失败时,CLI handler 必须返回结构化错误结果。

6. ToolResponse Contract

ToolResponse 只用于给 agent 提供 tool 结果文本投影。

规则:

  • ToolResponse.content 只包含 result 的完整 JSON 文本投影。
  • 不再把完整 ToolAgentOutput 序列化后塞进 ToolResponse.content
  • 文本投影必须与 result 保持等价信息量,不做摘要裁剪。

示例:

{"status":"success","items":[{"id":"evt_123","title":"Project sync","startAt":"2026-04-21T10:00:00+08:00"}],"count":1}

7. Tool Post-Processor Contract

runtime 必须在 tool 调用完成后运行 tool post-processor。

post-processor 负责生成完整 ToolAgentOutput,至少包括:

  • tool_name(固定为 project_cli
  • tool_call_id
  • tool_call_args
  • status
  • result
  • error
  • ui_hints

规则:

  • result 是真源。
  • result 应保留 modulemethoddata
  • ui_hints 由 post-processor 生成,不由 worker 生成。
  • tool 失败时 error 必须为结构化对象。
  • status 必须是 success | failure | partial

ui_hints 输出范围(当前协议):

  • 输出:当前业务 action 中适合稳定结构化展示的调用
    • calendar.read
    • calendar.create
    • calendar.update
    • calendar.delete
    • calendar.share
    • calendar.accept_invite
    • calendar.reject_invite
    • contacts.read
    • memory.update
  • 若某 action 暂无稳定 UI 模板,可不输出 ui_hints,但不能回退为 worker 生成 UI。

8. ToolAgentOutput Contract

ToolAgentOutput 用于系统内部和前端消费,不直接作为模型上下文主输入。

消费位置:

  • TOOL_CALL_RESULT
  • 数据库存储 metadata.tool_agent_output
  • /history tool UI replay
  • cold-path context rebuild

规则:

  • tool_name 固定为 project_cli
  • result 必须是 JSON-native、machine-oriented 结构。
  • 必须包含后续链式调用所需的 ID/outcome/status/count 等事实。
  • ui_hints 是 tool UI 的唯一真源。

推荐的 result 形状:

{
  "module": "calendar",
  "method": "read",
  "data": {
    "id": "evt_123",
    "title": "Project sync"
  }
}

失败时应返回结构化、可纠正的错误对象,而不是只返回泛化文案:

{
  "status": "failure",
  "error": {
    "code": "INVALID_ACTION_INPUT",
    "message": "calendar.read input does not match method schema",
    "module": "calendar",
    "method": "read",
    "input_schema": {
      "mode": "string enum(day|range|event)"
    }
  }
}

9. History Replay Contract

/history 必须支持 tool UI 回放。

规则:

  • history 对外返回 tool message。
  • tool message 的 UI 恢复从 metadata.tool_agent_output.ui_hints 读取,编译为 ui_schema 后返回。
  • tool message content 仍是 result 的 JSON 文本投影。

9.1 messages.content 存储类型决策

  • 当前决策:messages.content 继续保持 text,不迁移到 jsonb
  • 原因:
    • messages 表承担多角色消息(user/assistant/tool),content 统一作为文本载荷更稳定;
    • tool 的结构化数据已经由 metadata.tool_agent_output.resultmetadata.tool_agent_output.ui_hints 承载;
    • /history、SSE、context rebuild 当前都按“content 文本 + metadata 结构化字段”工作,避免双轨 schema 演进;
    • 实测出现过 dict 直接写入 messages.content 导致驱动类型错误(expected str, got dict),保持 text 可减少写入歧义。
  • 约束:凡写入 messages.content 的数据必须是字符串;结构化对象必须进入 metadata

10. SSE Contract

规则:

  • TEXT_MESSAGE_END 不再包含 worker ui_hintsui_schema
  • TOOL_CALL_RESULT 携带 ui_schema(由后端 codec 从 ui_hints 编译而来)。
  • tool UI 前端消费基于 ui_schema(由 ui_hints 编译)。

11. Controlled Credential Contract

tool runtime 的认证边界使用 controlled credential。

规则:

  • chat 与 automation 都不得把 owner_id 当作凭证。
  • controlled credential 由当前 bearer token 签发方在同一信任边界内签发。
  • TTL 目标为 5-10 分钟。
  • 该凭证只覆盖 tool runtime 所需权限窗口。
  • 凭证仅通过 backend-controlled env 注入 CLI。
  • 日志、错误响应、history、SSE 中不得暴露原始凭证。

12. Security Constraints

  • 不开放 shell 执行能力。
  • 不允许通过 tool args 传任意 token。
  • 不允许通过 owner_id 伪造用户 Bearer token。
  • 不允许把 DB session 直接注入 CLI 边界。

13. Compatibility Strategy

  • 策略:migration
  • ui_schema 作为 wire format 保留,由后端 codec 从 ui_hints 编译而来。
  • 前端 renderer 继续消费 ui_schema
  • ui_hints 作为内部字段,不直接传输给前端。
  • 模型侧 command/subcommand/args 输入协议废弃并移除,不保留广义别名兼容。