Version: 0.9.30.dev.260419

后端:
1. 工具事件推送从通用 EmitStatus 重构为 EmitToolCallStart / EmitToolCallResult 结构化双事件
- newAgent/node/execute.go:executeToolCall / executePendingTool 两处调用路径分离为 Start + Result 两步推送;blocked 场景显式传入状态码,不再复用通用状态
- 新增工具事件摘要生成链:resolveToolEventResultStatus(结果状态映射)、buildToolEventResultSummary / tryExtractToolResultSummaryCN(JSON→中文结论提炼)、buildToolCallStartSummary /
buildToolArgumentsPreviewCN(参数白名单中文标签)、resolveToolDisplayNameCN(17 个工具中文名映射)、formatToolArgValueByKeyCN / formatToolArgValueCN(参数值格式化)
- newAgent/stream/emitter.go:EmitStatus / EmitToolCallStart / EmitToolCallResult 统一收敛到 emitExtraOnly,不再回写 reasoning_content;EmitToolCallResult 新增 status 参数

前端:
1. 全局侧边栏统一提升到 App.vue
- App.vue 新增 MainSidebar + smartflow-layout 双栏布局,三个页面共享导航;AssistantView / DashboardView / ScheduleView 移除各自内联 sidebar 定义、路由跳转、拖拽逻辑及全部样式
2. Assistant 消息流从纯文本重构为结构化 block 时间线
- AssistantPanel 新增 ToolTraceEvent / StatusTraceEvent / DisplayAssistantBlock 类型;handleStreamExtraEvent 按 extra.kind 分发四类事件;getDisplayAssistantBlocks 按 seq 排序统一渲染 tool/status/reasoning/content 五种 block
- 模板层改为 TransitionGroup 动态渲染;工具卡片左侧彩色状态条 + 可展开详情;状态行显示节点阶段中文文案;兼容旧协议 tool_* 状态码归并
- SSE 协议切换到 extra-only:shouldSuppressReasoningDeltaByExtraKind 抑制 status/tool 事件的 reasoning 累积;会话/首页加载锁定 800ms 最少时间保证骨架屏动画
3. 设计系统从渐变毛玻璃迁移到 Flat Modern 扁平化
- 全局色板统一 #3b82f6 / #f8fafc / #f1f5f9,替代旧蓝紫渐变;confirm 卡片琥珀色顶条、用户气泡蓝底白字、工具卡片状态色条
- 新增 dashboard-item-pop / board-item-pop / message-stagger / fade-switch / task-detail 等入场动画;WeekPlanningBoard 格子弹簧动画按行列错峰;TaskClassSidebar 详情展开 max-height 过渡 + 角标旋转
4. 路由新增 /prototype/tool-trace 原型页(ToolTracePrototypeView)
This commit is contained in:
Losita
2026-04-19 00:21:44 +08:00
parent 6760e50e4b
commit 146b94fd50
15 changed files with 3162 additions and 1639 deletions

View File

