internal_api.md 20 KB

Tool Agent 内部接口文档

目录

  1. 数据模型
  2. 工具注册表格式
  3. 来源存储格式
  4. 容器状态表格式
  5. 任务书格式
  6. 内部消息格式
  7. 对外 HTTP 接口
  8. Coding Agent 工具接口
  9. 配置参数
  10. Router 工具匹配与对接

1. 数据模型

1.1 枚举类型

架构约束:所有工具对外统一为本地 Python/FastAPI 调用层(uv 管理)。 SourceType / BackendRuntime 表示工具内部的后端执行环境,不是调用方式。

枚举 说明
ToolStatus active, inactive, staging, building 工具生命周期状态
MessageType tool_request, tool_ready, tool_error, health_alert 内部消息类型
ContainerStatus running, destroyed 容器状态
SourceType local, docker, remote 工具来源类型(后端执行环境)
ProcessState stopped, starting, running, error 进程运行状态

1.2 ToolMeta(工具元信息)

{
  "tool_id": "image_compress_api",
  "name": "图片压缩 API",
  "category": "cv",
  "description": "基于 PIL 的图片压缩服务",
  "input_schema": {
    "type": "object",
    "properties": {
      "image_path": {"type": "string"},
      "quality": {"type": "integer", "minimum": 1, "maximum": 100}
    },
    "required": ["image_path"]
  },
  "output_schema": {
    "type": "object",
    "properties": {
      "compressed_size": {"type": "integer"},
      "compression_ratio": {"type": "number"}
    }
  },
  "stream_support": false,
  "status": "active"
}

1.3 ToolSource(工具来源)

{
  "type": "local",
  "host_dir": "tools/local/image_compress_api",
  "endpoint_path": "/",
  "http_method": "POST",
  "internal_port": 0
}

Docker 类型:

{
  "type": "docker",
  "container_id": "25e884ca6cec...",
  "image": "ubuntu:22.04",
  "internal_port": 8080,
  "endpoint_path": "/api/compress",
  "http_method": "POST"
}

Hub 类型(外部 API):

{
  "type": "remote",
  "remote_url": "https://api.example.com",
  "remote_path": "/v1/compress",
  "remote_api_key": "sk-***",
  "endpoint_path": "/v1/compress",
  "http_method": "POST"
}

1.4 ToolRoute(运行状态)

{
  "tool_id": "image_compress_api",
  "sources": [
    {"type": "local", "host_dir": "tools/local/image_compress_api"}
  ],
  "active_source": 0,
  "state": "running",
  "pid": 12345,
  "port": 52341,
  "started_at": "2026-03-26T10:30:00Z",
  "last_error": null
}

1.5 ContainerInfo(容器信息)

{
  "container_id": "25e884ca6cecfa87e19ea737315a8773d...",
  "tool_id": "test_git_tool",
  "image": "ubuntu:22.04",
  "port_mapping": {"8080": 9001, "3306": 9002},
  "volumes": {"C:/staging/project": "/app"},
  "mem_limit": "1g",
  "nano_cpus": 1000000000,
  "use_gpu": false,
  "gpu_count": -1,
  "status": "running",
  "created_at": "2026-03-20T07:31:50.421101Z",
  "last_accessed": "2026-03-20T07:33:16.214642+00:00",
  "destroyed_at": null
}

2. 工具注册表格式 (registry.json)

路径:data/registry.json

{
  "tools": [
    {
      "tool_id": "image_compress_api",
      "name": "图片压缩 API",
      "category": "cv",
      "description": "基于 PIL 的图片压缩",
      "input_schema": {},
      "output_schema": {},
      "stream_support": false,
      "status": "active"
    }
  ],
  "version": "2.0"
}

Registry 查询接口

ToolRegistry 类方法

方法 参数 返回
get(tool_id) tool_id ToolMeta | None
list_all() - list[ToolMeta]
list_active() - list[ToolMeta]
find_by_category(category) category list[ToolMeta]
search(keyword) keyword list[ToolMeta]
register(tool) ToolMeta None
unregister(tool_id) tool_id bool
destroy(tool_id) tool_id dict(清理结果)

