blueAgent / Deep Agents 接入调研与实施方案

状态:调研结论与实施草案

日期:2026-08-12

目标项目:lanque-app

1. 结论先行

这套系统可以接入同事的 DeepAgent 实现,但不是在前端新增一个接口地址就能完成。

当前最合适的目标架构是:

  1. Vue 只负责输入、会话展示、审批交互和固定模板渲染。
  2. Tauri/Rust 作为 Agent Host,负责 blueAgent 进程生命周期、登录身份、密钥、MCP 权限、工具审批、事件转发和故障恢复。
  3. blueAgent 负责意图理解、任务规划、Skill 使用、工具选择和回答编排。
  4. Java MCP Gateway 继续作为平台工具权限的服务端安全边界。
  5. AGV 状态、检修作业、业务报表继续使用现有结构化数据加固定 Vue 模板,不让模型生成 HTML。

不建议把 DeepAgent 包装成当前 Agent 的一个 MCP 工具。那会形成“当前模型编排器调用另一个模型编排器”的双层 Agent,工具选择、取消、审批、超时和上下文归属都会变得不可控。

综合判断:

项目判断
blueAgent v2 是否有可用接入协议有,已经提供 stdio JSON-RPC、流式事件、线程、运行、取消、审批和事件补流
lanque-app 是否有承接位置有,IpcClient、AgentEvent、Bridge、Reducer 和固定模板均可复用
能否现在直接全量替换不能,身份、工具代理、结构化卡片和 Windows 打包仍有缺口
推荐首期范围文本任务加只读 MCP,功能开关灰度,固定卡片暂保留旧链或先补结构化协议
推荐生产形态Tauri 托管的自包含 Windows sidecar,不依赖用户安装 Python 或 Conda

2. 调研对象澄清

2.1 D:\work\lanque_new

lanque_new 是设计资料包,不是可运行的 DeepAgent。

其中的 README.md 和 TECHNICAL_SOLUTION.md 已经规划了 Tauri、Python Deep Agents sidecar、Rust 工具执行器、JSON-RPC、MCP Gateway 和 SQLite,但目录中没有:

  • Python 包入口;
  • 依赖锁文件;
  • 可启动服务;
  • sidecar 二进制;
  • 可供 lanque-app 调用的运行时实现。

因此不能把 lanque_new 当作实际接入目标。

2.2 同事的 blueAgent

本次找到的实际实现是内网 Gitea 上的 blueAgent。

v2 分支已经具备运行时代码和协议文档:

  • Python 3.12;
  • uv 管理依赖;
  • uv run blue-agent 启动;
  • stdin 接收一行一个 UTF-8 JSON-RPC 请求;
  • stdout 只输出 JSON-RPC 响应与 runtime.event;
  • stderr 输出日志;
  • 支持 runtime.initialize、runtime.shutdown;
  • 支持 thread.create/get/list;
  • 支持 run.start/get/cancel/events.list;
  • 支持审批查询和 approve/deny;
  • 运行事件带严格递增的 seq,可按 afterSeq 补流;
  • 支持 streamable HTTP、SSE 和 stdio MCP;
  • 自身使用 SQLite 保存 thread、message、run、event、plan 和 approval。

但是截至 2026-08-11,v2 最新提交说明仍写有“还有 bug 没修完”。接入前必须让同事提供稳定 tag 或双方共同固定一个 commit,不能长期跟随浮动分支。

2.3 上游 Deep Agents

blueAgent 基于 LangChain 的 Deep Agents。Deep Agents 是建立在 LangGraph 上的 Agent harness,提供规划、子 Agent、Skill、文件上下文、持久化和人工审批等能力,但它本身不是 MCP 权限网关,也不会自动替当前桌面端解决用户鉴权。

生产使用时应锁定精确版本。Deep Agents 当前仍处于 1.0 之前的版本阶段,minor 更新也可能带来兼容性变化。

官方资料:

3. lanque-app 当前基础与缺口

3.1 已有基础

