boardx / boardx/workspacex

docs(architecture): LangGraph 全 chat 编排层——研究结论 + CopilotKit(AG-UI) 整合方案

Open
#782 0 comments 0 reactions 0 assignees View on GitHub
backlog
Dominant language
TypeScript
Stars
0
Forks
0
Avg merge
1h 7m
Merged PRs (30d)
969

Description

响应 #778/#781 裁决(撤销 #654 P4 限制,LangGraph+deepagents 扩大为全部 chat 的多步编排层)。这是"研究结论 + 整合方案"里程碑,不是最终实现——具体落地拆成后续 issue/PR。

## 1. 研究结论:deepagents / LangGraph 现状(2026-08,不锁定版本号)

### deepagents(当前最新 0.7.x 系列,`v0.7.0` 于 2026-07-27 发布)
- **中间件(middleware)架构**是 v0.7 的核心变化:`create_deep_agent` 现在是"默认中间件栈 + 可覆盖",不是一份写死的图。已验证过的 `FilesystemMiddleware`(虚拟文件系统,`write_file` 现在是覆盖写不是报错,`read_file` 分页并报告剩余行数)、`SubAgentMiddleware`(通过一个 `task` 工具把工作派发给子代理,子代理自动获得默认中间件栈)。
- **`interrupt_on` 参数**:给敏感工具调用加 LangGraph 原生 interrupt(人工审批后继续)——这是验收标准第 7 项(错误/风险透明度)之外,未来如果要做"高风险操作需要用户确认"这类体验的现成钩子,本次不实现,记录为可选后续。
- 虚拟文件系统对 chat 场景的直接价值:目前有限——本仓 chat 场景的"文件"概念已经有自己的 artifact/asset 体系(`apps/api` 的 files/asset 域),deepagents 的虚拟 FS 更适合"agent 内部工作记忆"(比如子代理之间传递中间产物),不建议现在就对接成用户可见的文件系统,避免和已有 asset 体系打架(同一事实两处声明的老问题)。留作后续如果真的需要"agent 生成中间文件、用户看得到"这类需求时再评估。
- **子代理派发(sub-agent)**是本次整合最有价值的新能力:chat 场景里"一个复杂任务拆成几个子任务分别执行、再汇总"(验收标准第 4 项"真实多步能力"的高阶形态)可以直接用 `SubAgentMiddleware` 的 `task` 工具实现,不需要在 TS 侧重新发明一套任务分解逻辑。

### AG-UI 协议 / `@ag-ui/core`(已是 `apps/web` 的传递依赖,`copilotkit-agui.controller.ts` 已在用)
- 协议原生定义了 **17 个事件类型**,本仓目前只用了其中 6 个(`RUN_STARTED`/`TEXT_MESSAGE_START`/`_CONTENT`/`_END`/`RUN_FINISHED`/`RUN_ERROR`)。
- **关键发现:`TOOL_CALL_START` → `TOOL_CALL_ARGS` → `TOOL_CALL_END` 和 `STEP_STARTED`/`STEP_FINISHED` 是协议原生事件类型**,不需要发明私有事件格式。这意味着验收标准第 2/3 项(可见规划步骤、可见工具调用)可以通过 SSE 原生下发,而不是现在 `#732` 那种"前端另外轮询 `GET /agent-runs/:runId` 的 `steps` 字段"的旁路方案——两条路径都能工作,但原生事件是更贴近"Claude Code 那种质感"的实现(工具调用是这条 SSE 流本身的一部分,不是另一个 HTTP 轮询)。
- `STATE_SNAPSHOT`/`STATE_DELTA`/`MESSAGES_SNAPSHOT` 这几个状态类事件本次不需要——本仓的对话状态权威源仍然是 Postgres 的 `chat_messages`/`agent_runs`,AG-UI 的 state 事件是给"前端直接持有完整 agent state"这类场景用的,不适合本仓"服务端是唯一事实源"的既有纪律,不采用。

## 2. 整合架构:复用已验证积木,补齐缺口

### 已验证、直接复用(不重写)
| 积木 | 状态 | 位置 |
|---|---|---|
| `apps/deep-agent-service`(deepagents 服务骨架,动态 skill 工具) | 已在生产 VM 用真实 `deepagents==0.7.5` 验证过端到端响应 | #739/#743,已合并 |
| `DeepAgentModelProvider`(`ModelCallPort` 实现,轮询协议) | 已实现+测试,等待 VM 服务持久化部署后合并 | #740/#747 |
| `completeWithProgress`/`ModelCallProgressEvent`(进度事件插件层) | 已实现+测试(fake provider) | #742/#756 |
| AG-UI SSE 桥接(`agui-bridge.ts` + `copilotkit-agui.controller.ts`) | 已上线,`TEXT_MESSAGE_*`/`RUN_*` 事件真实可用 | #654 阶段1b-2d |
| CopilotKit 前端渲染(Markdown、消息气泡) | 已上线 | PR #670 起 |
| 工具调用可见性后端(`tool_call` run-step + `expandToolCallChain`) | 已上线 | #730-#734 |
| 线程内转录卡(`chat-transcript-card`) | 已上线,替代已移除的全局 ambient-bar | #752/#762 |