3. 来源存储格式 (sources.json)

路径:data/sources.json

{
  "sources": {
    "image_compress_api": [
      {
        "type": "local",
        "host_dir": "tools/local/image_compress_api",
        "endpoint_path": "/",
        "http_method": "POST",
        "internal_port": 0
      }
    ],
    "gpu_tool": [
      {
        "type": "docker",
        "container_id": "abc123...",
        "internal_port": 8080,
        "endpoint_path": "/api/run",
        "http_method": "POST"
      }
    ]
  }
}

SourceStore 接口

方法 参数 返回
load() - dict[str, list[dict]]
save(sources) sources None
add_source(tool_id, source) tool_id, ToolSource None
get_sources(tool_id) tool_id list[ToolSource]
remove_tool(tool_id) tool_id None

4. 容器状态表格式 (containers.json)

路径:data/containers.json

{
  "containers": [
    {
      "container_id": "25e884ca6cec...",
      "tool_id": "gpu_tool",
      "image": "ubuntu:22.04",
      "port_mapping": {"8080": 9001},
      "volumes": {"C:/staging/project": "/app"},
      "mem_limit": "1g",
      "nano_cpus": 1000000000,
      "use_gpu": false,
      "status": "running",
      "created_at": "2026-03-20T07:31:50Z"
    }
  ]
}

5. 任务书格式 (task_spec)

Router 生成任务书,通过 asyncio.create_task 提交给 CodingAgent。

5.1 GitHub 项目接入任务

{
  "type": "github_deploy",
  "repo_url": "https://github.com/user/project",
  "tool_name": "project_api",
  "runtime": "docker",
  "description": "将该项目部署为 HTTP API 工具"
}

5.2 自主编写工具任务

{
  "type": "build_tool",
  "tool_name": "text_summarizer_api",
  "runtime": "uv",
  "description": "编写一个文本摘要工具,接受文本输入,返回摘要"
}

5.3 工具修复任务

{
  "type": "repair_tool",
  "tool_id": "image_compress_api",
  "error": "HTTP 503: Service Unavailable",
  "description": "工具健康检查失败,需要诊断并修复"
}

6. 内部消息格式 (AgentMessage)

Router 与 CodingAgent 通过 MessageBusasyncio.Queue)通信。

当前状态:MessageBus 已实现但未集成,Router 通过直接函数调用启动 CodingAgent。

{
  "type": "tool_request | tool_ready | tool_error | health_alert",
  "payload": {}
}

6.1 tool_request(Router → Coding)

{
  "type": "tool_request",
  "payload": {
    "task_spec": "{ /* 任务书 JSON */ }",
    "task_id": "550e8400-e29b-41d4-a716-446655440000",
    "description": "需要一个图片压缩工具",
    "reference_files": ["tools/local/example/main.py"]
  }
}

6.2 tool_ready(Coding → Router)

{
  "type": "tool_ready",
  "payload": {
    "tool_id": "image_compress_api",
    "result": "部署成功,工具已注册",
    "task_id": "550e8400-..."
  }
}

6.3 tool_error(Coding → Router)

{
  "type": "tool_error",
  "payload": {
    "tool_id": "failed_tool",
    "error": "依赖安装失败:torch 需要 CUDA 但未检测到 GPU",
    "task_id": "550e8400-..."
  }
}

6.4 health_alert(Router → Coding)

{
  "type": "health_alert",
  "payload": {
    "tool_id": "image_compress_api",
    "error": "HTTP 503",
    "last_healthy": "2026-03-20T10:00:00Z"
  }
}

7. 对外 HTTP 接口

基础地址:http://localhost:8001

GET /health

// Response
{"status": "ok"}

POST /search_tools

搜索可用工具列表,返回工具信息及运行状态。

// Request
{
  "keyword": "图片",
  "category": "cv"
}