lanque-app 已经有比较合适的运行时抽象层:

  • src/contracts/ipc.ts 定义 IpcClient 和 AgentEvent;
  • src/stores/bridge.ts 是统一事件入口;
  • src/reducer/CardReducer.ts 把流事件归并为会话卡片;
  • src/stores/chat.ts 管理会话、发送、取消和运行状态;
  • src-tauri/src/sessions.rs 用 SQLite 保存前端会话和消息;
  • src-tauri/src/profile.rs 下载 agent.md、mcp-config.json 和授权 Skill;
  • src-tauri/src/mcp.rs 已实现平台模式 MCP 发现、实时权限交集、调用前复核和高风险审批;
  • AnswerCard.vue 及 answers 目录可以继续渲染结构化固定视图。

这些都不需要因 DeepAgent 接入而推倒重写。

3.2 当前生产链仍在 WebView

当前桌面版实际仍使用 OpenAiIpcClient:

  • src/ipc/index.ts 中 USE_REAL_TAURI 仍为 false;
  • src/ipc/tauri/TauriIpcClient.ts 仍是占位实现;
  • 模型意图分类、工具循环、OpenAI SSE 和最终结构化提交主要运行在 OpenAiIpcClient.ts;
  • 当前主对话的 Chat API Key 会进入渲染进程。

接入 DeepAgent 后,应替换这一层编排,而不是同时保留两个编排器处理同一轮任务。

3.3 当前没有 sidecar 管理能力

Rust 侧目前没有:

  • AgentRuntime 或进程监督器;
  • stdin/stdout JSON-RPC 通道;
  • bundle.externalBin;
  • sidecar 健康检查;
  • 进程崩溃恢复;
  • Windows 进程树回收;
  • DeepAgent 事件适配器。

这是接入工作的主体。

4. 推荐目标架构

┌──────────────────────────────────────────────────────┐
│ Vue / WebView                                        │
│ 输入、会话、进度、审批 UI、固定 Vue 模板             │
└───────────────────────┬──────────────────────────────┘
                        │ Tauri command / agent-event
┌───────────────────────▼──────────────────────────────┐
│ Rust Agent Host                                      │
│                                                      │
│ 进程管理   JSON-RPC   事件补流   身份与密钥           │
│ Profile     MCP Broker  本地策略   审批与审计          │
└───────────────┬───────────────────────┬──────────────┘
                │ stdio JSON-RPC        │ HTTPS
┌───────────────▼────────────────┐      │
│ blueAgent / Deep Agents        │      │
│ 规划、Skill、子 Agent、工具选择 │      │
│ 不持有平台权限真相             │      │
└────────────────────────────────┘      │

                          ┌───────────────────────────┐
                          │ Java MCP Gateway          │
                          │ 登录鉴权、工具授权、审计   │
                          └────────────┬──────────────┘


                                各业务 MCP Server

4.1 Vue 的职责

  • 将用户输入交给 Rust;
  • 订阅统一 AgentEvent;
  • 展示文本流、工具步骤、计划、审批和错误;
  • 渲染现有固定 Vue 模板;
  • 不持有 Java access token;
  • 不直接启动 Python;
  • 不直接把平台 MCP 地址交给 Agent;
  • 不执行工具授权判断。

4.2 Rust Agent Host 的职责

  • 启停 blueAgent sidecar;
  • 保存并校验 runtime protocolVersion;
  • 维护 requestId、turnId、runId、threadId、callId 和 seq;
  • 转换 blueAgent 事件为现有 AgentEvent;
  • 对断线事件执行去重和补流;
  • 从安全存储读取模型密钥;
  • 读取当前登录用户的岗位配置和授权 Skill;
  • 向 blueAgent 暴露可用工具描述;
  • 执行所有 MCP 调用前的权限复核和审批;
  • 在退出登录、切换账号、关闭应用时回收运行时和子进程;
  • 对固定模板数据执行来源绑定和最终物化。

4.3 blueAgent 的职责

  • 理解当前任务;
  • 生成计划;
  • 选择 Skill;
  • 选择应该调用的工具及参数;
  • 根据工具结果组织自然语言回答;
  • 为固定模板选择数据引用;
  • 在需要审批时暂停运行;
  • 不直接决定用户是否有权限;
  • 不直接访问任意本地文件或 shell;
  • 不从 app.config.json 自行发现生产 MCP;
  • 不把模型生成的 HTML 交给客户端。

