# 候选分析诊断与分块恢复(F077) ## 当前行为 F094:统一正文综合及分批证据笔记遇到`summary_invalid_sources`时,只对失败批次重生成一次,附本批允许的来源编号并保留完整原输入。修正仍受原输入预算及32次总调用限制;预算不足不重试,网络错误不因此重试,不通过删除错误编号或猜测来源接受草稿。诊断新增`summary.diagnostics.source_repair_attempts`。修正仍失败时保留fallback及参考资料,但不输出`next_actions`或`follow_up_questions`,避免尚未给出有效答复就追问申报资格。正常成功答复的建议保持。需重启后端,新请求生效;不回填历史。 F093:API/CLI默认在本阶段前执行[四级rerank](rerank.md),弱/不相关候选可被过滤。下面的完整分块与失败规则适用于rerank保留的资料;初筛等级不替代原文核验,缺摘要、受保护或初筛失败的候选仍进入本阶段。 F092(2026-09-21):完整候选内的独立证据块共享当前请求的分析池,默认仍为4路模型调用;候选线程仅调度与合并,不能各自再开4路模型调用。逐块反馈与重试局部隔离,按原文顺序收集结果,全部通过后才合并完整知识。取消后该来源排队块不再发起模型调用,在途调用可能继续结束。分块大小、候选上限、原文覆盖和失败拒绝规则不变;池不跨请求共享。真实同组12份37块对照均39次调用/峰值4路,分析34.79秒至28.93秒;仅单组分析阶段对照,不代表生产端到端保证。 F087:citations除标准{evidence_id:编号}对象外,兼容数组内直接填写有效编号字符串,也允许两种格式混合。正文及卡片引用都按当前块、当前来源精确查找后回填原文;普通文字、未知编号、跨知识/分块及主体侧编号不能作为政策引用。非对象且非有效编号、空引文或错误数组结构会留下明确位置和类型,并在一次有界重试中反馈修正格式;旧逐字引用仍严格校验,不丢弃错误引用来伪造成功。 真实反馈曾出现检索完整、候选7块中第2块两次invalid_citation,旧诊断遗漏非对象引用,无法还原其具体值;这支持定位引用结构失败,不能证明历史值一定是编号字符串。上述兼容与诊断修复需重启,新请求生效;历史回答不回填,真实模型及完整问题仍需分别验证。 F083:候选分析输入evidence/subject_facts按知识ID、来源侧、路径、offset及原文绑定evidence_id。模型的citations及card字段引用只选择{evidence_id};conditions选择evidence_id/subject_evidence_id(无依据为null);match_basis选择policy_evidence_id/fact_evidence_id。程序从当前请求目录回填path/quote及主体事实。名称字段由程序绑定当前/title:模型可省略card.name或填null;若仍提供编号,先验证所有编号有效,再统一回填标题及一条标题引用,重复标题或有效正文编号不会使完整候选失败。未知、其他知识/分块或来源侧错误的编号仍返回invalid_evidence_id,并定向重试一次;不得利用同时提供的path/quote绕过错误编号。旧格式名称仍执行原严格校验。 解释正文、匹配理由、条件说明及其他卡片text保持自然语言,不被替换成原文;关键前提、否定和例外仍须保留。编号绑定仅证明所引片段真实存在,不自动证明解释语义或用户资格。旧path/quote输出继续通过原有严格校验,不能用模糊匹配修复;前端仍收到原引用字段,编号只用于模型输入。综合正文与扶持亮点阶段保持原协议,本轮不改其生成链路。 实际引用粒度为当前证据单元,程序回填整段原文,可能比此前模型短引文更长;不截取、拼接或改写引用。知识完整性哈希、12条完整知识检索上限和全文分析不变。合成真实模型检查入口:`python -m src.step3_question_answer.evidence_binding_check`,只发送合成资料并保存断言与计数。 检索上限MAX_CANDIDATES=12按完整知识record_id计数,不是知识块数量:先选择候选ID,再读取每条全部存储段、重组并校验哈希,随后才做模型分析分块。存储段与模型分析块是不同层次;F082保留检索的12条完整知识上限,只取消单条知识默认12个分析块限制。 逐条分析仍只使用原文证据,每块最多两次尝试;格式或证据校验失败可定向重试一次,网络错误不重复重试同块。F082取消默认最多12块的整条拒绝规则,按实际分块数遍历全文;4000字节组块与长字段1000字切分、单次输入/输出预算和候选并发不变。显式传入max_chunks的受限任务仍遵守上限,拒绝时诊断保留实际chunk_count。长资料需要更多模型调用及处理时间,不截断原文或把未完成候选包装为完成。 多块资料先提取局部字段:本批未提及的可选卡片字段为null,不能写成全文未明确;名称优先采用完整标题,名称文本必须与一条合法引文逐字一致。只有名称/部门/对象的片段可以暂存。全部块校验成功后程序合并同名卡片字段,无额外卡片生成模型请求;最终仍无支持标准及条件的片段不成为卡片,不同名称也不合并。单块流程保持原校验要求。 单块失败后继续后续块,仍受块数与重试上限约束;已取消的模型流不继续。成功片段保留,任何一块失败都禁止该候选进入推荐、知识答案综合及申请补问。其他成功候选正常回答;失败提示保持,不能把部分分析包装成完整分析。继续处理后续块可能比旧的提前退出耗时更长。 相关性由模型结合实际需求和主体事实判断,普通开店不自动等同科创创业;只有创业、企业或地域词语重合不足以推荐科创支持。有对应科技活动线索时仍可分析,未知资格保留待确认;政策了解可直接解释。没有新增关键词排除规则或检索库排他路由,整体召回与推荐质量仍需用户实测。 ## 诊断字段 位于最终 `result.data.recommendation`,随Redis检查点保留,不进入普通终端日志。 | 字段 | 含义 | | --- | --- | | candidate_diagnostics[].chunk_count | 计划分析的块数;旧记录或未进入分块阶段可为null | | candidate_diagnostics[].failed_chunks | 失败块的chunk_index与code;analysis_errors保留第一条错误码以兼容旧接口 | | candidate_diagnostics[].validation_attempts[].card_fields | 本次模型返回的五个卡片字段快照,包括名称文本及引文;属于未验证诊断数据 | | candidate_diagnostics[].validation_attempts[].field_errors | 精确location、rule及repair;缺引用含text,名称不一致含text及quotes | | candidate_diagnostics[].validation_attempts[].feedback | 下一次尝试实际收到的修正提示;原引用路径/引文匹配反馈仍保留 | | candidate_diagnostics[].analyses[].chunk_index | 成功分析来自哪个块 | | candidate_diagnostics[].analyses[].card_evidence | 多块资料各块验证通过的卡片字段片段;最终合并卡片仅放在第一条相关分析的card,其余card为null | | partial_answers | 不完整候选的已核验citations/conditions及来源ID,status固定partial_evidence_only,analysis_complete=false,附明确notice;不参与最终综合或推荐 | 失败字段、模型文本、知识原文均为数据,不执行其中指令。普通日志继续只记录固定错误码与计数,不能将card_fields或引文直接打入控制台。历史诊断不回填。 ## 验证与生效 合成回归:`python -m unittest discover -s src/step3_question_answer/tests -q`,以及第四步API测试。覆盖缺引用/名称差异定向修复、仍失败拒绝、跨块伪造引用拒绝、前后块失败隔离、部分结果不进入综合、引用与诊断序列化、名称冲突和上下文预算。 可选真实模型检查:`python -m src.step3_question_answer.chunk_card_check`。仅发送合成资料;缺引用及名称差异的首轮错误由检查器注入,后续修正由真实模型完成。检查器单次请求超时最多30秒,并逐组输出结果,不修改生产超时配置。检查普通开店、科创需求与政策了解正反例,结果仅保存断言/计数/错误码至output/checks/chunk-cards.json,不保存模型正文。此检查不是生产检索或全量语义验收。 代码生效需重启后端,新请求使用新逻辑,旧回答不回填;前端原回答协议保持,新增诊断字段可按需读取。不会承诺所有模型错误消失;若再出现不完整提示,可按request_id核对失败块、字段快照和两次尝试。 F082:有可用结果时,查询/候选分析失败合并为summary.notices内一条按实际阶段区分的资料提示,不再向overview追加同义句;附件失败仅保留附件专属说明,不误报候选分析失败。无可用结果时仍由正文说明无法可靠作答,不将服务失败等同没有政策。analysis_errors、candidate_diagnostics及complete状态保持真实;前端应展示summary.notices一次,最终result只用于校准。