Files

9.2 KiB
Raw Permalink Blame History

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 释放。

{
  "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 — 无状态工具集

多个动作,无生命周期。每次调用独立,动作间不共享状态。

{
  "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 — 单指令工具

只有一个动作,最简结构。

{
  "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 统一信封

所有消息使用同一个信封格式。

{
  "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

{
  "v": 1,
  "id": "msg_hello_agent",
  "type": "system.hello",
  "payload": {
    "name": "我的 AI 助手",
    "token": "预设的配对 Token",
    "agent": "Hermes",
    "version": "0.19.0"
  }
}

App → Agent

{
  "v": 1,
  "id": "msg_hello_app",
  "type": "system.hello",
  "payload": {
    "name": "我的手机",
    "platform": "web",
    "version": "1.0.0"
  }
}

text

两边都可以发送。

{
  "v": 1,
  "id": "msg_001",
  "type": "text",
  "payload": {
    "content": "帮我查一下下周的天气"
  }
}

image

Agent 展示图片给用户。

{
  "v": 1,
  "id": "msg_002",
  "type": "image",
  "payload": {
    "url": "http://192.168.1.100:9527/files/screenshot.png",
    "alt": "系统架构图",
    "caption": "这是当前项目的架构图"
  }
}

tool.list

查询 App 端支持哪些工具。

{
  "v": 1,
  "id": "msg_003",
  "type": "tool.list",
  "payload": {}
}

App 返回含工具列表。

{
  "v": 1,
  "id": "msg_004",
  "type": "tool.list",
  "payload": {
    "tools": [ ]
  }
}

tool.call

Agent 触发 App 端的一个工具动作。

{
  "v": 1,
  "id": "msg_005",
  "type": "tool.call",
  "payload": {
    "name": "工具名",
    "action": "动作名",
    "call_id": "本次调用的唯一 ID",
    "arguments": { }
  }
}

tool.result

App 返回工具执行结果给 Agent。

{
  "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 就知道具体可以做什么。