// Response
{
  "tools": [
    {
      "tool_id": "image_compress_api",
      "name": "图片压缩 API",
      "category": "cv",
      "description": "基于 PIL 的图片压缩",
      "params": [
        {
          "name": "image_path",
          "type": "string",
          "description": "图片路径",
          "required": true
        }
      ],
      "required_params": ["image_path"],
      "input_schema": {},
      "output_schema": {},
      "backend_runtime": "local",
      "host_dir": "tools/local/image_compress_api",
      "endpoint_path": "/",
      "http_method": "POST",
      "state": "running",
      "port": 52341,
      "pid": 12345
    }
  ],
  "total": 1
}

POST /select_tool

选择并调用工具(未启动则自动启动)。

// Request
{
  "tool_id": "image_compress_api",
  "params": {"image_path": "/path/to/img.jpg", "quality": 85},
  "stream": false
}

// Response
{
  "status": "success",
  "result": {"compressed_size": 256000, "compression_ratio": 0.25},
  "error": null
}

POST /create_tool

提交新工具创建需求(异步)。

// Request
{
  "description": "需要一个图片压缩工具",
  "task_spec": "详细任务描述..."
}

// Response
{
  "task_id": "create_a1b2c3d4",
  "status": "pending",
  "message": "Task submitted"
}

GET /tasks/{task_id}

查询异步任务状态。

// Response
{
  "task_id": "create_a1b2c3d4",
  "status": "completed",
  "result": "工具已成功注册",
  "task_spec": "..."
}

GET /tools/status

列出所有工具运行状态。

// Response
{
  "tools": [
    {
      "tool_id": "image_compress_api",
      "sources": [...],
      "active_source": 0,
      "state": "running",
      "pid": 12345,
      "port": 52341
    }
  ]
}

POST /tools/{tool_id}/start

手动启动工具。

// Response
{
  "tool_id": "image_compress_api",
  "state": "running",
  "port": 52341
}

POST /tools/{tool_id}/stop

手动停止工具。

// Response
{
  "tool_id": "image_compress_api",
  "state": "stopped"
}

POST /agent/chat

与 Router Agent 对话交互(自然语言)。

设计理念:外部 Agent 通过自然语言与 Router 交互,Router 理解意图后返回结构化方案,更加人性化和灵活。

支持场景

  • 工具发现与推荐
  • 工具使用方案指导
  • 组合工具使用说明(如 ComfyUI)
  • 工具创建请求
// Request
{
  "message": "用户的自然语言请求",
  "context": {}  // 可选的上下文信息
}

// Response
{
  "reply": "Router 的回复",
  "tools": [],      // 相关工具列表(可选)
  "solution": {},   // 解决方案(可选)
  "task_id": "",    // 任务 ID(创建工具时)
  "next_steps": []  // 后续操作建议
}

示例 1:工具发现

// Request
{
  "message": "我需要处理图片的工具",
  "context": {"task": "批量压缩图片"}
}

// Response
{
  "reply": "找到 2 个图片处理工具,推荐使用 image_compress_api",
  "tools": [
    {
      "tool_id": "image_compress_api",
      "name": "图片压缩 API",
      "reason": "专门用于图片压缩,支持质量调节",
      "usage_example": {
        "params": {"image_path": "/path/to/image.jpg", "quality": 85}
      }
    }
  ],
  "next_steps": ["调用 /select_tool 使用该工具"]
}

示例 2:ComfyUI 工具使用指导

// Request
{
  "message": "如何使用 ComfyUI 的 LoadImage 和 SaveImage 节点?"
}

