Files
qiming/qiming-rcoder/.qoder/repowiki/zh/content/数据模型与类型/聊天数据模型.md
2026-06-01 13:54:52 +08:00

17 KiB
Raw Permalink Blame History

聊天数据模型

**本文引用的文件** - [chat_prompt.rs](file://crates/shared_types/src/model/chat_prompt.rs) - [chat_response.rs](file://crates/shared_types/src/model/chat_response.rs) - [attachment.rs](file://crates/shared_types/src/model/attachment.rs) - [model_provider.rs](file://crates/shared_types/src/model/model_provider.rs) - [http_result.rs](file://crates/shared_types/src/model/http_result.rs) - [app_error.rs](file://crates/shared_types/src/model/app_error.rs) - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs) - [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs) - [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs) - [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs) - [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs) - [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs) - [router.rs](file://crates/agent_runner/src/router.rs) - [http_test.rest](file://http_test.rest)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件聚焦于聊天数据模型,系统性阐述 ChatPrompt 与 ChatResponse 的结构定义、提示词构造规则、上下文管理机制与附件处理方式;同时结合 chat_handler 的实现逻辑完整描述从请求到响应的数据转换流程并给出流式响应SSE的数据分块格式、进度更新机制与终止条件。最后提供 HTTP 请求/响应示例与边界情况、错误处理模式,帮助开发者快速理解并正确使用该系统。

项目结构

围绕聊天数据模型的关键文件分布如下:

  • 共享类型层:定义 ChatPrompt、ChatResponse、附件与模型提供商配置等核心数据结构
  • 业务处理器层chat_handler 负责接收请求、构建 ChatPrompt、调度代理并返回统一响应
  • 实时通知层SSE 通道 agent_session_notification 将会话消息以事件形式推送给客户端
  • 会话缓存层session_cache 提供会话级消息缓冲与推送,支持心跳、取消与清理
  • 代理服务层:根据模型提供商选择具体代理类型并启动 ACP 代理服务
graph TB
subgraph "共享类型层"
A["ChatPrompt<br/>ChatResponse<br/>Attachment<br/>ModelProviderConfig"]
end
subgraph "业务处理器层"
B["chat_handler.handle_chat"]
end
subgraph "代理服务层"
C["agent_service.AcpAgentService"]
end
subgraph "实时通知层"
D["agent_session_notification.SSE"]
E["session_cache.SessionData<br/>SessionWorker"]
end
B --> A
B --> C
C --> E
E --> D

图表来源

章节来源

核心组件

  • ChatPrompt承载一次聊天请求的全部上下文包括项目ID、工作目录、会话ID、提示词、附件、数据源附件、代理类型、服务类型、请求ID与模型提供商配置
  • ChatResponse统一的聊天响应载体包含项目ID、会话ID、可选错误信息与请求ID
  • Attachment多形态附件抽象支持文本、图像、音频、文档统一通过 AttachmentSource 表达数据来源文件路径、Base64、URL
  • ModelProviderConfig模型提供商配置决定代理类型与 API 协议
  • HttpResult统一的 HTTP 响应包装,包含 code、message、data、tid 与 success 字段
  • AppError应用级错误封装统一映射为 HTTP 响应

章节来源

架构总览

下图展示从 HTTP 请求到 SSE 实时推送的整体流程,涵盖提示词构造、代理调度、会话管理与事件分发。

sequenceDiagram
participant Client as "客户端"
participant Handler as "chat_handler.handle_chat"
participant Builder as "ChatPromptBuilder"
participant Agent as "AcpAgentService"
participant Worker as "LocalSetAgentRequest"
participant Cache as "SessionData/SessionWorker"
participant SSE as "agent_session_notification.SSE"
Client->>Handler : POST /chat {prompt, attachments, ...}
Handler->>Handler : 校验参数/生成project_id/request_id
Handler->>Builder : 构建ChatPrompt
Builder-->>Handler : ChatPrompt
Handler->>Worker : 发送LocalSetAgentRequest
Worker->>Agent : 启动代理服务并执行
Agent->>Cache : 推送SessionNotify消息
Cache-->>SSE : 通过mpsc通道分发消息
SSE-->>Client : 事件流prompt_start/prompt_end/agent_message_chunk/heartbeat

图表来源

详细组件分析

ChatPrompt 与 ChatResponse 数据模型

  • ChatPrompt 字段要点
    • project_id项目唯一标识用于隔离工作空间
    • project_path项目工作目录路径
    • session_id会话标识可选若未提供则由代理自动创建并返回
    • prompt用户提示词
    • attachments附件列表支持文本、图像、音频、文档
    • data_source_attachments数据源附件JSON 字符串数组),用于外部数据源信息传递
    • agent_type代理类型由模型提供商配置推导
    • service_type服务类型固定为 RCoder
    • request_id请求追踪ID可选
    • model_provider模型提供商配置决定代理与协议
  • ChatResponse 字段要点
    • project_id项目ID
    • session_id会话ID
    • error可选错误信息
    • request_id可选请求追踪ID

