生成者:OpenAI Codex 智能体。 审核状态:已经过人工确认。
1. 架构定位
xiaokun可以称为基于工作流的 RAG 智能体:编排器按代码规定的顺序执行任务规划、任务准备、答案生成和引用校验;其中问答、摘要、对比通过检索证据增强生成,闲聊另走无证据生成分支。
2. 六个逻辑阶段
| 顺序 | 阶段 | 实际动作与输出 | 源码依据 |
|---|---|---|---|
| 1 | 请求接入与上下文准备 | 校验请求,恢复或建立会话,获取历史消息和记忆;文章场景读取当前文章 | S5:153、240、251;S8:52 |
| 2 | 意图识别与任务规划 | 处理上下文依赖,构造规划输入;模型输出经解析和清洗形成任务,调用失败或无效 JSON 使用回退任务 | S2:51、72;S9:35 |
| 3 | 任务分发与证据准备 | 优先处理澄清和无效任务,再选择 Handler;需要证据的任务构造查询并整理 EvidenceBundle |
S3:39、127;S4;S6:96 |
| 4 | 答案生成 | 需要生成时组装提示词、历史消息和用户问题,调用模型;特定空输出可重试一次 | S1:73、80、125、131;S7:9 |
| 5 | 引用校验与有限修订 | 对需要校验的答案检查引用编号及覆盖,满足特定条件时修订一次,阻断性失败返回兜底 | S1:155、163、195、208、236;S10:11 |
| 6 | 最终交付与记录 | 尝试保存交互记录,发送最终结果和正文,保存会话,再发送结束事件 | S5:485—553;S8:133;S12:24 |
3. 总体执行时序
下图以接入成功、编排正常返回的请求为主;提前失败的分支另见第 6 节。编号仅用于阅读,不代表日志阶段编号。
图中调用顺序依据:接入、交付和退出统计见 S5;规划见 S2、S9;分发及检索见 S3、S4、S6;生成校验见 S1、S10;会话及后台整理见 S8。
4. 证据准备:不是每次都搜索,也不是有资料就一定生成
| 情况 | 实际行为 | 依据 |
|---|---|---|
| 任务要求澄清 | Registry 直接返回澄清问题,跳过具体 Handler 和答案生成 | S3:47 |
| 当前文章目标 | 使用入口已读取的 CurrentResource 作为证据,不再进行目录搜索 |
S4;S6:134 |
| 主题或实体目标 | 使用目标短语和完整任务目标组织搜索输入,交给目录查询 | S3:78;S4;S6:159 |
| 搜索对象明确指向本站 | 检索器额外读取站点概览,之后仍继续相应搜索 | S6:171 |
| 无证据 | 关闭生成,返回资料不足或检索失败提示 | S3:127 |
| 对比任务证据不足 | 在检索状态不是 error 时,目标数不足 2 或有证据的目标不足 2,关闭生成 | S4:compare_handler.go:25 |
| 闲聊 | 不调用证据检索器,启用生成,关闭引用校验 | S4:chat_handler.go:11 |
检索器按查询列表顺序处理查询,去重后给证据编号 E1、E2 等,并根据证据和失败记录生成 ok、partial、error 或 empty 状态。一次准备可包含多项查询,不能理解为“只搜索一次”。[S6:96]
当前编排器在 prepare 之后进入生成或直接返回,没有根据生成或校验结果再次调用规划器、Handler 的反馈检索循环。已有的多查询、本站概览补充属于检索阶段内部逻辑。[S1:50—205;S6:96、171]
5. 生成、重试和引用校验时序
下图针对需要引用校验的生成任务,假设模型调用没有返回传输类错误。
依据:S1:125—238。修订模型调用若报错,保留原校验结果,再按是否阻断决定兜底;不会无限重试。[S1:180—201]
必须区分两种有限重试:
- 输出上限重试:要求正文为空、结束原因为
length,且上下文仍有效;它重新生成答案,不是引用修订。[S1:131、217] - 引用修订:当前仅
answer_empty和unknown_citation可触发一次;不会重新检索证据。[S1:166、208]
citation_required(缺少引用)和 citation_coverage(覆盖不足)会记录为无效校验,但既不触发上述修订,也不阻断最终答案。不能把当前策略写成“所有引用校验失败都会重写或拒答”。[S1:208、236;S10:55]
校验器检查空答案、证据是否存在、引用编号是否合法和文本块是否带引用,没有比较事实陈述与证据内容是否在语义上相互支持。因此 Grounding.Valid 不能等同于事实正确率;提示词要求只依据证据回答,也不等于程序已经证明答案真实。[S10:11—71;S7:9]
当前请求的推理强度是:对比 medium、摘要 low、其他结果类型 none;这是代码传入网关的配置,不是模型实际推理行为的观测结论。[S1:285]
6. 流式交付、错误与持久化
正文在生成期间发送,需要同时满足 live_progress=true、stream_answer=true,并且模型提供内容增量、分段器产出可发送块。仅开启 stream_answer 不足以建立正文回调。[S5:300、357;S1:106]
分段器保留前瞻内容,按 Markdown 块边界发送;需要引用校验时,检测到未知引用会停止后续块发送。它并不等待每个块通过全部引用覆盖检查,尾部内容留到最终交付。[S11:11—46]
依据:S5:302—325、485—553。前缀分支在代码中先检查是否已有正文;图按三种互斥情况表达。交互保存失败会清空对外的交互 ID,但仍尝试交付答案;最终 SSE 写入失败会提前返回,不能保证客户端一定收到 done。[S5:489、498、520、547]
会话保存成功且清洗后的消息数至少为 4 时,会启动后台记忆整理;后台可以调用模型,更新时检查会话版本和身份,避免覆盖新一轮状态。后台完成与 done 没有固定先后关系,因此不能把它画成“done 后才开始”的串行步骤。[S8:133—195]
任务要求新会话时,生成前先忽略旧历史和记忆;编排成功返回后,HTTP 层才解析新会话并使用其 ID 完成后续记录。[S1:80;S5:455]
输入校验、会话读取、文章读取失败会在编排前返回。编排返回模型错误时,HTTP 层映射错误响应;开启实时进度时走 SSE error,否则走 JSON 错误响应。编排返回后注册的延迟逻辑会在未尝试写入交互记录时补记失败,但不覆盖编排之前的所有失败。[S5:176—270、285、392—453]
7. 最关键的是什么
从实现依赖看,问答、摘要、对比的关键基础是“任务目标正确,证据可用”。 Handler 根据目标构造查询,证据为空会关闭生成,对比还有目标证据数量检查,生成提示词明确以证据作为事实依据。这些都是代码可以直接确认的依赖和门槛。[S3:78、127;S4;S7]
但“证据可用”不等于“证据完整且正确”:当前通用门槛主要检查是否有证据,对比检查目标覆盖数量;最终引用校验也不做事实语义核验。因此仅凭现有代码,不能宣称系统已经自动证明证据足够回答所有问题。[S3:127;S4:compare_handler.go:25;S10]
此前“检索是最关键环节”的表述应理解为基于上述依赖关系的工程判断,不是已通过线上评测证明的瓶颈排名。本文没有证据证明检索在当前数据上比意图识别或生成错误更常见,也没有证据证明它最耗时。
准确的现状记录是:系统已有澄清、空证据停止生成、对比证据不足处理和有限答案修订;编排层尚无根据结果重新规划并补充检索的循环。 是否增加该循环,需要进一步评测,本文不把建议写成现有能力。[S1][S3][S4]
本文只记录当前源码可确认的控制流程及其直接推论,不将提示词约束、模型参数或引用格式检查等同于运行效果保证。
Conversation
评论