Files
agent_ops/02.架构设计/90.历史设计归档/01.前期分析与设计/tool-action-design.md
T

389 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LineUp — 协议定义
## 一、工具协议定义
工具协议定义 App 端可以向 Agent 暴露哪些能力,以及每个能力长什么样。
### 1.1 工具定义结构
所有工具使用统一的结构模板,通过 `type` 区分结构差异。
| type | 含义 | 定义结构 |
|------|------|---------|
| `app` | 有状态应用,有生命周期 | `{ name, type, description, actions[] }` |
| `toolset` | 无状态工具集,多个动作 | `{ name, type, description, actions[] }` |
| `action` | 单指令工具,一个动作 | `{ name, type, description, inputSchema }` |
app 和 toolset 包含多个动作,用 `actions` 数组描述。action 只有一个操作,直接用 `inputSchema`,不需要数组包一层。
### 1.2 三类工具的完整定义
#### type: app — 有状态应用
需要生命周期管理,先 open 创建实例,执行动作,最后 close 释放。
```json
{
"name": "canvas",
"type": "app",
"description": "画板应用,支持绘制、撤销、清空等操作",
"actions": [
{
"name": "open",
"description": "创建画板实例,返回 instance_id",
"inputSchema": {
"type": "object",
"properties": {
"width": { "type": "integer", "description": "画板宽度" },
"height": { "type": "integer", "description": "画板高度" }
},
"required": ["width", "height"]
}
},
{
"name": "draw",
"description": "在画板上绘制路径",
"inputSchema": {
"type": "object",
"properties": {
"instance_id": { "type": "string", "description": "画板实例 ID" },
"path": { "type": "string", "description": "SVG 路径数据" },
"color": { "type": "string", "description": "线条颜色" },
"width": { "type": "integer", "description": "线条粗细" }
},
"required": ["instance_id", "path"]
}
},
{
"name": "undo",
"description": "撤销上一步操作",
"inputSchema": {
"type": "object",
"properties": {
"instance_id": { "type": "string", "description": "画板实例 ID" }
},
"required": ["instance_id"]
}
},
{
"name": "clear",
"description": "清空画板内容",
"inputSchema": {
"type": "object",
"properties": {
"instance_id": { "type": "string", "description": "画板实例 ID" }
},
"required": ["instance_id"]
}
},
{
"name": "close",
"description": "关闭画板释放资源",
"inputSchema": {
"type": "object",
"properties": {
"instance_id": { "type": "string", "description": "画板实例 ID" }
},
"required": ["instance_id"]
}
}
]
}
```
#### type: toolset — 无状态工具集
多个动作,无生命周期。每次调用独立,动作间不共享状态。
```json
{
"name": "calculator",
"type": "toolset",
"description": "基础计算器,无状态,每次调用独立",
"actions": [
{
"name": "add",
"description": "两个数相加",
"inputSchema": {
"type": "object",
"properties": {
"a": { "type": "number" },
"b": { "type": "number" }
},
"required": ["a", "b"]
}
},
{
"name": "subtract",
"description": "两个数相减",
"inputSchema": {
"type": "object",
"properties": {
"a": { "type": "number" },
"b": { "type": "number" }
},
"required": ["a", "b"]
}
},
{
"name": "multiply",
"description": "两个数相乘",
"inputSchema": {
"type": "object",
"properties": {
"a": { "type": "number" },
"b": { "type": "number" }
},
"required": ["a", "b"]
}
},
{
"name": "divide",
"description": "两个数相除",
"inputSchema": {
"type": "object",
"properties": {
"a": { "type": "number" },
"b": { "type": "number" }
},
"required": ["a", "b"]
}
}
]
}
```
#### type: action — 单指令工具
只有一个动作,最简结构。
```json
{
"name": "choice",
"type": "action",
"description": "向用户提供一组选项让其选择",
"inputSchema": {
"type": "object",
"properties": {
"question": { "type": "string", "description": "问题描述" },
"options": { "type": "array", "items": { "type": "string" }, "description": "可选列表" }
},
"required": ["question", "options"]
}
}
```
### 1.3 三类工具对比
| | app | toolset | action |
|--|-----|---------|--------|
| 定义字段 | name + type + description + actions[] | name + type + description + actions[] | name + type + description + inputSchema |
| 适用场景 | 需要维护内部状态的应用 | 多个独立功能可归类 | 单个独立功能 |
| 生命周期 | open → use → close | 无 | 无 |
| instance_id | 需要 | 不需要 | 不需要 |
| 调用指定动作 | 每次调用需 action | 每次调用需 action | action 字段仍需传 |
| 示例 | canvas | calculator | choice / confirm / input |
---
## 二、消息协议定义
消息协议定义 Agent 和 App 之间交换的所有消息格式。
### 2.1 统一信封
所有消息使用同一个信封格式。
```json
{
"v": 1,
"id": "消息唯一 ID,用于去重和配对",
"type": "消息类型",
"payload": { }
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| v | integer | 协议版本号 |
| id | string | 消息唯一 ID,全局唯一 |
| type | string | 消息类型 |
| payload | object | 消息内容,按 type 决定结构 |
### 2.2 消息类型
| type | 方向 | 说明 |
|------|------|------|
| `system.hello` | 双向 | 连接握手,交换身份 |
| `system.ping` / `system.pong` | 双向 | 心跳保活 |
| `text` | 双向 | 普通文本消息 |
| `image` | Agent → App | 展示图片 |
| `tool.list` | 双向 | 查询或返回工具列表 |
| `tool.call` | Agent → App | 调用 App 端工具 / 动作 |
| `tool.result` | App → Agent | 返回工具执行结果 |
### 2.3 各类型消息格式
#### system.hello
连接建立后,双方通过 hello 交换身份。
Agent → App
```json
{
"v": 1,
"id": "msg_hello_agent",
"type": "system.hello",
"payload": {
"name": "我的 AI 助手",
"token": "预设的配对 Token",
"agent": "Hermes",
"version": "0.19.0"
}
}
```
App → Agent
```json
{
"v": 1,
"id": "msg_hello_app",
"type": "system.hello",
"payload": {
"name": "我的手机",
"platform": "web",
"version": "1.0.0"
}
}
```
#### text
两边都可以发送。
```json
{
"v": 1,
"id": "msg_001",
"type": "text",
"payload": {
"content": "帮我查一下下周的天气"
}
}
```
#### image
Agent 展示图片给用户。
```json
{
"v": 1,
"id": "msg_002",
"type": "image",
"payload": {
"url": "http://192.168.1.100:9527/files/screenshot.png",
"alt": "系统架构图",
"caption": "这是当前项目的架构图"
}
}
```
#### tool.list
查询 App 端支持哪些工具。
```json
{
"v": 1,
"id": "msg_003",
"type": "tool.list",
"payload": {}
}
```
App 返回含工具列表。
```json
{
"v": 1,
"id": "msg_004",
"type": "tool.list",
"payload": {
"tools": [ ]
}
}
```
#### tool.call
Agent 触发 App 端的一个工具动作。
```json
{
"v": 1,
"id": "msg_005",
"type": "tool.call",
"payload": {
"name": "工具名",
"action": "动作名",
"call_id": "本次调用的唯一 ID",
"arguments": { }
}
}
```
#### tool.result
App 返回工具执行结果给 Agent。
```json
{
"v": 1,
"id": "msg_006",
"type": "tool.result",
"payload": {
"name": "工具名",
"action": "动作名",
"call_id": "对应的调用 ID",
"result": {
"message": "用户操作结果"
}
}
}
```
V1 简化约定:App 返回的用户操作结果统一放在 `result.message` 字段。后续工具需要更丰富的返回格式时(如文件路径、选择详情),再按工具定义扩展 `result` 结构。
---
## 三、协议分层关系
```
通讯协议层(WebSocket 连接、心跳、重连、鉴权)
消息协议层(信封 + 消息类型)
工具协议层(工具定义 + 工具调用流程)
```
三层独立不耦合。通讯层换了,上面两层不用改。消息层升版本号,工具层不受影响。工具层加新工具,上面两层不需要动。
---
## 四、与 MCP 的对应关系
```
MCP LineUp
──────────────────────────────────────
MCP Server ────────────── Tool(画板 / 计算器 / 选择框)
│ │
├─ MCP Tool A ├─ Actionopen / draw / add / select
├─ MCP Tool B ├─ Action
└─ MCP Tool C └─ Action
```
MCP 里每一个 Tool 是无状态的一次性调用单元。LineUp 里 Tool 多了一层容器层。app 类型让有状态工具在逻辑上是一个整体,Agent 看到 canvas 就知道这是一个画板应用,再看 actions 就知道具体可以做什么。