题目重点:题目明确三项功能,设计对话与消息 schema、推理任务生命周期、流式响应、上下文截断、重试幂等、成本和故障恢复。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版本是一对一用户与 AI 的文本对话,支持创建会话、发消息、读取历史和生成一个助手回复;流式 token 与取消作为低延迟扩展。题目只给三大功能,不把 RAG/Agent/语音当必答。
- 用户消息和助手消息都保留身份、conversationId、messageId、turnId、role、内容、时间及状态;服务端对每个对话定义一致的消息顺序,用户可按授权读取自身历史。
- 示例容量取 10 万并发对话、平均每秒 1 次生成开始仅作面试规模推演;真实 GPU/模型预算必须按输入输出 token、上下文长度和排队时间测量。
解题路线
- POST /conversations/{id}/messages 带 clientMessageId,事务中校验所有权、写 user message 和 generation 请求/outbox,并返回稳定 turnId。重复提交同一个键返回同一 turn,不再次计费或生成;新的用户消息在上一轮生成中如何排队/取消,要定义会话状态机。
- 推理工作器按 conversationId 读取历史,构建系统指令+近期轮次+可选摘要,计算 token 预算后调用模型;记录 modelVersion、promptVersion、输入 token 数和输出状态。长历史不能无限塞进窗口,截断/摘要可能改变答案,应允许审计使用了哪些上下文版本。
- 输出可经 SSE/WebSocket 持续推送 token,但用户看到的部分 token 不等于最终持久答案;完成时原子写 assistant message=COMPLETED。失败/取消要记录 FAILED/CANCELLED 和已展示片段,重试时不能把第二次生成误当同一结果;若模型服务支持幂等键可减少重复费用,否则用单任务 lease 与结果对账。
- 持久数据库保存对话元数据和消息索引,长内容可放对象存储;热历史用缓存,推理队列按租户/用户限流,GPU 服务批处理与模型路由。历史读取使用游标分页,删除请求需覆盖持久库、缓存、日志及保留期策略。
- 安全层做身份与会话授权、输入长度限制、恶意内容与输出策略检查;不将别人的对话串进当前 prompt。监控首 token 延迟、总延迟、队列等待、token 成本、失败/取消率、上下文截断及历史读取一致性。
手动走一遍
用户发送‘解释这段代码’,clientMessageId=M1。API 写入 turn T1 与 QUEUED 事件后返回;推理 worker 读取该会话已完成的历史并按 token 预算构造 prompt,开始流式输出。网络断开后用户用 M1 重试发送,返回 T1,不生成第二轮;重新连接可读取 T1 状态及已持久片段。若生成失败,状态为 FAILED,用户明确发起 retry 才创建新的 attempt。
规模与取舍
若单轮输入 L token、输出 O token,模型计算与内存成本依模型结构和上下文长度增长;平台侧每轮至少 O(L+O) 传输与存储。会话历史 H 不能每轮无界重读/重送,需分页与上下文预算。峰值生成并发决定 GPU 内存、批处理和排队容量,不可只按 HTTP QPS 估算。
易错点与追问
容易失分的边界
- 仅设计消息表,未设计生成请求状态、超时/取消/失败及流式部分输出。
- HTTP 超时后同一用户消息生成两个 assistant 回复,既乱序又重复计费。
- 把全部历史无上限拼进模型输入,忽略上下文窗、成本和过时内容。
- 缓存或日志中混入跨用户历史,忽略授权和删除传播。
继续深挖
- 若加入工具调用,如何记录每次工具请求/结果、授权、超时及可重放的推理轨迹?
- 若要 RAG 检索,如何给召回片段版本、来源引用和用户权限加约束?
- 跨区域容灾时,进行中的生成能否恢复,若不能如何让用户明确看到失败而不出现假完成?