提示词构造规则

  • 若未提供 project_id处理器会自动生成 UUID 并移除连字符,随后创建项目工作目录
  • 若未提供 session_id处理器会清理该项目下的所有旧会话确保全新开始
  • 若未提供 request_id处理器会自动生成 UUID 并移除连字符
  • 代理类型由模型提供商配置推导,服务类型固定为 RCoder

附件处理方式

  • 附件通过统一的 Attachment 抽象表达,支持三种数据源:
    • FilePath相对项目目录的文件路径
    • Base64包含数据与 MIME 类型
    • Url远程链接
  • 附件类型包括 Text、Image、Audio、Document均包含可选的元数据如文件名、尺寸、时长、大小

章节来源

上下文管理机制

  • 项目与会话映射
    • 通过 PROJECT_SESSION_MAP 确保同一 project_id 仅对应一个活跃 session_id
    • 当 session_id 变化时,自动清理旧 session 的数据并更新映射
  • 会话缓存与推送
    • SessionData 维护当前连接与取消令牌,支持即时推送与环形缓冲
    • SessionWorker 负责将消息写入环形缓冲并实时推送到当前连接
    • 心跳消息定期发送,保持连接活性
  • 会话清理策略
    • 处理器在收到请求时,若指定 session_id 则移除该会话;否则清理该项目下所有会话
    • 取消任务时,主动触发 CancellationToken 并关闭发送端,确保连接及时断开

章节来源

流式响应SSE数据分块格式与终止条件

SSE 事件格式

  • 事件名称与消息类型映射
    • prompt_start会话开始
    • prompt_end会话结束包含停止原因与可选错误信息
    • agent_message_chunk代理输出片段
    • user_message_chunk用户输入片段
    • agent_thought_chunk代理思考片段
    • tool_call/tool_call_update工具调用与更新
    • plan/available_commands_update/current_mode_update计划、可用命令与当前模式更新
    • heartbeat心跳事件
  • 数据内容
    • 统一以 UnifiedSessionMessage 形式推送,包含 session_id、message_type、sub_type、data 与时间戳
    • data 内容根据子类型不同而异,例如 agent_message_chunk 的 data.content 包含文本内容与类型

进度更新机制

  • SSE 连接建立后立即发送 heartbeat随后持续推送实时更新
  • 心跳定时器每 30 秒发送一次,用于维持连接活性
  • 当取消令牌被触发或发送端被关闭时SSE 自然断开

终止条件

  • 会话结束事件prompt_end携带停止原因如 EndTurn、MaxTokens、MaxTurnRequests、Refusal、Cancelled
  • 取消任务时,主动关闭连接并清理旧消息
  • 容器连接失败或读取 SSE 流失败时,发送 error 事件并断开连接

章节来源

请求到响应的完整数据转换流程

  • 输入HTTP 请求体包含 prompt、可选 project_id、session_id、attachments、data_source_attachments、model_provider、request_id
  • 处理:
    • 参数校验prompt 非空)
    • 自动生成 project_id 与 request_id如缺失
    • 清理旧会话(按 session_id 或项目维度)
    • 构建 ChatPrompt 并发送到本地任务通道
    • 等待 ChatPromptResponse若包含错误则返回统一错误响应
  • 输出HttpResult包含项目ID、会话ID与可选错误信息