4.4 Java 后端与 MCP Gateway 的职责

  • 登录身份和稳定 userId、tenantId;
  • 岗位 Agent、MCP 和 Skill 授权配置下发;
  • 服务端实时工具授权;
  • Gateway 路由和下游连接控制;
  • 服务端审计;
  • 不能仅依赖客户端或 Python 进程给出的“已授权”标志。

5. 为什么 MCP 权限必须保留现有链路

平台模式下,lanque-app 当前会:

  1. 登录后下载当前用户的 mcp-config.json;
  2. 发现工具时,将下载的授权快照与 Gateway 实时 tools/list 取交集;
  3. 调用前重新读取授权配置并再次校验;
  4. 对需要确认的工具生成待审批调用;
  5. Rust 使用当前登录 token 和 clientid 请求 Gateway。

如果 blueAgent 直接读取 app.config.json 并连接下游 MCP,会绕过上述链路,也会让“本地调试模式”意外变成生产权限通道。

推荐按优先级选择下面的工具接法。

5.1 首选:双向 Host Tool RPC

扩展 blueAgent v2 协议,使运行时只能请求:

  • host.tools.list;
  • host.tools.call;
  • host.tools.cancel。

Rust 返回当前轮可见的工具描述,并负责实际调用。blueAgent 不获取平台 token,也不知道下游真实 endpoint。

优点:

  • 直接复用 src-tauri/src/mcp.rs 的权限和审批;
  • token 不进入 Python;
  • 调用结果原件天然掌握在 Rust;
  • 更适合后续的固定模板数据引用。

缺点:

  • 需要同事扩展 blueAgent 的双向 JSON-RPC 协议;
  • 需要把当前 Tauri MCP command 内核抽成可复用 Rust service。

5.2 过渡方案:Rust 提供本机 MCP Broker

Rust 在回环地址启动一个只服务当前 sidecar 的 MCP 代理,使用每次启动随机密钥。blueAgent 使用它已有的 MCP 客户端连接这个代理,代理再调用现有 Rust MCP service。

该方案能少改 blueAgent 的 Agent 循环,但 Rust 侧要维护本机 HTTP/MCP 服务,复杂度并不一定低于双向 RPC。

5.3 不推荐:把用户 token 交给 blueAgent 直连 Gateway

技术上可以让 blueAgent 只连接 Java MCP Gateway,但会把登录 token 放入 Python 进程,并形成第二套 Gateway 客户端和权限适配代码。

只有在以下条件全部满足时才应临时使用:

  • 只连接 Gateway,绝不连接下游 endpoint;
  • token 短期有效且可撤销;
  • Gateway 每次调用都做服务端授权;
  • Python 日志、异常和 checkpoint 均不记录 token;
  • 切换用户时强制重启运行时;
  • 生产前仍迁回 Rust Broker。

6. 岗位配置、Skill 与模型配置如何映射

