1c02503d1d
- 移除冗余的 user_token 参数传递 - 重构 tool.result 事件使用 ToolAgentOutput 模型 - 重构 text.end 事件使用 WorkerAgentOutput 模型 - 简化 store 模块的 tool result 处理逻辑 - 更新 router/service 适配新事件结构 - 清理废弃的测试文件与设计文档 - 新增 AgentRuns 多模态存储设计文档
88 lines
3.3 KiB
Markdown
88 lines
3.3 KiB
Markdown
# Agent Runs Multimodal 与落库重构设计
|
||
|
||
**目标**:让 `POST /agent/runs` 支持真实多模态直传到模型(非文本化),并将 worker/tool 结果按新 metadata 协议结构化落库。
|
||
|
||
**范围**:后端 `runs/resume` 请求校验、runtime 输入转换、事件落库、history 回放一致性。
|
||
|
||
---
|
||
|
||
## 1. 背景与问题
|
||
|
||
- 当前 `binary` 内容在运行链路中被当作普通 JSON 文本拼接进入 prompt,模型拿不到原生图像输入。
|
||
- tool 落库仍依赖旧摘要逻辑 `build_tool_content_summary`,与最新 `ToolAgentOutput` 元数据规范不一致。
|
||
- worker 落库当前只落文本内容,未确保 `WorkerAgentOutput` 结构化对象与 `content=answer` 的一致关系。
|
||
|
||
---
|
||
|
||
## 2. 设计原则
|
||
|
||
- 协议单一信源:严格遵循 `docs/protocols/agent-chat-messages.md`,只接受 `binary` 形态,不兼容旧形态。
|
||
- 最小安全边界:仅允许本项目 Supabase 私有桶签名 URL,拒绝任意外部 URL。
|
||
- 事件驱动持久化:以 event store 作为唯一落库入口,避免双轨逻辑。
|
||
- 数据可回放:history 始终可按 metadata 重新签名并回填 user 附件。
|
||
|
||
---
|
||
|
||
## 3. 目标数据流
|
||
|
||
1. `runs` 入参校验通过后,user message 入库(附件仅存 bucket/path/mime)。
|
||
2. runtime 执行时,将 `binary` 转为模型多模态 `image_url` content block 直传。
|
||
3. orchestrator 产出结构化事件:
|
||
- worker 主响应通过 `TEXT_MESSAGE_*` 事件发送,`TEXT_MESSAGE_END` 携带 `workerAgentOutput`。
|
||
- tool 执行结果通过 `TOOL_CALL_RESULT` 事件发送,携带 `toolAgentOutput`。
|
||
4. event store 统一校验并落库:
|
||
- worker:`content = answer`,metadata 写 `worker_agent_output`。
|
||
- tool:`content = result_summary`,metadata 写 `tool_agent_output`。
|
||
5. history 读取 user metadata 重新签名 URL,返回 `binary` block 给前端。
|
||
|
||
---
|
||
|
||
## 4. 安全与错误策略
|
||
|
||
### 4.1 URL 安全边界
|
||
|
||
- `binary.url` 必须满足:
|
||
- host 为当前 Supabase 项目域名。
|
||
- path 为 `/storage/v1/object/sign/{bucket}/{path}`。
|
||
- `{bucket}` 等于 `config.storage.bucket`。
|
||
- `{path}` 前缀匹配 `agent-inputs/{user_id}/{thread_id}/uploads/`。
|
||
|
||
### 4.2 运行失败
|
||
|
||
- 保持 AG-UI 生命周期完整:`RUN_STARTED` 后只能 `RUN_FINISHED` 或 `RUN_ERROR` 结束。
|
||
- 运行错误时不落半结构化消息,避免脏元数据。
|
||
|
||
---
|
||
|
||
## 5. 落库契约
|
||
|
||
### 5.1 Worker
|
||
|
||
- 入库角色:`assistant`
|
||
- `messages.content = worker_agent_output.answer`
|
||
- `messages.metadata.worker_agent_output = WorkerAgentOutput`(完整、schema 校验后)
|
||
|
||
### 5.2 Tool
|
||
|
||
- 入库角色:`tool`
|
||
- `messages.content = tool_agent_output.result_summary`
|
||
- `messages.metadata.tool_agent_output = ToolAgentOutput`(完整、schema 校验后)
|
||
- 删除旧摘要逻辑:`build_tool_content_summary`
|
||
|
||
---
|
||
|
||
## 6. 兼容性策略
|
||
|
||
- 不兼容旧输入块形态(如 `image_url` 作为 runs 输入)。
|
||
- 历史接口输出协议保持不变,前端无需修改消费协议。
|
||
- 原有 user 附件回放路径保留,只强化入站 URL 校验。
|
||
|
||
---
|
||
|
||
## 7. 验收标准
|
||
|
||
- runs 包含合法 `binary` 时,模型收到多模态消息(非文本化 JSON)。
|
||
- 非本项目签名 URL 返回 `422`。
|
||
- worker/tool 落库满足 `content` 与结构化 metadata 一一对应。
|
||
- history 仍能正确回放 user 附件(临时签名 URL)。
|