flowchart TD
Start(["进入 handle_chat"]) --> Validate["校验 prompt 非空"]
Validate --> GenIds{"是否提供 project_id/request_id?"}
GenIds --> |否| GenPid["生成 project_id 并创建工作目录"]
GenIds --> |是| UseProvided["使用提供的 project_id/request_id"]
GenPid --> CleanSessions["清理旧会话按 session_id 或项目"]
UseProvided --> CleanSessions
CleanSessions --> BuildPrompt["构建 ChatPrompt"]
BuildPrompt --> SendTask["发送 LocalSetAgentRequest"]
SendTask --> AwaitResp{"收到 ChatPromptResponse?"}
AwaitResp --> |是且有错误| ReturnErr["返回统一错误响应"]
AwaitResp --> |是且无错误| ReturnOk["返回 HttpResult.success(ChatResponse)"]
AwaitResp --> |否| ReturnLocalErr["返回本地发送错误"]

图表来源

章节来源

代理类型与模型提供商配置

  • 代理类型选择
    • 根据模型提供商配置推导代理类型Claude、Codex 等)
    • 通过 AcpAgentService trait 启动对应代理服务
  • 模型提供商配置
    • 包含 id、name、base_url、api_key、requires_openai_auth、default_model、api_protocol
    • api_protocol 默认 OpenAI支持 Anthropic 与 OpenAI

章节来源

依赖关系分析

  • 组件耦合与内聚
    • chat_handler 与 shared_types 的 ChatPrompt/ChatResponse 强耦合,但通过 Builder 模式降低复杂度
    • 代理服务通过 trait 解耦,便于扩展新代理类型
    • SSE 层通过 SessionData/SessionWorker 与处理器解耦,实现高内聚低耦合
  • 外部依赖
    • Axum 路由与响应封装
    • Tokio mpsc 通道用于异步消息传递
    • DashMap 用于全局会话缓存
graph LR
chat_handler["chat_handler.handle_chat"] --> shared_types["shared_types.ChatPrompt/ChatResponse"]
chat_handler --> agent_service["AcpAgentService"]
agent_service --> session_cache["SessionData/SessionWorker"]
session_cache --> agent_session_notification["SSE 事件推送"]

图表来源

章节来源

性能考量

  • 会话消息缓冲
    • 使用环形缓冲ringbuf提升消息吞吐避免阻塞
    • 心跳消息不入环形缓冲,确保实时性
  • 连接管理
    • 通过 CancellationToken 主动关闭旧连接,避免资源泄漏
    • 即时推送失败时自动降级为丢弃,保证系统稳定性
  • 并发控制
    • 项目级并发限制:同一项目仅允许一个活跃代理任务
    • 会话级清理:确保新会话不会混入旧消息

章节来源

故障排查指南

常见错误与处理

  • 参数校验失败
    • prompt 为空:返回统一错误响应
  • 并发请求限制
    • 项目存在活跃代理任务返回“Agent正在执行任务请等待当前任务完成后再发送新请求”
  • 本地发送错误
    • 任务通道发送失败:返回本地发送错误
  • SSE 连接问题
    • 容器连接失败或读取流失败:发送 error 事件并断开连接
    • 未找到对应容器:返回“未找到 session_id 对应的活跃容器”

章节来源

结论

本文系统梳理了聊天数据模型的核心结构与处理流程,明确了提示词构造规则、上下文管理机制与附件处理方式,并深入解析了 SSE 的事件格式、进度更新与终止条件。结合 chat_handler 的实现逻辑,读者可以准确把握从请求到响应的全链路数据转换过程,并据此编写正确的 HTTP 请求与客户端消费逻辑。

附录

HTTP 请求/响应示例

  • 创建聊天会话POST /chat
    • 请求体字段prompt、project_id可选、session_id可选、attachments可选、data_source_attachments可选、model_provider可选、request_id可选
    • 成功响应HttpResult.success(ChatResponse),包含 project_id、session_id、request_id
    • 错误响应HttpResult.error(code, message)
  • 建立 SSE 连接GET /agent/progress/{session_id}
    • 事件类型prompt_start、prompt_end、agent_message_chunk、user_message_chunk、agent_thought_chunk、tool_call、tool_call_update、plan、available_commands_update、current_mode_update、heartbeat
    • 断开条件:取消令牌触发、发送端关闭、容器连接失败
  • 取消会话POST /agent/session/cancel
    • 参数project_id、session_id
    • 行为:主动关闭 SSE 连接并清理旧消息

章节来源