当前资源DeepAgent 中的用途处理规则
profile/agent.mdsystem prompt登录同步后由 Rust 读取;不经 WebView;新轮使用固定 revision
profile/skills/*/SKILL.mdDeep Agents skills只加载本次授权下载成功的目录;不得扫描任意本地 Skill
profile/mcp-config.json工具白名单和 Skill 关联作为本地授权输入之一;实际调用仍以 Gateway 实时校验为准
app.config.json应用与调试连接配置平台模式不直接交给 blueAgent;本地直连只用于显式调试模式
runtime-settings.json 的 Chat 配置DeepAgent 模型Rust 从安全存储取 Key,初始化 OpenAI-compatible Chat 模型
AnswerPayload JSON Schema固定视图输出约束最终仍由客户端既有 Schema 校验和 Vue 模板渲染

对于当前 OpenAI-compatible 模型,blueAgent 应显式初始化 ChatOpenAI,并关闭默认 Responses API 推断:

ChatOpenAI(
    model=model_name,
    base_url=base_url,
    api_key=api_key,
    use_responses_api=False,
)

前提是模型可靠支持 tool calling。不能只用“能聊天”作为兼容性判断。

7. 身份与会话设计

7.1 当前缺少稳定身份

blueAgent 的 run.start 要求稳定的 actorId 和 tenantId。

当前 Rust AuthSession 主要保存显示名、服务器地址、登录方式和登录时间,不能把显示名、用户名或 face-user 当成租户隔离键。

后端登录或用户资料契约需要补充:

  • userId;
  • tenantId;
  • 可选 deptId;
  • 当前岗位或个人 Agent revision;
  • 当前权限 revision。

如 token 中存在这些字段,也应由受信任的 Rust 或后端解析和确认,不应由模型或前端猜测。

7.2 UI 会话与 Agent thread 不应混为一谈

lanque-app 的 SQLite 会话保存的是前端 StreamItem,用于恢复 UI;blueAgent 的 SQLite 保存的是 Agent thread、run、event 和 approval。二者生命周期不同,不能共用同一张 session_messages 表。

建议增加映射:

UI sessionId
  └─ UI 展示与历史持久化

turnId
  └─ 当前用户请求
      ├─ blueAgent threadId
      └─ blueAgent runId

7.3 保持“每次输入都是新任务”

当前系统按此前产品要求,不把旧对话历史重新喂给模型。DeepAgent 默认的 checkpointer 容易恢复同一 thread 的历史,因此首期不能直接做:

一个 UI session = 一个长期 blueAgent thread

首期建议每个 turn 创建独立 thread,UI session 只负责显示历史。审批、取消和事件补流仍在同一个 run/thread 内完成。

以后如果需要跨轮记忆,应作为明确设置项,并按 tenantId、userId、Agent revision 做隔离,不能因框架默认行为悄悄开启。

8. JSON-RPC 与事件适配

8.1 复用 blueAgent v2 现有协议

Rust 侧至少需要接入:

  • runtime.initialize;
  • runtime.shutdown;
  • thread.create;
  • run.start;
  • run.get;
  • run.cancel;
  • run.events.list;
  • run.approvals.list;
  • approval.resolve;
  • runtime.event。

每次请求需要独立 JSON-RPC id。stdout 每一行必须是完整 JSON;所有普通日志只能进入 stderr。

8.2 事件映射

blueAgent 事件lanque-app 事件
run startedturn.start
plan / model phaseagent.step
tool startedagent.tool_call
tool progressagent.tool_progress
tool completedagent.tool_result
message deltamessage.delta
message completedmessage.replace 或消息收尾
structured answer建议新增 answer.payload;兼容期可转成 answer fenced JSON
approval required现有工具审批状态和审批窗口
scope boundaryscope.out_of_range 或 scope.intercept
run completedmessage.done
run cancelled / failedagent.step(error) + 用户可见错误 + message.done

8.3 seq、补流和去重

blueAgent v2 事件具有递增 seq,并支持 run.events.list(afterSeq)。Rust 应为每个 run 保存 lastSeq:

  1. 收到 seq 小于等于 lastSeq 的事件时去重;
  2. 通道中断后先调用 events.list 补齐;
  3. 补流完成后再恢复实时事件;
  4. 只有收到终态事件才结束 turn;
  5. 重复的 tool completed 不得导致卡片或审批重复执行。

现有 AgentEvent 没有统一 seq。首期可以由 Rust adapter 内部消费;后续建议在事件契约中增加可选 runId 和 seq,便于诊断与恢复。

8.4 取消

用户点击取消后必须同时处理:

  • blueAgent run.cancel;
  • 正在进行的模型请求;
  • 正在进行的 MCP 调用;
  • 待审批调用;
  • 子 Agent;
  • UI 的 pending 状态。

“前端停止显示”不等于真正取消。最终应等待 runtime 返回 cancelled,超时后 Rust 再强制终止相应运行或重启 sidecar。

9. 固定模板与结构化数据

9.1 当前直接替换会丢失固定卡片能力

blueAgent v2 当前主要在事件中输出文本、工具状态和裁剪后的结果预览,并不把 MCP 的完整结构化结果作为稳定协议返回。

而 lanque-app 的 AGV 状态、检修作业和业务报表需要完整且可校验的数据:

  • AGV vehicles 和 tasks;
  • 检修 locomotives、plans 和 faults;
  • 来源校验;
  • AnswerPayload Schema;
  • 固定 Vue 组件渲染。

因此不能在未补协议时直接将所有任务切到 blueAgent。

9.2 不建议让模型重新抄整份工具结果

全年检修计划可能包含几十条记录。让模型把 MCP 原始数组重新生成进 AnswerPayload 会带来:

  • 数千 token 的无意义输出;
  • 数分钟等待;
  • 字段抄错;
  • 漏行或重复;
  • 模型补造数据;
  • 大数组接近超时。

推荐使用“证据数据集引用”。

9.3 推荐的证据数据集流程

  1. Rust MCP Broker 执行工具;
  2. Rust 保存本轮完整 structuredContent,并生成不可伪造的 evidenceId;
  3. Rust 向 blueAgent 提供紧凑 manifest,只包含数据类型、记录数、查询参数、主键摘要和 evidenceId;
  4. blueAgent 最终只选择模板、字段与 evidenceId;
  5. Rust 根据白名单映射物化 AnswerPayload;
  6. Rust 或共享校验层执行 Schema、业务域、空数组和来源校验;
  7. 前端继续用现有固定 Vue 模板渲染;
  8. 历史消息保存物化后的 AnswerPayload,不保存仅本轮有效的引用。

建议的概念结构:

{
  "type": "answer.binding",
  "template": "report",
  "bindings": [
    {
      "field": "plans",
      "datasetKind": "rail.maintenance-plans",
      "evidenceId": "ev_01J..."
    },
    {
      "field": "locomotives",
      "datasetKind": "rail.in-depot-locomotives",
      "evidenceId": "ev_01K..."
    }
  ]
}

不能允许模型提交:

  • 任意 JSONPath;
  • 数组下标;
  • 客户端不存在的 evidenceId;
  • 与模板字段不兼容的数据类型;
  • 其他 turn 的 evidenceId;
  • 未授权或失败调用产生的数据;
  • 被截断的工具预览。

9.4 兼容期策略

在结构化协议完成前可选:

  1. DeepAgent 只处理自由文本任务,三类固定模板继续走旧链;
  2. 先只迁移 AGV 或报表中的一个模板做 PoC;
  3. blueAgent 新增 answer.structured 事件,先传完整 AnswerPayload,再迭代成 evidence 引用。

推荐第二种和第三种结合。不要以“临时生成 HTML”作为过渡。

10. 审批设计

blueAgent v2 当前支持 approve 和 deny;lanque-app/Rust 已经有工具审批状态。

最终只能有一个权威审批判定,推荐由 Rust 控制:

  1. blueAgent 选择工具和参数;
  2. Rust 规范化参数并计算调用摘要;
  3. Rust 根据平台风险级别决定是否需要审批;
  4. UI 展示工具、影响范围和参数;
  5. 用户批准后,Rust 校验批准对象仍是同一工具和同一参数;
  6. Rust 再执行 Gateway 调用;
  7. 参数发生变化时原批准作废;
  8. Gateway 仍执行服务端授权。

如果 blueAgent 需要用自己的 pending approval 来暂停图执行,可以让 Rust 将最终 approve/deny 结果回填,但不能让 Python 端的 riskLevel 成为安全边界。

后续如需要“编辑后批准”,需要同事扩展当前只支持 approve/deny 的协议,并定义编辑后重新校验和幂等键。

11. Sidecar 打包与生命周期

11.1 不依赖用户环境

客户端安装包不应要求用户:

  • 安装 Python;
  • 创建 Conda 环境;
  • 安装 uv;
  • 手工 pip install;
  • 在命令行启动 blueAgent。

应由 blueAgent 项目输出自包含 Windows 可执行文件,再作为 Tauri externalBin 打包。可使用 PyInstaller 或同事认可的其他构建方案,但必须固定 Python、blueAgent 和 deepagents 依赖版本。

11.2 Rust 进程管理

建议新增 Rust AgentRuntime,至少负责:

  • 启动和握手;
  • protocolVersion/capabilities 校验;
  • stdin 写队列;
  • stdout 逐行 JSON 解码;
  • stderr 有界日志采集和脱敏;
  • 请求超时;
  • pending request 映射;
  • run/event 路由;
  • 健康检查;
  • 取消;
  • 优雅 shutdown;
  • 异常退出检测;
  • 有限次数自动重启;
  • 应用关闭时回收整个进程树。

Windows 上仅让父进程退出,不保证孙进程全部退出。除 runtime.shutdown 和 kill-on-drop 外,建议使用 Windows Job Object 管理进程树。

11.3 Tauri 权限

即使使用 Tauri shell sidecar,也只应从 Rust 代码启动,不给 WebView 通用 shell 权限。外部二进制需要:

  • 在 tauri.conf.json 配置 externalBin;
  • 按 Tauri target triple 命名构建产物;
  • 安装包校验版本和 hash;
  • 正式发布时对主程序和 sidecar 签名。

12. 密钥与文件安全

12.1 密钥

  • Java access token 留在 Rust;
  • Chat API Key 从系统安全存储读取;
  • 不把 Key 放进命令行参数;
  • 不写 stdout/stderr;
  • 不写 Agent checkpoint;
  • 不出现在模型 prompt;
  • 如果必须交给 Python 模型客户端,只通过一次性初始化通道传递,并在退出、切号时销毁运行时;
  • 长期可考虑由 Rust 提供模型代理,使 Python 完全不持有 Key。

12.2 文件与 shell

Deep Agents 自带文件系统、执行和 sandbox 相关能力,但当前企业客户端不应默认开放:

  • 不给真实项目目录根权限;
  • 不给用户目录读权限;
  • 不给任意 shell;
  • 不让模型自己启动 MCP server;
  • 不用 FilesystemBackend 指向真实磁盘;
  • Skill 只来自本次后端授权下载的快照;
  • 如未来需要文件能力,应通过 Rust 的受控文件工具和独立审批实现。

13. 分阶段实施

阶段 0:冻结契约

目标:先消除双方协议仍在变动的风险。

  • blueAgent 发布稳定 tag 或固定 commit;
  • 固定 protocolVersion;
  • 确认所有 JSON-RPC method、event schema 和错误码;
  • 确认最大单行、最大事件、补流保留范围;
  • 后端补稳定 userId 和 tenantId;
  • 决定“每轮独立 thread”;
  • 与同事确认 Host Tool RPC 方案;
  • 确认结构化答案或 evidence binding 协议;
  • 固定 Python 和 deepagents 精确版本;
  • 给出 Windows 自包含构建产物。

完成标准:双方有一份可执行的版本化协议测试。

阶段 1:文本链路 PoC

目标:打通进程、事件和取消,不开放真实写工具。

  • Rust AgentRuntime 启停 sidecar;
  • 实现 runtime.initialize/shutdown;
  • 实现 thread.create、run.start/get/cancel;
  • 实现 seq 去重和 events.list 补流;
  • 实现 TauriIpcClient;
  • 将文本 delta、step、tool preview、done 映射到现有 UI;
  • 增加 legacy/deepAgent 功能开关;
  • 每轮独立 thread;
  • 固定模板任务暂走 legacy;
  • 禁用 shell、真实文件写入和长期记忆。

完成标准:普通问答可流式显示、可取消,崩溃后不会留下进程。

阶段 2:只读 MCP

目标:验证平台权限和真实工具编排。

  • 把 mcp.rs 的命令逻辑抽成可复用 Rust service;
  • 接 Host Tool RPC 或本机 Broker;
  • 只暴露当前用户授权交集;
  • 接入 agent.md 和授权 Skill;
  • 先开放 AGV 和机车检修只读工具;
  • 保存完整 structured result 作为本轮 evidence;
  • 工具执行和结果继续显示在右侧过程栏;
  • 未授权、已下线、Gateway 失败均返回明确结构化错误。

完成标准:伪造工具名或参数也无法越过 Rust/Gateway。

阶段 3:固定结构化卡片

目标:让 DeepAgent 驱动现有三套固定 Vue 模板。

  • 定义 dataset kind 与模板字段白名单;
  • 定义 evidence manifest;
  • 新增 answer binding 或 answer.structured 事件;
  • Rust 物化 AnswerPayload;
  • 复用现有 AnswerPayload Schema;
  • 校验空数组确实来自成功的 0 条查询;
  • 只保存已物化 payload;
  • 引用来源只包含最终实际采用的工具;
  • 验证全年报表不再由模型重打几十条原始记录。

完成标准:大数据报表快速生成,模型不能补造或改写 MCP 记录。

阶段 4:审批与写工具

目标:开放调度、取消等有副作用工具。

  • 合并 blueAgent 暂停态与 Rust 审批;
  • 按规范化参数绑定批准;
  • 接入 idempotencyKey;
  • 支持拒绝、取消和超时;
  • 如需编辑批准,先升级双方协议;
  • 对写操作禁用自动 fallback 和自动重试;
  • 增加服务端审计关联 ID。

完成标准:每个高风险动作都能证明由谁、何时、批准了哪组参数。

阶段 5:生产加固

  • 进程树回收;
  • sidecar 签名、hash 和版本回滚;
  • 账号切换隔离;
  • profile revision 热更新边界;
  • crash/replay/duplicate event 压测;
  • 超长 MCP 结果与背压;
  • 日志脱敏;
  • 模型与 Gateway 超时分层;
  • 安装包无 Python 环境验证;
  • 灰度与 legacy 回退;
  • 版本不兼容时 fail closed。

14. 预计改动位置

14.1 lanque-app / Rust

建议新增:

src-tauri/src/agent_runtime/
  mod.rs
  process.rs
  rpc.rs
  event_adapter.rs
  tool_broker.rs
  structured_answer.rs

预计修改:

  • src-tauri/Cargo.toml:进程、异步 IO、sidecar 和 Windows Job Object 依赖;
  • src-tauri/tauri.conf.json:externalBin;
  • src-tauri/src/lib.rs:管理 AgentRuntime、启动与退出清理;
  • src-tauri/src/mcp.rs:抽离可复用 MCP service;
  • src-tauri/src/profile.rs:向 runtime 提供 revision、agent.md 和 Skill 快照;
  • src-tauri/src/auth.rs:稳定用户身份和切号生命周期;
  • src-tauri/src/settings.rs:模型密钥只在 Rust/runtime 使用;
  • 可新增 agent commands:send、cancel、status、approval。

14.2 lanque-app / TypeScript

预计修改:

  • src/ipc/tauri/TauriIpcClient.ts:实现真正的 Tauri bridge;
  • src/ipc/index.ts:用配置或 feature flag 选择 runtime;
  • src/contracts/ipc.ts:可选 seq、runId、审批和结构化答案事件;
  • src/stores/bridge.ts:接入 agent-event;
  • src/reducer/CardReducer.ts:处理新增结构化事件和恢复;
  • 设置页:运行时模式、健康状态和诊断;
  • 固定模板组件原则上不需要重写。

当前 IpcClient.on 是同步返回取消函数,而 Tauri listen 是异步注册。实现时必须处理“监听尚未注册,组件已经取消订阅”的竞态,或正式把接口调整为异步订阅。

14.3 blueAgent

建议由同事补充:

  • 稳定 release 与 protocolVersion;
  • Host Tool RPC 或受控工具 provider;
  • profile/Skill revision 初始化与 reload;
  • answer.structured 或 evidence binding;
  • 取消传播到模型、MCP 和子 Agent;
  • 统一错误码;
  • 审批参数绑定;
  • Windows 自包含构建;
  • 完整协议兼容测试;
  • 运行时健康与 capabilities。

14.4 Java 后端

至少需要确认或补充:

  • 登录态可得到稳定 userId、tenantId;
  • Agent/Profile revision;
  • Skill/MCP 配置 revision;
  • Gateway 继续对每次 tools/list 和 tools/call 做实时授权;
  • 如采用短期直连方案,提供作用域明确、可撤销的 delegated token;
  • 服务端审计能关联 clientId、userId、runId、turnId 和 tool call。

15. 验收清单

15.1 功能

  • 普通问答流式显示;
  • 工具步骤、计划和结果实时展示;
  • 用户可取消;
  • 进程重连后通过 seq 补流,不重复消息;
  • AGV、检修作业、报表继续使用固定模板;
  • 全年报表不需要模型重打完整数组;
  • 授权 Skill 能使用,未授权 Skill 不加载;
  • 新 profile 在下一轮生效,进行中的一轮不混用两个 revision。

15.2 权限

  • 未授权工具不出现在运行时工具列表;
  • 运行时伪造工具名会被 Rust 拒绝;
  • 运行时伪造 evidenceId 会被拒绝;
  • Gateway 仍做服务端校验;
  • 高风险工具必须批准;
  • 参数改变后旧批准失效;
  • A 用户退出后,B 用户看不到 A 的工具、Skill、thread、event 或 checkpoint。

15.3 稳定性

  • sidecar 未安装或版本不匹配时,应用仍可启动并清楚提示运行时不可用;
  • sidecar 崩溃不会让 UI 永久卡在运行中;
  • 关闭客户端后没有 blueAgent、Python 或孙进程残留;
  • 大结果不会撑爆单行协议或内存;
  • 取消后不会继续执行写工具;
  • 同一事件重放不会执行第二次工具;
  • 网络断开与 Gateway 错误能区分。

15.4 安全

  • Chat API Key 不出现在 WebView;
  • Java token 不出现在模型 prompt;
  • token/key 不出现在命令行、stdout、stderr、SQLite 或 telemetry;
  • sidecar 没有任意 shell 和宿主文件系统权限;
  • 平台模式不读取 app.config.json 的下游 MCP endpoint;
  • 安装包中的 sidecar 有版本、hash 和签名。

16. 不建议采用的方案

  • 把 DeepAgent 注册成一个 MCP 工具供当前 OpenAiIpcClient 调用;
  • 让 Vue 直接启动或控制 Python;
  • 在用户机器上依赖 Conda 环境;
  • 让 blueAgent 自动扫描所有本地 Skill;
  • 让 blueAgent 在平台模式直连任意 MCP server;
  • 把 app.config.json 当平台授权来源;
  • 将 blueAgent checkpoint 塞进现有 session_messages;
  • 默认使用同一 thread 恢复全部历史;
  • 允许模型生成固定视图 HTML;
  • 让模型重写几十条 MCP 原始记录;
  • 仅通过延长超时掩盖大 payload;
  • 同时弹出 blueAgent 审批和 Rust 审批两个窗口;
  • 对有副作用工具做失败后自动切回 legacy 重试。

17. 接入前需要同事确认的问题

  1. v2 是否会作为正式协议继续维护?稳定 tag 是什么?
  2. protocolVersion 和 capabilities 如何协商?
  3. 当前已知 bug 清单及修复计划是什么?
  4. actorId、tenantId 的语义和隔离责任是什么?
  5. 能否支持由 Host 执行工具,而不是 Python 直接连接 MCP?
  6. 能否返回完整 structuredContent 的引用,而不是裁剪后的文本预览?
  7. 是否接受 answer.structured 或 evidence binding 扩展?
  8. Skill 如何绑定 MCP 工具,是否支持运行时 reload?
  9. 是否完整支持 OpenAI-compatible Chat Completions 和 tool calling?
  10. run.cancel 能否真正取消模型、MCP 和子 Agent?
  11. 事件补流保留多久,最大 seq 和最大消息尺寸是多少?
  12. 进程重启后哪些状态可恢复,哪些会取消?
  13. 审批是否计划支持编辑,还是只支持 approve/deny?
  14. 能否提供不依赖 Python 环境的 Windows 构建产物?
  15. sidecar 的依赖许可证、签名和升级策略是什么?
  16. 是否有协议级集成测试和可供客户端 CI 使用的 mock runtime?

18. 最终建议

建议立项,但按“替换编排层、保留安全边界与渲染层”的方式接入:

  1. 先固定 blueAgent v2 版本和协议;
  2. 先完成 Rust sidecar Host 与纯文本事件链;
  3. 再由 Rust Broker 接只读 MCP;
  4. 通过 evidence 引用接现有固定模板;
  5. 最后开放高风险工具和长期记忆。

短期最重要的两个前置不是 UI,而是:

  • blueAgent 支持由 Host 受控执行工具;
  • blueAgent 与客户端共同定义不需要模型重写原始数据的结构化答案协议。

这两项解决后,现有登录、岗位配置、MCP 权限、会话流、过程栏和三套固定 Vue 模板都能继续利用;如果跳过它们直接把 blueAgent 接到模型和 MCP,虽然很快能跑通演示,但会重新制造权限分叉、数据造假、长报表超时和进程残留问题。