### 需要新增的胶水(本次整合的实际工作量所在)
1. **`copilotkit-agui.controller.ts` 扩展 `TOOL_CALL_START`/`TOOL_CALL_ARGS`/`TOOL_CALL_END` 事件**:`DeepAgentModelProvider.completeWithProgress` 产出的 `ModelCallProgressEvent`(已有,#756)通过 `agui-bridge.ts` 的 `onProgress`-style 回调(新增,镜像现有 `onDelta`)转发成这三个原生事件,而不只是写 `AppendedRunStep`。**两条路径不互斥**:仍然写 run-step(`GET /agent-runs/:runId` 轮询端点保留,非 SSE 客户端/重连场景需要它),SSE 是新增的实时通道,不是替换。
2. **`DeepAgentModelProvider` 从"轮询到终态"升级为"轮询中途也读 state 变化"**:当前实现(#747)只在 run 到终态后读一次最终回复。要支撑原生工具调用可见性,需要在 `running` 状态期间也定期 `GET /threads/:id/state`,diff 出新出现的工具调用消息,通过 `completeWithProgress` 的 `onProgress` 报出——这是 #742 调查结论里已经写好的下一步方案,现在有了 VM 上的真实服务可以验证。
3. **子代理派发的可见性**:如果 `apps/deep-agent-service` 的 graph 用上 `SubAgentMiddleware`,子代理的执行也应该产出 `tool_call`/`STEP_STARTED` 级别的事件(子代理本身可以映射成一个 `STEP_STARTED`(stepName=子代理名)+ 内部若干 `TOOL_CALL_*`),细节留到实现阶段验证真实事件形状后确定。
4. **多轮上下文(验收标准第 6 项)**:`DeepAgentModelProvider` 目前每次 `complete()` 都新建一个 LangGraph thread(同 `DeepResearchModelProvider` 的模式)——这意味着 deepagents 自己的 checkpointer/记忆完全没用上,多轮上下文完全靠 `execute-run.ts` 已有的 `trimHistoryToBudget`/`ModelCallInput.history` 机制(把历史消息塞进每次新 run 的 messages 数组)。这个决定**保留**(不改成"复用同一个 LangGraph thread 跨多轮对话")——原因:本仓的对话历史权威源必须留在 Postgres `chat_messages`(多端一致性、可审计、可导出、RLS 隔离都靠它),把跨轮记忆下放到 LangGraph 自己的 checkpointer 会制造"两个事实源"的新漂移,与本仓"同一事实不得声明在两处"的强纪律直接冲突。

## 3. 分阶段实现计划(各自独立 issue/PR)

1. (已完成,待协调者验证部署)#739/#743 服务骨架、#740/#747 provider 接线、#741/#751 旧路径下线、#742/#756 进度事件插件层。
2. **新 issue**:`DeepAgentModelProvider` 升级为运行中轮询 state(第 2 节第 2 点)+ 单元测试(stub LangGraph server 模拟"运行中已有部分工具调用消息")。
3. **新 issue**:`agui-bridge.ts`/`copilotkit-agui.controller.ts` 扩展 `TOOL_CALL_START/ARGS/END` 原生事件转发(第 2 节第 1 点)。**不碰 `apps/web/components/chat/**`**——前端消费这些新事件类型的渲染工作留给 #728 那条线(CopilotKit 的 `@copilotkit/react-ui` 理论上原生认识这几个协议事件类型,不需要本仓自己写渲染器,但需要 #728 那边确认接线)。
4. devapp 端到端验证:协调者已有 VM 权限,实现完成后由协调者部署+验证。
5. `chat-ux-acceptance-criteria.md` 十项评分:协调者用真实浏览器验收,未达 10/10 持续迭代。

## 4. 待回填的文档(ADR #781 已指出,本 issue 登记,具体 PR 见后续实现分支)
- `.harness/instructions/architecture.md` 第 22/108/111 行、`docs/architecture/context-engine.md` 第 310/311/321/333 行——"LangGraph 仅限深度研究/P4"的措辞需要更新为"LangGraph 是全部 chat 的编排层,深度研究/HITL/多阶段生成是其中的场景之一,不是唯一场景"。**本 issue 不改这些文件**(避免在实现方向尚未逐条验证前就动权威文档),实现阶段的第一个 PR 一并回填。

Closes 无(后续每个实现阶段各自开 issue,`Closes` 各自的 issue 号)。

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reading the cited architecture files, `agui-bridge.ts`, `copilotkit-agui.controller.ts`, and `DeepAgentModelProvider`, then review issues #739–#756 and #781. This milestone is done when the LangGraph integration conclusions and the boundaries of the follow-up implementation issues are recorded; the authoritative documentation files are intentionally not changed here.

Written by the indexing model from the issue text.

Assessment

Tech stack
postgresql, python, typescript
Domain
backend-api-design, documentation
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.