# LineUp Agents v1 — 设计方案 **版本:** v1.1(第二版) **最后更新:** 2026-07-27 --- ## 一、产品定位 LineUp Agents 是一个**远程 Agent 操作交互端**。用户通过手机或 Web App,与运行在本地或服务器上的 AI Agent 进行顺畅的交互。不是任务管理系统,Agent 的任务拆解、执行、管理属于 Agent 自己的工作范畴。 ### MVP 范围 | 做 | 不做 | |----|------| | App 直连 Agent(局域网 WebSocket)| 任务生命周期管理 | | 通过 IM 中转连接 Agent(远程)| 自动化编排、调度 | | App 收发消息、查看 Agent 状态 | 通知推送 | | Agent 调 App 的工具(choice / 画板 / 计算器 等)| MCP 封装 | | 工具发现与调用协议 | 多 Agent 工作流编排 | | 用户 ↔ 用户基础通信(由 IM 平台提供)| 端到端加密(后续加) | --- ## 二、核心设计原则 **LineUp 协议只定义工具交互,不定义基础消息。** 这条原则是整个设计的关键。工具相关的内容(`tool.call`、`tool.result`、`tool.list`)由 LineUp 协议定义。文本、图片、语音、文件等基础消息,由下层传输平台(IM 服务或 WebSocket)原生处理,LineUp 不重复定义。 这让协议非常薄,换传输平台时工具协议不受影响。 --- ## 三、架构总览 ### 3.1 两种网络模式 LineUp 支持两种连接模式,插件根据配置自动切换。 **直连模式(局域网)** ``` Agent 插件 ── WebSocket 端口 :9527 ──→ App 端(Web) ``` Agent 插件在本地开 WebSocket Server,App 端手动输入 IP:端口连接。适合局域网内无公网 IP 的场景。 **中转模式(广域网)** ``` Agent 适配器 ──→ WuKongIM ←── 唐僧叨叨客户端 / LineUp App ▲ │ Webhook / HTTP API 唐僧叨叨业务服务 ``` WuKongIM 负责客户端长连接、消息投递和消息存储;唐僧叨叨业务服务负责用户、好友、群组、文件等 IM 业务能力,并通过 Webhook 与 WuKongIM 协作。客户端以 WuKongIM 官方 SDK 建立长连接,以唐僧叨叨 API 处理业务操作。LineUp 的中转适配器需使用 WuKongIM 官方 SDK 或经验证的协议实现,不能复用其他 IM 平台的网关协议。 ### 3.2 分层架构 ``` ┌──────────────────────────────────────────────┐ │ 工具协议层(LineUp 定义) │ │ 内容:工具定义、tool.call / tool.result │ │ App 渲染 choice / canvas / calculator 等工具 │ ├──────────────────────────────────────────────┤ │ 消息传输层(IM 平台或直连 WebSocket) │ │ 内容:文本 / 图片 / 文件 / 语音的收发 │ │ 直连模式:WebSocket 原生传输 │ │ 中转模式:WuKongIM 消息通道传输 │ ├──────────────────────────────────────────────┤ │ 连接层(IM 平台或 WebSocket Server) │ │ 内容:连接建立、心跳保活、断线重连 │ │ 直连模式:Agent 插件 WS Server │ │ 中转模式:WuKongIM 连接管理 │ └──────────────────────────────────────────────┘ ``` LineUp 协议只关心最上面一层。下面两层由传输平台处理。 ### 3.3 设计决策 | 决策 | 当期结论 | 后续扩展思路 | |------|---------|-------------| | 网络模式 | 局域网直连 + WuKongIM 中转并存 | — | | 中转服务 | 唐僧叨叨业务层 + WuKongIM 通讯层 | — | | Agent 接入方式 | 直连模式用 LineUp 适配器;中转模式待基于 WuKongIM SDK 实现 | — | | IM 平台选型 | WuKongIM;唐僧叨叨提供配套业务层和客户端 | — | | App 端技术方向 | Vite + React(直连模式用 WebSocket;中转模式使用 WuKongIM JS SDK / 唐僧叨叨 API) | 原生移动端 App | | 连接认证 | 直连:预共享 Token;中转:唐僧叨叨用户系统与 WuKongIM Token | 端到端加密 | | 工具路由方式 | 字典路由 | 可引入框架级路由 | --- ## 四、工具协议定义(LineUp 协议的全部内容) LineUp 协议只定义工具相关的三个消息类型。 ### 4.1 工具定义结构 所有工具使用统一的结构模板,通过 `type` 区分行为差异。 | type | 含义 | 定义结构 | |------|------|---------| | `app` | 有状态应用,有生命周期 | `{ name, type, description, actions[] }` | | `toolset` | 无状态工具集,多个动作 | `{ name, type, description, actions[] }` | | `action` | 单指令工具,一个动作 | `{ name, type, description, inputSchema }` | ### 4.2 三类工具的完整定义 #### type: app — 有状态应用 ```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"] } } ``` ### 4.3 三类工具对比 | | app | toolset | action | |--|-----|---------|--------| | 定义结构 | name + type + description + actions[] | name + type + description + actions[] | name + type + description + inputSchema | | 适用场景 | 需要维护内部状态的应用 | 多个独立功能可归类 | 单个独立功能 | | 生命周期 | open → use → close | 无 | 无 | | instance_id | 需要 | 不需要 | 不需要 | | 每次调用需 action | 是 | 是 | 仍需 action 字段 | | 示例 | canvas(画板) | calculator(计算器) | choice / confirm / input | ### 4.4 tool.call 消息格式 ```json { "call_id": "c1", "name": "canvas", "action": "open", "arguments": { "width": 800, "height": 600 } } ``` 字段说明: - `call_id` — 调用方生成,唯一标识一次调用,用于 tool.result 配对 - `name` — 工具名 - `action` — 动作名(app 和 toolset 类型必填,action 类型可省略) - `arguments` — 动作的参数,按 inputSchema 结构传入 ### 4.5 tool.result 消息格式 ```json { "call_id": "c1", "name": "canvas", "action": "open", "result": { "message": "instance_id: inst_001" } } ``` 字段说明: - `call_id` — 与 tool.call 中的 call_id 一致,用于配对 - `name` — 工具名 - `action` — 动作名 - `result` — 返回数据,约定统一放在 result.message,后续按工具定义扩展 ### 4.6 tool.list 消息 ```json { "tools": [ { "name": "choice", "type": "action", "description": "...", "inputSchema": {} }, { "name": "calculator", "type": "toolset", "description": "...", "actions": [] }, { "name": "canvas", "type": "app", "description": "...", "actions": [] } ] } ``` 设备注册和查询工具列表用统一的数据结构。直连模式下双向可查,中转模式下 App 端通过自定义消息类型注册工具。 --- ## 五、完整交互流程 ### 5.1 choice 工具调用 ``` Agent 需要用户做选择 │ ├── Agent 发 tool.call │ { call_id: "c1", name: "choice", action: "select", │ arguments: { question: "部署到哪个环境?", options: ["测试", "预发布", "生产"] } } │ ├── App 渲染选择界面,用户点击"预发布" │ ├── App 返回 tool.result │ { call_id: "c1", name: "choice", action: "select", │ result: { message: "预发布" } } │ └── Agent 拿到结果,继续执行 ``` ### 5.2 canvas 完整生命周期 Agent 调 `canvas` 的 `open` 动作: ```json { "call_id": "c1", "name": "canvas", "action": "open", "arguments": { "width": 800, "height": 600 } } ``` App 返回 instance_id: ```json { "call_id": "c1", "name": "canvas", "action": "open", "result": { "message": "instance_id: inst_001" } } ``` Agent 绘制路径: ```json { "call_id": "c2", "name": "canvas", "action": "draw", "arguments": { "instance_id": "inst_001", "path": "M10 10 L50 50", "color": "red" } } ``` Agent 关闭画板: ```json { "call_id": "c3", "name": "canvas", "action": "close", "arguments": { "instance_id": "inst_001" } } ``` --- ## 六、与 MCP 的关系 ``` MCP LineUp ─────────────────────────────────────── MCP Server ──────────────── Tool(画板 / 计算器 / 选择框) │ │ ├─ MCP Tool A ├─ Action(open / draw / add / select) ├─ MCP Tool B ├─ Action └─ MCP Tool C └─ Action ``` Tool = MCP Server 层,Action = MCP Tool 层。Action 才是实际可调用的最小能力单元。 工具定义格式复用 MCP 的 JSON Schema 标准。 --- ## 七、后续可能的扩展 - 端到端加密,中转不可读消息内容 - 移动端原生 App(目前用响应式 Web) - 直连模式切换到中转模式时的无缝过渡 - 更多 Agent 框架的插件支持(目前以 Hermes 为第一期) - 框架级工具路由替代字典路由