初始化 agent_ops 文档治理体系

This commit is contained in:
2026-08-07 16:56:51 +08:00
commit 10840909ab
75 changed files with 15750 additions and 0 deletions
@@ -0,0 +1,577 @@
# LineUp IM Agent 交互平台:历史方案与实施计划(已归档)
**版本:** 0.2(提案)
**状态:** 已归档;不作为当前技术路线
**日期:** 2026-07-30
**原决策范围:** LineUp 的 IM 基础、人与 Agent 的交互协议、首个 Hermes 接入,以及唐僧叨叨 / WuKongIM 在体系中的职责。
> 归档说明(2026-08-03):本方案依赖唐僧叨叨业务服务与 WuKongIM v2 运行栈;该路线已经退役。当前项目使用 WuKongIM 3.0 官方源码 + LineUp AppServer,客户端与 Mini Runtime 路线见 `lineup-app/` 和 `设计/02.正式方案/`。本文仅保留作为历史决策与兼容性分析记录。
---
## 1. 决策摘要
LineUp 的定位是一个连接**人、人与人协作、人与智能体**的交互平台。它以即时通讯的可靠连接和消息能力为基础,但不把产品限制为传统的聊天窗口。
LineUp 的核心能力是:用户与 Agent 可以在同一个会话中交换文本、媒体、状态、产物和结构化交互;Agent 可在用户授权边界内调用用户端工具,用户端将结构化结果可靠返回给 Agent。
因此,本方案作出以下正式决策:
1. **LineUp 以唐僧叨叨作为成熟 IM 业务层基础,以 WuKongIM 作为通讯内核。** 用户、联系人、群组、文件、工作台与现有多端客户端能力优先复用;仅在 LineUp 的产品需要超出现有能力时再扩展或替换。
2. **LineUp 的正式 Agent 交互通道采用 `增强后的 LineUp Client + WuKongIM 官方 SDK + LineUp 自定义消息协议`。** 该协议在唐僧叨叨的用户与业务体系内运行,不把 LineUp 限制为机器人文本对话。
3. **LineUp Agent Adapter / Gateway 作为外部常驻服务运行,负责连接 Agent Runtime 与 LineUp 协议。** Hermes 是第一个适配目标,后续可接入其他 Agent Runtime。
4. **唐僧叨叨 Robot Events API 是可复用的机器人接入能力。** 它适合快速提供文本型 Hermes 入口、通知和兼容降级;结构化工具交互的正式主载体仍是 LineUp 自定义消息协议。
5. **WuKongIM AI Plugin 不作为第一阶段核心依赖。** 它保留为后续的服务端路由、低延迟流式输出和自动化处理能力;待确认当前部署版本的插件机制与唐僧叨叨配套版本兼容后再评估。
6. **LineUp Client 是对唐僧叨叨客户端能力的面向 Agent 扩展,而不是孤立重造一个聊天客户端。** choice、confirm、canvas、artifact 等由 LineUp 模块实现,同时保留已有 IM 业务体验。
---
## 2. 产品目标与边界
### 2.1 产品目标
LineUp 让人和 Agent 在远程、跨设备、可恢复的 IM 会话中协作。交互不局限于文本问答,而是包含:
- 人与人:文本、图片、语音、文件与群组协作;
- 人与 Agent:自然语言、任务进度、状态、图像、文件和流式内容;
- Agent 与用户端工具:选择、确认、表单、画板、文件预览、设备能力等;
- Agent 与 Agent:在受控会话或频道中交换结构化协作消息;
- 用户对 Agent 的控制:继续、取消、修改指令、批准、拒绝和恢复。
### 2.2 关键体验目标
用户面对的不是一个只会输出文本的机器人,而是一个可呈现和操作工作内容的 Agent 会话。例如:
```text
Agent:需要确认部署目标
└─ LineUp Client 渲染为 choice 卡片
用户:选择“预发布”
└─ Client 返回结构化 tool.result
Agent:开始执行,持续更新进度
└─ Client 渲染进度与状态,不强迫用户阅读多段文本
Agent:生成架构草图
└─ Client 打开画板,持续接收 canvas.patch
用户:点击“暂停”,修改颜色后继续
└─ Client 发送控制事件或 tool.result
```
### 2.3 明确不承担的职责
- LineUp 不取代 Agent Runtime 的任务规划、工具调用引擎或记忆系统;
- LineUp 不把 WuKongIM 替换为自研消息服务器;
- LineUp 不在第一阶段实现多 Agent 编排平台;
- LineUp 不默认授予 Agent 对用户设备、文件或系统操作的无限权限;
- LineUp 不把所有消息都交给服务端 AI 插件处理。
---
## 3. 总体架构
```text
┌─────────────────────────────────────────────────────────────┐
│ LineUp Client(唐僧客户端能力 + 扩展) │
│ │
│ 会话 / 聊天 / 媒体 / 文件 │
│ Agent 状态 / 进度 / 产物 │
│ Tool Registry / Choice / Confirm / Form / Canvas │
│ LineUp 自定义消息渲染与本地授权 │
└───────────────────────┬─────────────────────────────────────┘
│ WuKongIM SDK 长连接
│ 原生消息 + LineUp 自定义 Payload
┌─────────────────────────────────────────────────────────────┐
│ WuKongIM │
│ │
│ 认证后连接、频道、可靠投递、离线同步、重连、顺序、流消息 │
└───────────────────────┬─────────────────────────────────────┘
│ 指定 Agent 频道 / 绑定路由
┌─────────────────────────────────────────────────────────────┐
│ LineUp Agent Adapter / Gateway │
│ │
│ Actor / Device / Conversation 映射 │
│ LineUp 信封编解码、去重、持久 inbox/outbox │
│ call_id 生命周期、超时、取消、恢复、权限校验 │
│ Hermes Adapter、未来其他 Runtime Adapter │
└───────────────────────┬─────────────────────────────────────┘
Hermes / 其他 Agent Runtime 与其本地工具
┌─────────────────────────────────────────────────────────────┐
│ 唐僧叨叨业务层(复用与扩展) │
│ │
│ 用户与认证 / 联系人与群组 / 文件与对象存储 / 工作台 / 管理端 │
│ Android、Web、PC 基础 IM 能力 / Robot Events(可选接入) │
└─────────────────────────────────────────────────────────────┘
```
### 3.1 组件职责
| 组件 | 负责 | 不负责 |
|---|---|---|
| WuKongIM | 长连接、消息投递、离线同步、频道与消息流 | LineUp 工具语义、设备授权、Agent 会话管理 |
| 唐僧叨叨 | LineUp 的 IM 业务基础:用户、认证、好友、群组、文件、工作台、管理端与既有多端客户端 | 替代 LineUp 的 Agent 交互协议与工具语义 |
| LineUp Client | 在唐僧叨叨客户端基础能力上增加交互 UI、工具注册、本地授权、协议显示与回传 | Agent 任务规划与执行 |
| LineUp Adapter / Gateway | 协议路由、可靠性、会话与调用映射、Agent 适配 | 直接替代 IM 服务 |
| Hermes | 理解用户意图、执行任务、调用其工具、请求用户交互 | 负责移动端 UI 渲染 |
| WuKongIM AI Plugin(后续可选) | 服务端高性能路由、流式和自动化 Hook | 定义 LineUp 协议或取代唐僧叨叨业务层与 Adapter |
---
## 4. 协议分层与消息模型
### 4.1 三层分工
```text
LineUp 交互协议层
└─ 会话语义、Actor、设备能力、工具、状态、产物、取消与确认
WuKongIM 消息传输层
└─ 文本、媒体、文件、自定义 Payload 的可靠投递与同步
WuKongIM 连接层
└─ 认证、长连接、心跳、重连、离线恢复
```
LineUp 不重新实现下层 IM 可靠传输;WuKongIM 也不解释 LineUp 的工具和 UI 语义。
### 4.2 统一 LineUp 信封
所有自定义交互消息使用一个可演进的信封。基础媒体仍优先使用 IM 的原生媒体能力;信封保存其交互语义、引用关系或媒体元数据。
```json
{
"v": 1,
"id": "msg_01J...",
"type": "lineup.v1.tool.call",
"conversation_id": "conv_01J...",
"sender": {
"kind": "agent",
"id": "agent_hermes_main"
},
"target": {
"kind": "device",
"id": "device_phone_01"
},
"timestamp": "2026-07-30T14:00:00+08:00",
"payload": {}
}
```
字段规则:
- `v`:协议主版本。未知主版本必须拒绝执行,只可按安全降级显示;
- `id`:全局唯一的应用级消息 ID,用于幂等去重;
- `type`:以 `lineup.v1.` 为命名空间,禁止与基础 IM 类型混淆;
- `conversation_id`:LineUp 会话 ID,不以某一个 IM message ID 代替;
- `sender` / `target`:显式描述人、Agent、设备或群组,而不只依赖底层频道;
- `payload`:仅由对应 `type` 的 schema 定义。
### 4.3 第一批正式消息类型
| 类型 | 方向 | 目的 |
|---|---|---|
| `lineup.v1.text` | 双向 | 与 Agent 相关的结构化文本元数据;普通 IM 文本仍可原生发送 |
| `lineup.v1.device.hello` | Client → Gateway | 设备注册、客户端版本、协议版本、能力摘要 |
| `lineup.v1.tool.list` | 双向 | 声明或查询可用工具与 schema |
| `lineup.v1.tool.call` | Agent → Client | 请求调用用户端工具 |
| `lineup.v1.tool.result` | Client → Agent | 返回工具结果、拒绝、取消或错误 |
| `lineup.v1.tool.cancel` | 双向 | 取消尚未完成的调用 |
| `lineup.v1.agent.status` | Agent → Client | idle / thinking / waiting_input / running / interrupted / failed |
| `lineup.v1.agent.progress` | Agent → Client | 可合并、可覆盖的进度状态 |
| `lineup.v1.artifact.offer` | Agent → Client | 声明图片、文件、网页、报告、画板等可展示产物 |
| `lineup.v1.canvas.open` | Agent → Client | 创建一个受控画板实例 |
| `lineup.v1.canvas.patch` | Agent → Client | 增量更新画板内容 |
| `lineup.v1.canvas.close` | Agent → Client | 关闭画板实例 |
| `lineup.v1.stream.start/delta/end` | Agent → Client | 流式文本、代码、图形或状态输出 |
| `lineup.v1.ui.open/patch/close/event` | 双向 | 受控 HTML/CSS/JS UI Surface 的生命周期与用户事件 |
| `lineup.v1.app.list/call/result` | 双向 | Client 上层应用能力的声明、授权调用与结构化结果 |
不在第一阶段实现的消息类型可以预留命名空间,但不得先发布无 schema 的行为。
UI Surface 与 App Capability 的完整隔离、生命周期和权限约束见[《LineUp UI Surface 与 App Capability 协议》](lineup-ui-surface-protocol.md)。Surface 不是 Agent 在 Client 主进程执行任意代码的通道;它只能运行在受限容器中,并通过预定义 bridge 回传用户事件。任何上层 App / 原生能力必须经 `app.call`、用户确认和 capability registry 执行。
---
## 5. 用户端工具调用规范
### 5.1 工具注册
Client 在设备上线或能力变化后发布 `tool.list`。每个工具至少声明:
```json
{
"name": "choice",
"version": "1.0",
"type": "action",
"description": "展示选项并返回用户选择",
"inputSchema": {},
"outputSchema": {},
"risk": "user_confirmation"
}
```
工具分为三类:
- `action`:一次性操作,如 `choice``confirm``input`
- `toolset`:无状态工具集合,如计算器、文件选择器;
- `app`:有生命周期的交互应用,如 `canvas`,通过 `instance_id` 管理 `open → use → close`
### 5.2 调用与返回
```json
{
"v": 1,
"id": "msg_01J_call",
"type": "lineup.v1.tool.call",
"conversation_id": "conv_01J",
"sender": { "kind": "agent", "id": "agent_hermes_main" },
"target": { "kind": "device", "id": "device_phone_01" },
"payload": {
"call_id": "call_01J",
"name": "choice",
"action": "select",
"expires_at": "2026-07-30T14:10:00+08:00",
"arguments": {
"question": "部署到哪个环境?",
"options": ["测试", "预发布", "生产"]
}
}
}
```
返回必须携带相同 `call_id`,并且结果为可扩展对象,不长期限制为纯字符串:
```json
{
"v": 1,
"id": "msg_01J_result",
"type": "lineup.v1.tool.result",
"conversation_id": "conv_01J",
"sender": { "kind": "human", "id": "user_01" },
"target": { "kind": "agent", "id": "agent_hermes_main" },
"payload": {
"call_id": "call_01J",
"status": "completed",
"result": {
"selected": "预发布"
}
}
}
```
`status` 的第一版枚举为:
```text
completed | rejected | cancelled | expired | unsupported | failed
```
### 5.3 调用状态机
```text
created
→ delivered
→ acknowledged_by_client
→ waiting_user
→ completed | rejected | cancelled | expired | failed
```
规则:
1. `call_id``conversation_id` 范围内唯一;
2. 同一个 `call_id` 的重复 `tool.call` 必须幂等显示,不能重复执行本地副作用;
3. `tool.result` 必须幂等转交给 Agent,Gateway 需持久记录最终状态;
4. Client 离线时调用可等待到 `expires_at`,不得无限期阻塞 Agent
5. 用户、Agent 或系统取消后,旧调用及旧流输出不可覆盖新一代会话状态;
6. 高风险工具没有显式用户授权时,Client 必须返回 `rejected`,而不是静默执行。
---
## 6. 身份、会话、设备与权限
### 6.1 四种核心对象
| 对象 | 说明 | 示例 |
|---|---|---|
| Human | 一个经过 IM 认证的人类用户 | `user_01` |
| Device | 某个具体 Client 实例 | `device_phone_01` |
| Agent | 一个可接收和处理 LineUp 消息的 Agent 实例 | `agent_hermes_main` |
| Conversation | 人、人群或 Agent 间的一段稳定上下文 | `conv_01J` |
底层 WuKongIM 频道负责投递,LineUp `conversation_id` 负责产品语义。一个 Conversation 可映射到单聊、群聊、主题或多个设备,但映射关系必须由 Gateway 显式维护。
### 6.2 权限原则
1. 默认最小权限:Agent 只看得到被明确路由给它的会话;
2. 设备能力显式声明:没有在 `tool.list` 声明的工具不可调用;
3. 风险分级:`display_only``user_confirmation``system_permission``restricted`
4. 人类可取消:用户在任一 Agent 会话中必须可发出取消/中断;
5. 群聊默认只响应明确提及或授权的 Agent;
6. Gateway 记录调用、确认、结果和取消的审计事件;
7. Agent Runtime 的本地终端、文件和浏览器权限不因 IM 通道自动扩大。
---
## 7. 可靠性、重连与用户插入指令
### 7.1 双层可靠性
```text
WuKongIM
└─ 连接、顺序、离线消息、重连与传输级可靠性
LineUp Gateway
└─ 应用级 idempotency、call_id 状态、inbox/outbox、Agent 执行恢复
```
Gateway 维护持久 inbox/outbox。任何消息只有在成功落入 inbox 后才视为被应用层接收;任何对 Agent 或 Client 的关键发送都要记录投递状态和应用级消息 ID。
### 7.2 用户中断
用户的新指令不能因为旧 Agent 任务运行很久而被阻塞:
```text
Client 新消息
→ WuKongIM 实时送达 Gateway
→ Gateway 按 conversation_id 分发
→ Hermes Adapter 调用 Hermes 的会话中断/追加机制
→ 旧 run 标记为过期 generation
→ 旧 run 的迟到输出禁止回写 Client
→ 新指令立即开始或进入指定队列
```
第一版约定:
- 普通新文本:默认 `interrupt` 当前同会话 Agent run
- `/stop` 或显式“停止”:取消当前 run 并通知用户;
- “完成后再……”:由 Client 或 Adapter 标记为 queued follow-up
- 不同 Conversation:相互独立,可并发处理。
---
## 8. 技术选型与当前环境定位
### 8.1 主通道选择
| 方案 | 结论 | 原因 |
|---|---|---|
| 唐僧叨叨业务层 | 正式业务基础 | 已提供用户、认证、联系人、群组、文件、工作台、管理端及多端客户端基础;LineUp 优先在其上生长,而非在第一阶段重新建设这些通用 IM 业务能力 |
| 唐僧叨叨 Robot Events API | 机器人接入与兼容通道 | 具备事件队列、ACK、机器人身份,适合文本 Hermes 入口、通知和降级交互;当前发送能力不适合作为完整结构化工具协议的唯一主载体 |
| WuKongIM AI Plugin | 后续可选 | 适合低延迟和服务端 Hook;当前部署为唐僧叨叨配套 WuKongIM v2,插件协议和管理能力需单独验证,且不替代 Client/Gateway 的产品语义 |
| WuKongIM SDK + 外部 LineUp Gateway | 正式 Agent 交互通道 | 在唐僧叨叨业务体系内保留自定义消息、双向实时、客户端工具、多个 Agent Runtime 与独立演进能力 |
### 8.2 当前部署的使用方式
当前环境维持:
```text
唐僧叨叨服务端 v1.5 + WuKongIM v2 + MySQL + Redis + MinIO
监听:100.121.118.116Tailscale
```
该环境在本方案中的职责:
- 以唐僧叨叨作为 LineUp 的既有业务基础,继续提供用户、认证、联系人、群组、文件、工作台和管理能力;
- 以 WuKongIM 承担基础 IM 服务、长连接、离线同步和自定义消息传输;
- 以现有唐僧 Android / Web 作为可复用的客户端基础,并逐步加入 LineUp 交互渲染与工具模块;
- 用于验证 LineUp Client 的 SDK 连接、消息、离线和媒体行为;
- 为 LineUp Gateway 提供受控网络内的消息服务;
- 可选提供唐僧 Robot Events 文本机器人、通知和降级入口。
不得为了启用 AI Plugin 而直接将该稳定配套环境替换为 WuKongIM 主线版本;插件实验必须使用独立测试实例。
---
## 9. 分阶段实施计划
### Phase 0:协议与可行性基线
**目标:** 在不改变现有生产性 IM 数据的前提下,确认 WuKongIM v2 可以承载 LineUp 自定义 Payload。
**工作项:**
1. 定义 `lineup.v1` 自定义 Payload 的编码、消息类型编号和最大体积;
2. 使用两个测试账户,通过官方 SDK 收发并解码一条 LineUp 信封;
3. 验证离线消息、多设备同步、顺序、重复投递与撤回等边界;
4. 验证图片、文件与自定义交互消息的引用关系;
5. 定义测试频道/Agent 身份命名规范;
6. 记录 WuKongIM v2 的精确 SDK 与协议限制。
**验收标准:**
- 任一端离线重连后,`lineup.v1.tool.call` 不丢失且不重复执行;
- 自定义消息可以被测试 Client 正确识别;
- 不改变现有唐僧叨叨用户、消息和 Docker 命名卷。
### Phase 1LineUp 协议核心与最小 Gateway
**目标:** 打通 Client、Gateway 与一个模拟 Agent 的双向结构化交互。
**工作项:**
1. 实现 LineUp 信封编解码库与 JSON Schema
2. 实现 Gateway 的 Actor、Device、Conversation 映射;
3. 实现 SQLite 持久 inbox/outbox 与消息去重;
4. 实现 `device.hello``tool.list``tool.call``tool.result``tool.cancel`
5. 实现 `call_id` 状态机、超时和审计;
6. 使用模拟 Agent 发起 `choice``confirm`
**验收标准:**
- Client 断线、Gateway 重启后,待处理工具调用仍可恢复;
- 重复投递不导致工具执行两次;
- 不受支持工具返回 `unsupported`
- 用户拒绝、取消、超时能精确回到对应 Agent 调用。
### Phase 2LineUp Client 最小交互面
**目标:** 从“聊天 UI”进入“Agent 交互 UI”。
**工作项:**
1. 基于现有唐僧叨叨客户端能力建立 LineUp Client 扩展层或受控分叉,保留登录、联系人、聊天、媒体与文件基础;
2. 接入并验证 WuKongIM SDK 的 LineUp 自定义 Payload
3. 实现文本、Agent 状态、进度、choice、confirm、input
4. 实现工具注册、风险提示、用户授权与结果回传;
5. 实现会话列表中的 Agent 标识、运行状态与取消入口;
6. 实现最小 Artifact 展示:图片与文件;
7. 记录客户端能力及版本兼容策略。
**验收标准:**
- 用户可在手机上完成 Agent 发起的选择和确认;
- Agent 能得到结构化而非文本猜测式的结果;
- 用户可在 Agent 工作期间中断并发送替代指令;
- 图片、文件与进度不会破坏普通人与人聊天。
### Phase 3Hermes 首个正式 Adapter
**目标:** Hermes 成为第一个完整支持 LineUp 协议的 Agent Runtime。
**工作项:**
1. 实现 Hermes ↔ Gateway Adapter
2. 将 LineUp Conversation 映射到 Hermes session
3. 将用户新消息、取消和排队指令映射到 Hermes 原生会话控制;
4. 将 Hermes 的工具等待映射为 `tool.call` / `tool.result`
5. 将 Hermes 进度、状态和产物映射为 LineUp 消息;
6. 实现按用户/群组/Agent 的访问控制与审计。
**验收标准:**
- Hermes 可以发起 `choice` / `confirm` 并等待手机端结果后继续;
- 任务中途的新指令能取消旧 run,旧输出不会污染新会话;
- Gateway 或 Hermes 重启时不重复执行不可逆工具调用;
- 白名单外用户不能访问 Hermes 的本地执行能力。
### Phase 4:富交互与机器人接入
**目标:** 扩展产品表达能力,同时保持现有唐僧客户端可用。
**工作项:**
1. 实现 `canvas.open/patch/close` 与基础画板;
2. 实现 Artifact 卡片、图片预览、文件产物和流式状态;
3. 建立 `lineup_hermes` 唐僧机器人,提供文本入口、通知和不支持富交互时的安全降级;
4. Robot Events Adapter 将文本对话接入 Hermes
5. 对尚未安装 LineUp 扩展能力的客户端,发送安全的降级文本与 LineUp Client 跳转提示;
6. 建立跨客户端能力协商策略。
**验收标准:**
- LineUp Client 可以呈现至少一种非文本 Agent 交互(画板或结构化表单);
- 唐僧客户端仍可完成文本对话和基础确认降级;
- 两种入口不会对同一会话产生重复 Agent 回复。
### Phase 5WuKongIM AI Plugin 评估与增强
**前置条件:** 仅在独立测试实例确认当前 WuKongIM 版本、插件协议、插件管理与唐僧叨叨兼容边界后启动。
**目标:** 评估服务端 Plugin 是否为 LineUp 带来明确收益。
**评估项:**
- 流式延迟与 Gateway 外部 SDK 通道的对比;
- 插件绑定是否能精确限定 Agent 频道;
- 插件崩溃、升级、滚动重启的影响;
- Go Plugin 与 Hermes/Python 外部 Runtime 的超时、取消和恢复;
- 与唐僧叨叨 webhook 的消息所有权和重复处理风险;
- 安全审计、配置密钥和多租户隔离。
只有存在可量化收益时,才将 Plugin 用作 Gateway 的优化实现或服务端路由层。
---
## 10. 近期执行顺序
本方案确认后,近期工作的严格顺序如下:
```text
1. Phase 0:验证 WuKongIM v2 自定义 Payload 与 SDK 行为
2. 固化 LineUp v1 消息 schema 与 call 状态机
3. 建立最小外部 LineUp Gateway(模拟 Agent
4. 在唐僧叨叨客户端基础上实现 LineUp 最小交互:choice / confirm / input
5. 实现 Hermes 正式 Adapter
6. 补唐僧机器人作为文本、通知和降级入口
7. 最后才评估 WuKongIM AI Plugin
```
### 10.1 各阶段目标概览
| 阶段 | 阶段目标 | 完成后得到什么 |
|---|---|---|
| 1. 验证 WuKongIM 自定义消息能力 | 证明当前唐僧叨叨配套的 WuKongIM v2 能可靠传输 LineUp 自定义 Payload | 确认 IM 基础能够承载 `tool.call``tool.result` 等协议,而不是只能传普通文本 |
| 2. 固化 LineUp 协议 | 明确消息格式、类型、版本、会话、调用 ID、取消和错误语义 | Client、Gateway、Hermes 可遵循同一份可测试、可版本化的协议契约 |
| 3. 建立最小 Gateway | 建立 IM 和 Agent 之间的常驻中枢,负责收发、去重、会话映射与持久化 | 得到可靠的 LineUp 交换站,Client 或 Agent 重启时关键交互仍可恢复 |
| 4. 实现最小 LineUp Client | 在唐僧叨叨客户端基础上,让客户端从文本聊天界面进入可操作的 Agent 交互界面 | 用户可执行 choice、confirm、input 等结构化交互,而非回复编号或自然语言猜测 |
| 5. 接入 Hermes | 将真实 Hermes 会话映射为 LineUp 会话和工具调用 | 用户可远程操控 Hermes,Hermes 可请求确认、获得结果、展示状态并被中断 |
| 6. 提供唐僧叨叨机器人入口 | 在既有唐僧叨叨业务与客户端体系内提供 Hermes 文本、通知和降级交互 | 为尚未具备 LineUp 富交互能力的客户端提供可用入口;复杂操作安全降级为文本 |
| 7. 评估 WuKongIM AI Plugin | 判断服务端插件是否能在当前兼容边界内带来可量化收益 | 在确认版本、稳定性和收益后,决定是否加入低延迟流式与服务端路由增强层 |
依赖关系如下:
```text
先证明 IM 能传 LineUp 消息
再规定 LineUp 消息、会话和工具调用的统一语义
建立可靠的 Gateway
让 Client 将结构化消息渲染为可操作 UI
接入 Hermes,形成真实的人—Agent 协作闭环
补充唐僧叨叨机器人文本、通知与降级入口
最后按实际收益评估 WuKongIM AI Plugin
```
这保证产品核心先围绕“人和 Agent 的结构化协作”落地,而不是被某个现有 IM 客户端的文本机器人能力限制。
---
## 11. 与既有文档的关系
本方案继承早期文档中以下原则:
- 三层分离:连接层、消息传输层、工具/交互层;
- LineUp 协议只定义上层交互,不重复实现 IM 基础能力;
- `tool.call` / `tool.result` 使用结构化数据与 `call_id` 配对;
- Agent Runtime 插件化接入,避免将所有 Agent 逻辑写入客户端。
- 唐僧叨叨作为成熟 IM 业务层和客户端基础,优先复用并按 LineUp 实际需求扩展。
本方案替换或细化以下早期假设:
- 不再将“官方唐僧叨叨客户端上的文本机器人”视为 LineUp 的唯一体验;机器人是完整业务体系中的一种 Agent 接入形式;
- 不再将“基于某一个 Agent 的 WebSocket 插件”视为广域网交互的唯一架构;
- 正式引入 Client、Device、Agent、Conversation 与持久化 Gateway 的边界;
- 将自定义 IM Payload、客户端工具注册、调用状态机、取消与权限模型列为 MVP 基础,而不是后续附加能力;
- LineUp 的新增能力以唐僧叨叨已有用户、群组、文件、工作台和多端客户端能力为基础生长,不预设重造整套 IM 业务系统。
@@ -0,0 +1,441 @@
# LineUp Agents — MVP 产品与技术规格
**状态:** v0.1 / 讨论稿
**日期:** 2026-07-24
**目标:** 用最小可行的服务端、Web 客户端和 Agent Adapter,验证“统一的人机协作交互层”是否成立。
---
## 1. 一句话定义
**LineUp Agents 是一个面向个人与小团队的 Agent 协作入口:人通过统一的对话、任务、状态与确认组件,连接并管理自己已经拥有的 AI Agent。**
它类似于一个为 Agent 设计的 Channel:不是替换 OpenClaw、Codex、Hermes 或自定义运行时,而是把它们接入一个更适合持续协作的交互层。
## 2. 讨论结论与产品判断
| 已达成的判断 | 对首版的含义 |
|---|---|
| 先做好交互,不急着做万能 Agent 平台 | 任务、状态、确认和展示是核心,不把能力重心放在模型或编排 |
| Agent 的长期运行需要服务端 | 服务端持久化事件、会话和任务;客户端可随时离开和回来 |
| 主流 Agent 应能接入 | 定义轻量、事件驱动的 Adapter 协议,而非绑定单一框架 |
| 配置必须简单通用 | 用户只需绑定 Agent、选择会话、开始协作;复杂部署隐藏在 Adapter 后 |
| 自动拆分/分配可探索,但自动可靠完成仍很难 | v0.1 允许 Agent 报告子任务;不做自动抢占、调度或自治执行承诺 |
## 3. 问题与目标用户
### 3.1 要解决的问题
今天的人机协作通常被困在终端、网页聊天页或某个框架专属界面中。用户很难跨端了解:
- 我的 Agent 现在是否正在执行、卡在哪里、是否失联?
- 它何时需要我确认、补充信息或授权?
- 多个持续任务之间,哪个最重要、哪个已经完成?
- 换一个 Agent 框架后,为什么交互与历史记录都断裂?
LineUp 的工作不是替 Agent 思考,而是把这些协作状态变得可见、可控、连续。
### 3.2 首批用户
1. **重度个人 Agent 用户**:在本机或 VPS 上长时间运行一个或多个 Agent,希望在手机和 Web 上随时查看和介入。
2. **小型 AI 原生团队**:成员共享少量部署好的 Agent,需要看清谁在处理什么、何时要人类决策。
3. **Agent/Runtimes 开发者**:希望用少量接入工作获得成熟交互界面,而不是重造消息、任务与通知系统。
### 3.3 北极星任务
> 我在外出时收到一条通知:我的代码 Agent 需要决定是否执行数据库迁移。我打开 LineUp,看见完整任务上下文、影响说明和两个清晰选项;批准后 Agent 继续执行,我随后能看到结果与相关产物。
## 4. 产品原则
1. **状态先于文本。** 聊天记录很重要,但“正在运行”“等待我”“已失败”必须一眼可见。
2. **人保留关键控制权。** 有风险、费用、外部副作用的行动必须能由 Agent 发起清晰的确认请求。
3. **Agent 无关,但不抹平差异。** 统一最小能力;框架特有能力可通过扩展卡片展示。
4. **渐进披露。** 默认只展示当前决策所需的信息;详细日志、原始事件和调试字段按需展开。
5. **每一件事都可追溯。** 任务、消息、审批和状态转换写入不可变事件流,便于同步与审计。
6. **先轻后重。** 先交付一个连接可靠、体验细腻的 Channel,再逐步增加任务协作能力。
## 5. MVP 范围
### 5.1 必须交付
| 能力 | 用户价值 | v0.1 交付 |
|---|---|---|
| Agent 绑定 | 连接用户已有 Agent | 配对码/Token 绑定、Agent 在线状态、撤销绑定 |
| 会话 | 保持对话连续 | 会话列表、消息流、流式文本、附件链接 |
| 任务 | 看清长期工作 | 创建任务、状态、进度、父子任务展示、取消请求 |
| 人类介入 | 不让 Agent 默默卡住 | 单选、多选、文本补充、批准/拒绝四类交互卡片 |
| 实时同步 | 跨端了解当前状态 | WebSocket、断线重连、顺序事件、离线补偿 |
| 通知 | 用户离开时仍可介入 | 浏览器通知/邮件二选一,优先通知“等待用户”和“失败” |
| Adapter SDK | 接入至少一个实际 Agent | TypeScript SDK + 示例 Adapter + 事件协议文档 |
### 5.2 明确不做
- 自动从自然语言可靠拆解、排程并完成任意复杂任务。
- Agent 之间的自动抢单、竞价、自治协调与长期记忆治理。
- 模型 API 代理、模型计费、Sandbox 执行器或完整远程桌面。
- 企业 SSO、复杂 RBAC、多租户计费与组织级合规功能。
- 原生 iOS/Android App;首版先用响应式 Web 验证交互模型。
## 6. 信息架构
```text
工作区
├── 收件箱
│ ├── 等待我处理
│ ├── 失败 / 需要关注
│ └── 最近完成
├── 会话
│ └── 一个会话对应人与一个或多个 Agent 的协作上下文
├── 任务
│ ├── 全部
│ ├── 进行中
│ ├── 等待我
│ └── 已完成 / 已取消
├── Agent
│ ├── 在线状态与能力
│ ├── 绑定 / 配置
│ └── Adapter 诊断日志
└── 设置
└── 用户、通知、开发者 Token
```
### 6.1 核心对象
| 对象 | 含义 | 关键字段 |
|---|---|---|
| Workspace | 数据与访问边界 | `id`, `name` |
| User | 使用者 | `id`, `displayName` |
| Agent | 一个可连接的 Agent 实例 | `id`, `name`, `runtime`, `status`, `capabilities` |
| Conversation | 一个协作上下文 | `id`, `workspaceId`, `title`, `agentIds` |
| Message | 用户、Agent 或系统产生的内容 | `id`, `conversationId`, `author`, `content`, `createdAt` |
| Task | 可追踪的工作单元 | `id`, `conversationId`, `parentTaskId`, `title`, `status`, `progress` |
| Interaction | 必须由用户处理的结构化请求 | `id`, `taskId`, `type`, `status`, `payload`, `expiresAt` |
| Event | 所有状态变化的事实记录 | `id`, `sequence`, `type`, `subject`, `payload`, `occurredAt` |
### 6.2 任务状态机
```mermaid
stateDiagram-v2
[*] --> queued
queued --> running: Agent 接受 / 用户开始
running --> waiting_for_human: 发起 Interaction
waiting_for_human --> running: 用户响应
running --> succeeded: 完成
running --> failed: 失败
queued --> cancelled: 取消
running --> cancelled: 取消确认 / Agent 停止
waiting_for_human --> cancelled: 用户取消
succeeded --> [*]
failed --> [*]
cancelled --> [*]
```
状态定义:
- `queued`:任务已创建、尚未由 Agent 接受。
- `running`:Agent 正在执行,允许不断上报进度与日志摘要。
- `waiting_for_human`:工作被一个未处理的 Interaction 阻塞,应进入收件箱并通知用户。
- `succeeded` / `failed` / `cancelled`:终态;任务和完整事件历史可查。
## 7. 关键交互
### 7.1 首次连接 Agent
1. 用户在「Agent」页点击“连接我的 Agent”。
2. 选择 Adapter 类型(首版:Generic SDK;后续可有 OpenClaw 预设)。
3. 服务端生成一次性配对码和安装命令;配对码有效期 10 分钟。
4. 用户在 Agent 所在机器运行 AdapterAdapter 用配对码建立出站 WebSocket。
5. 服务端显示 Agent 名称、版本、可用能力与在线状态;用户确认命名后完成绑定。
**体验要求:** 不要求用户开放入站端口;Agent 主动连接中转服务。连接失败时必须显示可复制的诊断码及下一步建议。
### 7.2 发起与跟进一个任务
1. 用户在会话底部输入自然语言需求,可勾选“作为任务跟踪”。
2. 系统先创建 `task.created`,再把文本作为 `message.created` 发送给目标 Agent。
3. Agent 接受后上报 `task.status_changed: running`,可持续上报 0–100 的进度和一句简短状态。
4. 用户可在会话内看简要进度,也可打开任务详情查看子任务、产物和事件时间线。
5. Agent 完成、失败或需要人类处理时,状态即时同步到任务列表和收件箱。
### 7.3 Agent 请求人类决策
交互卡片的结构为:**为什么需要你 → 影响是什么 → 你能做什么 → 详细信息(折叠)**。
| 卡片类型 | 示例 | 必填交互 |
|---|---|---|
| `approval` | “将执行生产数据库迁移” | 批准 / 拒绝;可选备注 |
| `choice` | “部署区域选择” | 2–5 个选项;可标注推荐项 |
| `input` | “请提供测试环境 URL” | 文本输入、格式校验 |
| `review` | “请检查生成的变更计划” | 展示内容或附件;批准 / 要求修改 |
响应后,卡片变为只读并保留“谁在何时作出什么决定”;对应事件发送回 Agent,任务恢复 `running`
### 7.4 Agent 失联与恢复
- WebSocket 心跳间隔 25 秒;连续 2 次未收到心跳标记为 `offline`
- 运行中任务不立刻标为失败,而显示“Agent 连接中断”,并保留最后心跳时间。
- Adapter 重连后携带最后确认的 `sequence`;服务端补发缺失下行事件。
- 若 Agent 在配置的宽限期(默认 15 分钟)后仍未恢复,任务改为 `failed`,原因是 `agent_unreachable`
## 8. 页面与组件规格
### 8.1 桌面端主界面
```text
┌──────────────┬───────────────────────────────────────┬──────────────────────┐
│ 工作区 │ 会话:网站重构 │ 任务详情 │
│ │ │ │
│ 收件箱 (2) │ [用户] 分析现有页面并提交改进建议 │ ● 正在执行 60% │
│ 会话 │ │ “整理组件依赖” │
│ 任务 │ [Agent] 已建立任务计划,正在扫描仓库… │ │
│ Agent │ │ 子任务 │
│ │ ┌───────────────────────────────────┐ │ ✓ 扫描仓库 │
│ │ │ 需要你的确认 │ │ ● 整理组件依赖 │
│ │ │ 允许安装 3 个开发依赖? │ │ ○ 输出迁移方案 │
│ │ │ [查看变更] [拒绝] [允许] │ │ │
│ │ └───────────────────────────────────┘ │ 事件时间线 │
│ │ │ │
│ │ 输入消息… [发送] │ │
└──────────────┴───────────────────────────────────────┴──────────────────────┘
```
**响应式规则:** 宽度小于 900px 时隐藏右侧详情为抽屉;小于 640px 时侧栏收起,顶部保留收件箱未读数和 Agent 在线指示。
### 8.2 首版设计令牌
```css
:root {
--surface-canvas: #f7f8fa;
--surface-default: #ffffff;
--surface-subtle: #f1f3f5;
--text-primary: #1b1f24;
--text-secondary: #59636e;
--border-subtle: #d8dee4;
--brand: #356ae6;
--status-running: #356ae6;
--status-waiting: #b7791f;
--status-success: #168a5b;
--status-danger: #c93c37;
--radius-card: 12px;
--radius-control: 8px;
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-6: 24px;
}
```
可访问性底线:正文与背景对比度至少 4.5:1;不只依靠颜色表达状态;所有卡片操作支持键盘焦点、Enter/Space 触发及明确的加载/提交结果。
## 9. 系统架构
```mermaid
flowchart LR
subgraph Clients[用户客户端]
WEB[响应式 Web]
MOBILE[未来移动端]
end
subgraph Cloud[LineUp 中转服务]
API[HTTPS API]
RT[Realtime Gateway\nWebSocket]
AUTH[身份与设备绑定]
APP[协作应用服务]
DB[(PostgreSQL)]
BUS[(Event / Job Queue)]
PUSH[通知服务]
end
subgraph UserEnv[用户的本机或服务器]
ADAPTER[LineUp Adapter]
RUNTIME[OpenClaw / Codex /\nHermes / 自定义 Agent]
end
WEB <-- HTTPS + WS --> API
WEB <-- HTTPS + WS --> RT
MOBILE <-- HTTPS + WS --> API
MOBILE <-- HTTPS + WS --> RT
API --> AUTH
API --> APP
RT --> APP
APP --> DB
APP --> BUS
BUS --> PUSH
ADAPTER <-- 出站 WSS --> RT
ADAPTER <--> RUNTIME
```
### 9.1 推荐实现取舍
| 层 | 首版选择 | 原因 |
|---|---|---|
| Web | Next.js + TypeScript | 同时覆盖 Web、响应式移动体验与后续 BFF 需求 |
| 服务端 | TypeScriptFastify/NestJS 任选其一) | 与 SDK 共享类型和校验器,迭代快 |
| 实时连接 | 标准 WebSocket | 对 Agent 和客户端都简单;协议可公开 |
| 数据 | PostgreSQL | 可靠存储、查询任务,JSONB 容纳扩展事件 |
| 临时事件/队列 | Redis Streams 或 BullMQ | 处理通知、投递重试和长连接广播 |
| Adapter SDK | TypeScript 首发 | 覆盖主要 Node Agent;协议保持语言无关 |
| 鉴权 | 短期 Access Token + Agent 配对 Token | 安全模型足够简单,后续可演进 OAuth/设备授权 |
**关键边界:** 业务服务不执行 Agent 的工具调用,也不存放模型密钥。它仅路由已认证事件、持久化协作状态,并向用户端可靠同步。
## 10. 最小事件协议(LAP/0.1
所有 WebSocket 帧使用统一 envelope。`payload``type` 做 schema 校验;未知字段容忍但记录,未知事件类型忽略并保留兼容性告警。
```ts
type Envelope<T = unknown> = {
id: string; // UUID,幂等键
type: string; // 如 task.status_changed
version: '0.1';
occurredAt: string; // ISO 8601 UTC
workspaceId: string;
conversationId?: string;
taskId?: string;
sequence?: number; // 服务端下行事件全局递增序号
correlationId?: string; // 串联一次用户请求和后续事件
payload: T;
};
```
### 10.1 用户端 → 服务端
| 事件 | 说明 | 关键 payload |
|---|---|---|
| `message.create` | 发消息 | `content`, `targetAgentId` |
| `task.create` | 创建受跟踪任务 | `title`, `description`, `targetAgentId` |
| `interaction.respond` | 回应卡片 | `interactionId`, `response` |
| `task.cancel_requested` | 请求取消 | `reason?` |
### 10.2 Agent → 服务端
| 事件 | 说明 | 关键 payload |
|---|---|---|
| `agent.hello` | Adapter 握手与能力声明 | `agentVersion`, `runtime`, `capabilities`, `lastSequence?` |
| `message.create` | Agent 文本或富内容 | `content`, `blocks?` |
| `task.accepted` | 接受任务 | `taskId` |
| `task.status_changed` | 上报状态或进度 | `status`, `progress?`, `summary?`, `error?` |
| `task.child_created` | 仅用于展示的子任务 | `parentTaskId`, `title`, `status` |
| `interaction.requested` | 请求用户输入或确认 | `interaction` |
| `artifact.created` | 上报链接/文件/结果 | `name`, `url`, `mimeType?`, `summary?` |
### 10.3 服务端 → Agent
| 事件 | 说明 |
|---|---|
| `task.assigned` | 新任务及所属会话上下文 |
| `message.delivered` | 用户追加消息 |
| `interaction.resolved` | 用户的结构化回答 |
| `task.cancel_requested` | 用户请求停止 |
| `system.resync_required` | Adapter 无法从断点恢复,需拉取或重建状态 |
### 10.4 Interaction 示例
```json
{
"type": "interaction.requested",
"version": "0.1",
"id": "evt_01J...",
"occurredAt": "2026-07-24T12:00:00Z",
"workspaceId": "ws_01J...",
"conversationId": "conv_01J...",
"taskId": "task_01J...",
"payload": {
"interaction": {
"id": "int_01J...",
"type": "approval",
"title": "允许执行数据库迁移吗?",
"description": "此操作会在 production 执行 3 个已审阅的迁移文件。",
"risk": "high",
"options": [
{ "id": "approve", "label": "允许执行", "style": "primary" },
{ "id": "reject", "label": "拒绝", "style": "danger" }
],
"details": { "migrationCount": 3, "environment": "production" },
"expiresAt": "2026-07-25T12:00:00Z"
}
}
}
```
## 11. 安全与可靠性基线
- Agent 仅建立**出站** TLS WebSocket;用户无需暴露本机端口。
- 配对码为一次性、短有效期且仅用于兑换 Agent 凭据;凭据可单独撤销。
- 每一个 Agent 凭据限定到单 Workspace 和 Agent 身份,禁止跨工作区投递。
- 写入事件必须使用 envelope `id` 去重;客户端与 Adapter 应能安全重发。
- 明确区分“取消请求”与“已取消”:只有 Agent 确认停止或超时策略生效后任务才进入终态。
- 记录审批摘要、响应人、时间和关联任务;不要默认把原始敏感输入发到通知正文。
- 默认保留最小化运行日志;敏感字段可在 Adapter 侧脱敏后再上报。
## 12. 验证指标与首轮测试
### 12.1 产品假设
如果用户能在离开 Agent 所在机器后,仍清楚掌握任务状态并在 30 秒内完成关键介入,那么他们会愿意把更多长期任务交给已连接的 Agent。
### 12.2 成功指标
| 指标 | 首轮目标 |
|---|---|
| 成功绑定一个 Agent 的比例 | ≥ 80% |
| 从收到“等待用户”通知到完成处理的中位时间 | < 60 秒 |
| 用户判断任务当前状态的正确率 | ≥ 90% |
| 消息/状态在在线情况下端到端可见延迟 P95 | < 1 秒 |
| Agent 重连后未丢失的待处理事件比例 | 100% |
| 试用用户愿意在下一周继续连接 Agent 的比例 | ≥ 60% |
### 12.3 5 人可用性测试
找 3 位已有 Agent 使用经验的用户与 2 位刚接触长任务 Agent 的用户;每人完成以下任务:
1. 连接一个模拟 Agent,说明它是否在线。
2. 创建“整理项目依赖并产出计划”的任务,定位它的当前进度。
3. 在不打开日志的前提下处理一个高风险批准请求。
4. 让 Agent 断线并恢复,判断任务是否需要重新开始。
记录完成率、完成时间、误操作、口头疑问和 SUS 问卷。任何导致用户错误批准高风险行为的问题均视为 P0,必须在公开测试前解决。
## 13. 实施顺序与分工建议
### 13.1 三个迭代
| 迭代 | 目标 | 可演示结果 |
|---|---|---|
| I1:连通性 | 账户/工作区、配对、WebSocket、事件存储 | 一个模拟 Agent 在线,能发收消息 |
| I2:协作闭环 | 会话、任务状态、Interaction 卡片、收件箱 | 用户能创建任务、远程批准、看到 Agent 继续与完成 |
| I3:可靠性 | 重连补偿、通知、审计、示例 Adapter | Agent 断线恢复后协作连续,能供首批用户试用 |
### 13.2 初始分工(两人)
| 负责人 | 主责 | I1I3 输出 |
|---|---|---|
| Stephen | 中转服务与协议 | 数据模型、事件路由、WebSocket、鉴权、Adapter SDK、模拟 Agent |
| 爱德姆 | 产品交互与客户端 | 信息架构、Web 交互、任务/确认卡片、连接引导、可用性测试与反馈整理 |
共同决策:协议版本、风险确认策略、首个真实 Agent Adapter 的接入优先级。每周用一段真实的 Agent 长任务进行端到端验收,而不是只测 API。
## 14. 待决策清单
这些决策会改变实现范围,应在开始 I1 前由两位创始人确认:
1. **首个真实接入对象:** OpenClaw 优先,还是先做 Generic SDK + 模拟 Agent?建议先后者,避免因特定框架阻塞核心验证。
2. **首批部署模式:** 托管中转服务,还是可自托管?建议先托管开发环境,协议与部署保持可自托管。
3. **账号范围:** 仅个人 Workspace,还是首版就允许邀请第二位成员?建议数据模型支持成员,界面先围绕个人。
4. **通知通道:** 浏览器推送、邮件、Telegram/飞书任选一条。建议浏览器通知优先,集成型 Channel 放在 I3 后评估。
5. **产品命名:** “LineUp Agents”暂作工作名;上线前需检查域名、商标及中文名称可用性。
## 15. Definition of DoneMVP 演示
一次合格的演示应从零完成以下闭环:
1. 用户注册并创建一个 Workspace。
2. 用户通过一次性配对码连接运行在另一台机器上的模拟或真实 Agent。
3. 用户创建一个任务,关闭浏览器后再打开,任务与会话仍完整存在。
4. Agent 上报至少两个进度变化,并创建一个子任务。
5. Agent 发起一个 `approval` 请求,用户在收件箱处理后,Agent 收到响应并继续执行。
6. 断开 Adapter,界面在合理时间内显示失联;重连后不重复执行或丢失审批响应。
7. Agent 产出一条结果消息和一个 Artifact,任务成为 `succeeded`,全部过程在事件时间线中可追溯。
完成这套闭环后,再根据试用反馈决定是优先扩充移动端、增加框架 Adapter,还是深化任务协作能力。