// Response
{
  "reply": "ComfyUI 节点已通过 runcomfy 工具接入,需要三步操作",
  "solution": {
    "type": "composite_workflow",
    "base_tools": ["runcomfy_launch_env", "runcomfy_run_only", "runcomfy_stop_env"],
    "steps": [
      {
        "step": 1,
        "action": "启动环境",
        "tool": "runcomfy_launch_env",
        "params": {},
        "returns": "container_id"
      },
      {
        "step": 2,
        "action": "执行 workflow",
        "tool": "runcomfy_run_only",
        "params": {
          "container_id": "<from_step_1>",
          "workflow": {
            "nodes": [
              {"id": 1, "type": "LoadImage", "inputs": {"image": "input.png"}},
              {"id": 2, "type": "SaveImage", "inputs": {"images": ["1", 0]}}
            ]
          }
        }
      },
      {
        "step": 3,
        "action": "清理环境",
        "tool": "runcomfy_stop_env",
        "params": {"container_id": "<from_step_1>"}
      }
    ]
  }
}

示例 3:工具创建

// Request
{
  "message": "帮我创建一个文本摘要工具",
  "context": {"requirements": "支持中英文,最大长度 500 字"}
}

// Response
{
  "reply": "已提交工具创建任务,预计 2-3 分钟完成",
  "task_id": "create_a1b2c3d4",
  "status": "pending",
  "tracking": "使用 GET /tasks/create_a1b2c3d4 查询进度",
  "estimated_time": "2-3 分钟"
}

8. Coding Agent 工具接口

CodingAgent 通过 claude_agent_sdk 暴露以下 10 个工具:

Docker 环境

工具 必填参数 可选参数 返回
create_docker_env image mem_limit, nano_cpus, ports, volumes, use_gpu container_id, port_mapping
run_in_docker container_id, command is_background, timeout exit_code, stdout, stderrlog_file
rebuild_docker_ports container_id, ports mem_limit, nano_cpus new_container_id, port_mapping
destroy_docker_env container_id status, message

本地 uv 环境

工具 必填参数 可选参数 返回
create_uv_project name python_version project_dir
run_in_uv project_dir, command is_background, timeout exit_code, stdout, stderr
uv_add_dependency project_dir, package dev status, message

文件操作

工具 必填参数 返回
write_file path, content status, path, size
read_file path status, path, content

注册

工具 必填参数 可选参数 返回
register_tool tool_id, name, description, runtime_type, internal_port category, input_schema, output_schema, container_id, host_dir, endpoint_path, http_method, group_ids status, tool_id, backend_runtime, message

9. 配置参数

