# 聊天数据模型 **本文引用的文件** - [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 代理服务 ```mermaid graph TB subgraph "共享类型层" A["ChatPrompt
ChatResponse
Attachment
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
SessionWorker"] end B --> A B --> C C --> E E --> D ``` 图表来源 - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L176-L320) - [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62) - [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L140) - [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483) 章节来源 - [router.rs](file://crates/agent_runner/src/router.rs#L41-L70) ## 核心组件 - ChatPrompt:承载一次聊天请求的全部上下文,包括项目ID、工作目录、会话ID、提示词、附件、数据源附件、代理类型、服务类型、请求ID与模型提供商配置 - ChatResponse:统一的聊天响应载体,包含项目ID、会话ID、可选错误信息与请求ID - Attachment:多形态附件抽象,支持文本、图像、音频、文档,统一通过 AttachmentSource 表达数据来源(文件路径、Base64、URL) - ModelProviderConfig:模型提供商配置,决定代理类型与 API 协议 - HttpResult:统一的 HTTP 响应包装,包含 code、message、data、tid 与 success 字段 - AppError:应用级错误封装,统一映射为 HTTP 响应 章节来源 - [chat_prompt.rs](file://crates/shared_types/src/model/chat_prompt.rs#L1-L52) - [chat_response.rs](file://crates/shared_types/src/model/chat_response.rs#L1-L18) - [attachment.rs](file://crates/shared_types/src/model/attachment.rs#L1-L216) - [model_provider.rs](file://crates/shared_types/src/model/model_provider.rs#L1-L132) - [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L1-L103) - [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L1-L65) ## 架构总览 下图展示从 HTTP 请求到 SSE 实时推送的整体流程,涵盖提示词构造、代理调度、会话管理与事件分发。 ```mermaid 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 ``` 图表来源 - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L176-L320) - [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62) - [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L140-L222) - [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483) ## 详细组件分析 ### 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,均包含可选的元数据(如文件名、尺寸、时长、大小) 章节来源 - [chat_prompt.rs](file://crates/shared_types/src/model/chat_prompt.rs#L1-L52) - [chat_response.rs](file://crates/shared_types/src/model/chat_response.rs#L1-L18) - [attachment.rs](file://crates/shared_types/src/model/attachment.rs#L1-L216) - [model_provider.rs](file://crates/shared_types/src/model/model_provider.rs#L1-L132) - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L198-L210) - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L225-L258) - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L266-L283) ### 上下文管理机制 - 项目与会话映射 - 通过 PROJECT_SESSION_MAP 确保同一 project_id 仅对应一个活跃 session_id - 当 session_id 变化时,自动清理旧 session 的数据并更新映射 - 会话缓存与推送 - SessionData 维护当前连接与取消令牌,支持即时推送与环形缓冲 - SessionWorker 负责将消息写入环形缓冲并实时推送到当前连接 - 心跳消息定期发送,保持连接活性 - 会话清理策略 - 处理器在收到请求时,若指定 session_id 则移除该会话;否则清理该项目下所有会话 - 取消任务时,主动触发 CancellationToken 并关闭发送端,确保连接及时断开 章节来源 - [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L140) - [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L140-L222) - [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L224-L355) - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L225-L258) ### 流式响应(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 事件并断开连接 章节来源 - [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L36-L57) - [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483) - [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L1-L180) - [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L140-L222) ### 请求到响应的完整数据转换流程 - 输入: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与可选错误信息 ```mermaid 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["返回本地发送错误"] ``` 图表来源 - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L176-L320) - [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L1-L103) 章节来源 - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L176-L320) - [http_result.rs](file://crates/shared_types/src/model/http_result.rs#L1-L103) ### 代理类型与模型提供商配置 - 代理类型选择 - 根据模型提供商配置推导代理类型(Claude、Codex 等) - 通过 AcpAgentService trait 启动对应代理服务 - 模型提供商配置 - 包含 id、name、base_url、api_key、requires_openai_auth、default_model、api_protocol - api_protocol 默认 OpenAI,支持 Anthropic 与 OpenAI 章节来源 - [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62) - [model_provider.rs](file://crates/shared_types/src/model/model_provider.rs#L1-L132) ## 依赖关系分析 - 组件耦合与内聚 - chat_handler 与 shared_types 的 ChatPrompt/ChatResponse 强耦合,但通过 Builder 模式降低复杂度 - 代理服务通过 trait 解耦,便于扩展新代理类型 - SSE 层通过 SessionData/SessionWorker 与处理器解耦,实现高内聚低耦合 - 外部依赖 - Axum 路由与响应封装 - Tokio mpsc 通道用于异步消息传递 - DashMap 用于全局会话缓存 ```mermaid 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 事件推送"] ``` 图表来源 - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L176-L320) - [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62) - [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L140) - [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483) 章节来源 - [router.rs](file://crates/agent_runner/src/router.rs#L41-L70) ## 性能考量 - 会话消息缓冲 - 使用环形缓冲(ringbuf)提升消息吞吐,避免阻塞 - 心跳消息不入环形缓冲,确保实时性 - 连接管理 - 通过 CancellationToken 主动关闭旧连接,避免资源泄漏 - 即时推送失败时自动降级为丢弃,保证系统稳定性 - 并发控制 - 项目级并发限制:同一项目仅允许一个活跃代理任务 - 会话级清理:确保新会话不会混入旧消息 章节来源 - [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L140-L222) - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L211-L224) ## 故障排查指南 常见错误与处理 - 参数校验失败 - prompt 为空:返回统一错误响应 - 并发请求限制 - 项目存在活跃代理任务:返回“Agent正在执行任务,请等待当前任务完成后再发送新请求” - 本地发送错误 - 任务通道发送失败:返回本地发送错误 - SSE 连接问题 - 容器连接失败或读取流失败:发送 error 事件并断开连接 - 未找到对应容器:返回“未找到 session_id 对应的活跃容器” 章节来源 - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L137-L168) - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L211-L224) - [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L135-L153) - [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L231-L244) ## 结论 本文系统梳理了聊天数据模型的核心结构与处理流程,明确了提示词构造规则、上下文管理机制与附件处理方式,并深入解析了 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 连接并清理旧消息 章节来源 - [http_test.rest](file://http_test.rest#L1-L109) - [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L102-L173) - [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)