@@ -0,0 +1,219 @@
# Agent 流式协议前后端对齐 决策记录
## 1. 基本信息
- 记录编号FDR-009
- 功能名称Agent Chat SSE 协议前后端对齐(去伪思考化)
- 记录日期2026-04-18
- 决策状态:提议(评审后执行)
- 负责人SmartFlow 团队
- 关联需求 / Issue
- 工具调用信息前端可视化(折叠式、通俗文案)
- 降低“深度思考”误导(当前为伪装块)
## 2. 背景与问题
- 业务背景:
- 目前聊天页已经在做流式展示、确认卡片、会话管理;
- 计划将“工具调用过程”以专属样式内联展示。
- 现状问题:
1. 后端阶段状态/工具状态,会通过 `reasoning_content` 回传给前端,形成“看起来像深度思考”的内容;
2. 前端目前只消费 `extra.kind=confirm_request`,其他 `extra` 结构化事件并未真正用于渲染;
3. 用户感知层面会误以为模型正在“深度思考”,但其中大量内容其实是流程状态(非真实思考)。
- 不做此决策的后果:
1. 前端即使先移除“深度思考框”,也会连同状态可见性一起丢失;
2. 前后端协议继续漂移,工具可视化落地会重复返工;
3. 后续“真流式 speak”与“工具事件流”会相互干扰排查困难。
## 3. 决策目标
- 目标 1统一 SSE 协议语义边界:`reasoning_content` 仅承载真实思考文本,不再承载阶段/工具状态文案。
- 目标 2`extra.kind` 作为结构化事件主通道,前端据此渲染工具/状态专属 UI。
- 目标 3明确迁移顺序先后端协议就位再前端切换展示最后清理兼容层。
- 非目标(本次不解决):
- 不在本轮实现“每一次 speak 都改成 chat 节点流式消息头”;
- 不在本轮重构全部历史会话数据存储格式。
## 4. 备选方案
### 方案 A先改前端先隐藏深度思考区
- 描述:前端先把思考区关闭或默认不展示,后端暂不改。
- 优点:
- 见效快UI 即刻变“干净”。
- 缺点:
- 只是遮罩,不是协议治理;
- 状态可见性与思考内容耦合,后续仍要返工。
- 复杂度 / 成本:低(短期)/ 高(长期返工)
### 方案 B先改后端协议再改前端渲染采纳
- 描述:后端先把状态/工具事件改为结构化主通道,前端再切换消费逻辑与样式。
- 优点:
- 语义边界清晰,长期维护成本低;
- 前端可直接做“折叠式工具行”,不再依赖伪思考文本;
- 可通过双写/开关平滑迁移,风险可控。
- 缺点:
- 首轮需要前后端并行协作与联调。
- 复杂度 / 成本:中
### 方案 C前后端同一轮同时硬切
- 描述:单次发布同时切后端协议和前端展示,不保留兼容层。
- 优点:
- 路径最短,代码最“干净”。
- 缺点:
- 回归风险高,灰度与回滚空间小;
- 一旦线上混部或缓存命中旧逻辑,容易出现空白块/重复块。
- 复杂度 / 成本:中(开发)/ 高(上线风险)
## 5. 最终决策
- 采纳方案:方案 B先后端协议再前端渲染最后清理兼容层
- 关键理由:
1. 先解决协议语义,再做视觉层改造,避免 UI 层“治标不治本”;
2. 与“工具调用可视化”目标一致,能直接对接折叠式工具行;
3. 具备可灰度、可回滚的工程路径。
## 6. 影响范围
- 涉及模块:
- 后端:`backend/newAgent/stream``backend/newAgent/node`
- 前端:`frontend/src/components/dashboard/AssistantPanel.vue`
- 数据与存储影响:
- 无数据库结构变更;
- 仅影响实时 SSE 事件解释方式。
- 接口 / 协议影响:
- `POST /api/v1/agent/chat` 的 SSE chunk 语义调整(见第 7/8 节)。
- 监控与日志影响:
- 需新增“事件类型计数”与“前端解析命中率”观测。
## 7. 前后端接口现状AS-IS
### 7.1 SSE 外层协议(当前)
- 后端已定义 OpenAI 兼容壳 + `extra` 扩展,代码位置:
- `backend/newAgent/stream/openai.go`
- `backend/newAgent/stream/emitter.go`
- `extra.kind` 已有枚举:`status``tool_call``tool_result``confirm_request` 等。
### 7.2 当前关键现象
1. 后端 `EmitStatus` 会把阶段文案同时写入:
- `extra.kind=status`
- `choices[0].delta.reasoning_content`(降级文本)
2. 执行节点多数工具过程仍通过 `EmitStatus(code=tool_call/tool_blocked)` 推送;
3. 前端 `processSseBlock` 当前只显式处理:
- `parsed.extra?.kind === 'confirm_request'`
4. 结果大量状态文案作为“reasoning”显示形成伪“深度思考”体验。
### 7.3 当前事件样例(简化)
```json
{
"choices": [
{
"delta": {
"reasoning_content": "阶段execute\n正在调用工具queue_status"
}
}
],
"extra": {
"kind": "status",
"status": {
"code": "tool_call",
"summary": "正在调用工具queue_status"
}
}
}
```
## 8. 目标协议TO-BE
### 8.1 总体原则
1. `reasoning_content`:只承载真实模型思考文本;
2. `extra.kind`:承载流程状态和工具事件(前端主消费通道);
3. 前端渲染:默认不把状态事件塞入“深度思考区”,而是进入工具/状态专属样式。
### 8.2 目标事件约定
| 事件类型 | `extra.kind` | 前端默认表现 | 是否进入 reasoning 区 |
|---|---|---|---|
| 阶段状态 | `status` | 轻量状态行 / 提示条 | 否 |
| 工具调用开始 | `tool_call` | 折叠工具行(默认摘要) | 否 |
| 工具调用结果 | `tool_result` | 更新同一工具行状态与详情 | 否 |
| 待确认 | `confirm_request` | 确认卡片 | 否 |
| 真思考 | `reasoning_text` | 思考区(可折叠) | 是 |
| 正文输出 | `assistant_text` | 正文区 | 否 |
### 8.3 目标工具事件样例(简化)
```json
{
"choices": [],
"extra": {
"kind": "tool_call",
"stage": "execute",
"tool": {
"name": "queue_status",
"status": "start",
"summary": "已调用工具:查看任务队列",
"arguments_preview": "默认参数"
}
}
}
```
```json
{
"choices": [],
"extra": {
"kind": "tool_result",
"stage": "execute",
"tool": {
"name": "queue_status",
"status": "done",
"summary": "待处理 3 项,已完成 1 项"
}
}
}
```
## 9. 实施计划(先后端、再前端)
### 里程碑 1后端协议对齐先做
- 目标:状态/工具事件走结构化主通道,不再依赖伪 reasoning 文本。
- 开工清单(后端):
1. `execute` 工具链路改用 `EmitToolCallStart/EmitToolCallResult`
2. `EmitStatus` 增加策略开关:支持“仅 extra不回写 reasoning_content”模式
3. `tool_blocked` 统一归类到工具事件(或结构化 status避免文本拼接歧义
4. 输出契约补充到 `backend/newAgent/ARCHITECTURE.md`
### 里程碑 2前端事件消费切换
- 目标:前端按 `extra.kind` 渲染,不再把流程状态当“深度思考”。
- 开工清单(前端):
1. `processSseBlock` 增加 `status/tool_call/tool_result` 解析;
2. 新增“折叠式工具行”状态机(默认摘要、展开详情);
3. 深度思考区默认只接收真 `reasoning_text`
4. 确认卡片逻辑保持兼容。
### 里程碑 3兼容层收敛
- 目标:确认稳定后去除伪思考降级写法。
- 开工清单:
1. 关闭后端状态写入 `reasoning_content`
2. 清理前端旧降级路径;
3. 补齐回归用例与文档。
## 10. 风险与应对
- 风险 1前端未及时消费 `extra.kind`,导致状态缺失。
- 应对策略:后端先双写一段窗口期(可配置开关),灰度切换。
- 风险 2工具事件顺序乱序导致 UI 折叠状态错位。
- 应对策略:使用 `block_id + tool.name + stage` 做关联键,按到达顺序幂等更新。
- 风险 3历史会话与新会话混合展示不一致。
- 应对策略:仅对新流式消息生效,历史消息维持只读展示。
## 11. 验证与回滚
- 验证方式:
1. 后端单测:事件序列与 payload 结构校验;
2. 前端联调:`tool_call -> tool_result -> summary` 顺序回放;
3. 手工场景:普通问答 / 工具调用 / confirm / tool_blocked。
- 成功判定标准:
1. 状态类文本不再出现在“深度思考区”;
2. 工具事件能稳定渲染为折叠行;
3. confirm 卡片行为不回归。
- 回滚方案:
- 后端切回“状态写 reasoning_content + 旧前端渲染”兼容模式;
- 前端保留旧路径开关,必要时回退版本。
## 12. 后续计划
- 后续优化项 1把 speak 也统一到更细粒度真流式事件头(下一轮决策)。
- 后续优化项 2工具详情文案模板化通俗中文 + 可本地化)。
- 后续优化项 3工具事件接入埋点点击展开率、阅读停留、错误率
## 13. 复盘结论(上线后补充)
- 实际效果:待补充
- 与预期偏差:待补充
- 后续是否需要二次决策:待补充