Settings(环境变量前缀:TOOL_AGENT_

参数 类型 默认值 说明
fastapi_port int 8001 对外 HTTP 端口
mcp_port int 8001 MCP Server 端口
docker_port_start int 9001 Docker 端口起始
docker_base_image str "agent-sandbox:latest" 默认基础镜像
docker_mem_limit str "1g" 默认容器内存
docker_nano_cpus int 1000000000 默认 CPU(1 核)
docker_ttl_seconds int 1800 容器自动清理 TTL
cold_tool_idle_timeout_s int 300 冷工具空闲超时
hot_tool_max_containers int 5 最大热工具容器数
eviction_policy str "lru" 置换策略
monthly_limit_usd float 100.0 月预算上限
single_tx_limit_usd float 20.0 单笔上限
require_approval_above_usd float 10.0 需审批阈值
health_check_interval_s int 60 健康检查间隔

10. Router 工具匹配与对接

10.1 职责

Router 负责与外部 Agent 对话,将自身工具库与外部工具表进行匹配和对接。

10.2 工具匹配策略

当外部 Agent 请求工具时,Router 执行以下匹配逻辑:

外部 Agent 请求工具 X
       │
       ▼
Router 查询 registry.json
       │
       ├─ 直接匹配:tool_id 或 name 完全匹配
       │   → 返回工具信息,调用 /select_tool
       │
       ├─ 模糊匹配:keyword 匹配 description
       │   → 返回候选列表,由外部 Agent 选择
       │
       ├─ 组合工具匹配:检测是否为复合工具需求
       │   → 例如:ComfyUI 节点工具
       │   → 检查是否有基础工具(如 runcomfy)
       │   → 返回基础工具 + 使用说明
       │
       └─ 无匹配:返回 404
           → 外部 Agent 可选择提交 /create_tool 请求

10.3 ComfyUI 工具对接示例

场景:外部 Agent 请求使用 ComfyUI 内部节点(如 LoadImage, SaveImage

Router 响应策略

  1. 检测 ComfyUI 相关关键词

    • 请求中包含 comfyui, workflow, node 等关键词
    • 或请求的 tool_id 包含 comfyui 相关命名
  2. 查询基础工具

    • 检查 registry 中是否有 runcomfy 相关工具
    • 例如:runcomfy_launch_env, runcomfy_run_only, runcomfy_stop_env
  3. 返回组合工具信息

{
  "status": "composite_tool",
  "message": "ComfyUI 节点工具已通过 runcomfy 基础工具接入",
  "base_tools": [
    {
      "tool_id": "runcomfy_launch_env",
      "name": "启动 ComfyUI 环境",
      "description": "启动 ComfyUI Docker 环境,返回容器 ID 和端口",
      "usage": "先调用此工具启动环境,获取 container_id"
    },
    {
      "tool_id": "runcomfy_run_only",
      "name": "执行 ComfyUI Workflow",
      "description": "在已启动的环境中执行 workflow JSON",
      "usage": "传入 workflow JSON 和 container_id,执行节点流程"
    },
    {
      "tool_id": "runcomfy_stop_env",
      "name": "停止 ComfyUI 环境",
      "description": "停止并清理 ComfyUI 容器",
      "usage": "任务完成后调用,释放资源"
    }
  ],
  "workflow_example": {
    "description": "使用 LoadImage 和 SaveImage 节点的示例",
    "steps": [
      "1. 调用 runcomfy_launch_env 启动环境",
      "2. 构造 workflow JSON(包含 LoadImage, SaveImage 节点)",
      "3. 调用 runcomfy_run_only 执行 workflow",
      "4. 获取输出结果",
      "5. 调用 runcomfy_stop_env 清理环境"
    ],
    "workflow_json": {
      "nodes": [
        {"id": 1, "type": "LoadImage", "inputs": {"image": "input.png"}},
        {"id": 2, "type": "SaveImage", "inputs": {"images": ["1", 0]}}
      ]
    }
  }
}

10.4 工具对接接口

Router 提供以下内部方法支持工具匹配:

方法 参数 返回 说明
match_tool(query) query: str ToolMeta | None 精确匹配 tool_id 或 name
search_tools(keyword, category) keyword, category list[ToolMeta] 模糊搜索
detect_composite_tool(query) query: str dict | None 检测是否为组合工具需求
get_base_tools(composite_type) composite_type: str list[ToolMeta] 获取基础工具列表

10.5 扩展:外部工具表对接

未来规划:Router 可对接外部工具表(如其他 Agent 系统的工具库)

// 外部工具表注册
POST /external_tools/register
{
  "source": "agent_system_x",
  "tools_url": "https://agent-x.com/api/tools",
  "api_key": "sk-***"
}

// Router 查询时同时搜索本地 + 外部工具表
// 返回统一格式的工具列表

附录:工作日志格式

LocalRunner 命令日志 (last_run.log)

路径:{project_dir}/last_run.log

Command: python main.py
Exit Code: 0
--- STDOUT ---
Server started on port 8080
--- STDERR ---
WARNING: Using development server

CodingAgent 执行日志(stdout)

2026-03-26 15:09:32 [tool_agent.tool.agent] INFO: [CodingAgent] Starting task: 部署 flask 项目...
2026-03-26 15:09:35 [tool_agent.tool.agent] INFO: [TOOL_USE] create_docker_env | {"image":"python:3.12-slim","ports":[8080]}
2026-03-26 15:09:40 [tool_agent.tool.agent] INFO: [TEXT] 正在创建 Docker 环境...
2026-03-26 15:10:15 [tool_agent.tool.agent] INFO: [TOOL_USE] register_tool | {"tool_id":"flask_api",...}
2026-03-26 15:10:16 [tool_agent.tool.agent] INFO: [DONE] duration=44000ms
2026-03-26 15:10:16 [tool_agent.tool.agent] INFO: [COST] $0.12