step3-agent.md 53 KB

第三步:青浦区营商助手企业画像、政策检索与推荐(F017/F018)

F114(2026-09-23):knowledge_images从与原文分析相同的事实字段提取image-scope图片,不读取生成摘要或模型建议字段;完整且相关的知识/卡片分析条目携带图片说明与出处。综合时模型只输出图片位置标记,程序按最终source_ids绑定URL并追加逐字图片引用。普通短答带图片时进入综合,超长整理保留图片标记,政策综合支持相同处理;同题QA原样保留。未选图片不追加文末,未采用来源或伪造标记不转换成图片。图片规则仅在存在图片时加入提示,不改变无图问题的预算。SSE临时delta隐藏内部标记,最终正文用image-scope就地交给前端渲染,详见接口说明。已核对目标DMS问答、真实Milvus单条回读及真实模型图片输出;未完成实时检索重放/生产前端验收。

F113(2026-09-23):办事指南的情形名称、事项及地区随rerank、每个分析证据块及最终综合传递,避免同名指南的延续/变更/注销条件混用。服务链接文字和detail_links.title优先采用原文具体情形,指南与网上办理入口分别标明;无标题短答可通过明确标记保留对应链接。只问某项细节时直接回答该项,完整办理介绍才展开三栏。已完成三份历史来源的两组真实模型固定候选回放,未重放实时Milvus检索或部署前端;模型仍可能误判,需重启后评审新请求。详见答复规范。

F099(2026-09-22):API/CLI全文分析及卡片短文案并发由KNOWLEDGE_ANALYSIS_CONCURRENCY控制,默认及当前本地值8。完整原文跨库回读改为有界并发,由RETRIEVAL_CONTENT_CONCURRENCY控制,默认及本地值8,当前六库实际最多6路;同库分段依赖、完整性校验与候选顺序保持。系统环境优先,修改后重启;见并发配置与风险。下文workers默认4的历史描述不再代表生产入口。

F098(2026-09-22):检索完成后,在rerank和全文分析之前检查已召回QA。沿用原同题规则(NFKC、空白及末尾问号等排版归一,不做语义近似),答案非空且未被现有明确执行期限规则判过期时,直接使用全部可用同题QA的原答案及来源。跳过rerank、其他候选分析、卡片短文案和综合模型调用;不创建候选/证据块分析线程池。多份同题答案不一致时沿用qa_conflict,保留各自答案和来源,不擅选一个。带附件仍走原联合处理,含失败附件也不得静默跳过;检索部分失败仍保留不完整状态和提示。

返回结构保持,retrieval新增fast_path={kind:exact_qa,matched_count,skipped_candidate_count}。sources和candidate_diagnostics仅包含实际处理的同题QA;跳过的候选不标成不相关或分析成功。不新增SSE事件,summary/result直接携带原答案,source返回完整原文,无政策item或模型正文delta。耗时日志会出现exact_qa区间,命中路径不再出现rerank/analysis/highlights/synthesis的模型调用。

该优化发生在现有召回和完整资料回读之后,不跳过意图识别、具体需求规划、按需企业查询或六库检索,也不新增全库精确QA查询。未召回的QA不能触发此路径,未知有效期不被视为已验证有效。需重启后新请求生效,真实线上节省时间待采集。

F094(2026-09-21):需求识别在检索前处理普通业务词的同音误选、错字。可选term_interpretation={original,interpreted,confidence},无纠错为null。high仅作可纠正的暂定理解,原问题保留,补充查询通过context_query传给检索,conversation_context中的解释同步规划、候选判断及综合;summary.notices提示暂定理解。uncertain直接返回简短确认,保持policy_overview分类,不启动公司查询/检索/推荐。不得按召回内容反推词义,不能把企业宽泛扶持自动缩成科创人才需求。公司名、代码、金额、日期和否定不应纠正,原词必须在本轮唯一出现,数字或公司线索内的改写拒绝;非法结构回原问题查询。新轮重建解释,不跨话题复用。需重启后端,新请求生效。

F069(2026-09-20):API/CLI公司检索新增DMS优先步骤。先匹配基础信息,精确确认或候选选择并读取基础成功后才按信用代码查询荣誉;最多3候选并提供“搜索更多公司”进入企查查。无候选自动补充查询,错误保留诊断。返回企查查兼容业务结构和DMS实际来源,详见公司检索。以下纯企查查流程为历史基线。

F067(2026-09-20):详情链接改为普通Markdown格式 查看产品详情,不再用尖括号包裹URL。地址中的括号等字符由程序编码,summary.detail_links.url与正文目标地址一致。某些前端会把尖括号目标识别成相对路径并拼上本站域名,本次从后端输出消除此兼容问题;原数据地址、来源绑定与SSE字段不变。需重启后端重新提问,已保存旧回答不会自动修复。

F066(2026-09-20):办事指南/办理事项介绍默认固定为一句话前置摘要(无标题),随后依次“### 办理渠道”“### 申请材料”“### 办理流程”。渠道说明原文支持的入口/窗口及限制,材料用列表并保留份数、原件/复印件和条件性要求,流程按原文步骤编号。缺失栏目保留并明确资料未说明,不补造渠道、材料、时限或通用审批步骤;跨事项/地区分别标明。其他相关知识可在三栏之后补充。用户明确只问某项细节时可聚焦该项,同题QA保留原文展示契约。

service_guide短答案也经过综合生成,详细排版规则集中在最终答复提示,分析阶段仅保留简短顺序要求;分层笔记保留渠道/材料/流程对应关系。summary.text与来源字段契约不变,前端按Markdown渲染,无新增接口。合成检查通过不保证所有真实模型输出始终遵循结构;需重启后端后新请求生效,历史不回填。

F065(2026-09-20):金融产品正文按“产品名称(机构)+默认2至3个关键要点”介绍,优先金额覆盖、额度/期限、融资成本与关键条件;保留“最高/起/年化”、担保及资格门槛,不逐字段铺陈。明确追问详情可展开,无字数硬截断。金融库短答案也走综合生成;同题QA仍保留原文路径,政策与其他知识联合正文保持。

每个采用且有有效地址的金融产品,在介绍旁显示Markdown“查看产品详情”链接。地址优先使用完整记录data.detail_url,缺失/非法时尝试source.url,仅接受无凭据HTTP(S)地址,不推测详情接口。模型只返回产品标记,程序绑定实际引用的source_id并插入真实存储地址;漏标记优先补到对应标题段末,无法定位则在正文附产品名和直达链接。缺地址时不制造链接,完整参考资料仍保留。

summary新增可选detail_links数组,每项source_id/title/url;knowledge_answers补充knowledge_type/detail_url。summary.text已含Markdown链接,前端正常渲染并允许这些已绑定URL即可点击,不应再追加一份知识正文或详情链接列表。source仍返回完整原文。CLI HTML同步仅启用绑定的产品链接,其余正文链接不激活;未新增产品卡片或改动SSE事件。外部前端需联调其Markdown链接支持;后端重启后新请求生效,历史不回填。

F063:政策小卡片条件精简(2026-09-18)

入选卡片conditions改为最多三项,优先申报条件引文和关键待核验门槛,去重、去除无原文占位。仅返回dimension/status/quote/user_evidence,展示信息方向及状态、原文要求、已知信息。完整内部分析先用于排除与补问,再做卡片投影;诊断保留完整条件。下文历史‘全部条件随卡片返回’被替代。接口与前端迁移见api-chat.md;需重启,新请求生效。

F056:3/12候选、首六卡分散及一致总结(2026-09-17)

检索采用每条查询每库3条、合并最多12候选;仅回读入选原文全部分段并逐条核验。政策先按惠企来源、问题关联层级及主体依据排序,再选各支持类别中优先项组成初始六卡,不足六类以原排序补足;同类其余项后移,全部items仍返回。类别由LLM按原文主要支持目的输出policy_category,固定枚举见接口字段说明,缺失为其他;不以标题或来源库替代类别判断。不同类别之间,优先类别代表仍遵循基础排序;为分散首屏,其他来源的不同类别可能排在惠企来源的重复类别前。

F064更新(2026-09-20):最终items[:6]仍限定正文的政策范围、地区前提、follow_up_questions及追加的next_actions;相关knowledge_answers与首六政策通过有界综合生成共同参与正文。政策及其他知识各自携带核验引文与适用限制,summary.source_ids/citations关联采用来源,sources保留完整参考资料;无卡片/同题QA沿用原知识回答。联合生成失败明确提示整理失败,保留全部来源,不拼接未完成正文。presentation.summary_policy_limit=6。展开更多不会触发重新总结。真实六库3/12候选检索及三条纯合成真实模型分类验证通过;真实用户分析的质量、分类稳定性、总耗时和前端展示仍待重启新请求验收。

F054:待确认相关政策(2026-09-17)

F054按用户反馈保留有原文依据且相关的待确认政策,移除缺少需求/行业/资质supports即排除的门槛;unknown依据补入有原文的具体确认问题,地区仍第一,其后优先待确认政策问题。follow_up_questions保留5项、next_actions保留3项上限,全部条件仍随卡片返回。同上位办法不同完整事项标题分别保留,完整标题重复仍去重。无关、明确不满足、过期、引用失败及政策卡片来源限制保持。recommendation_status继续由LLM生成最高扶持短文案,资格说明在eligibility_status/conditions,新增match_status=pending_confirmation。

历史insufficient_personal_match记录继续兼容,新筛选不再生成此排除原因。match_status表示匹配依据仍需确认,不等于资格通过。来源白名单未调整,办事指南等仍可提供正文依据。

F052 政策卡片扶持短文案(2026-09-17最新:LLM总结)

入选item.recommendation_status由LLM根据card.support_methods_standards的原文引文概括,目标约10字。 每张入选卡片调用一次当前JsonModel,复用Recommender.workers并发上限;不使用正则提取或金额比较, 不累计不同事项,年/人等单位与金额语义由LLM依据原文总结。无原文标准时不调用模型,显示奖励上限未明确。 程序只验证返回text非空、citations存在且path/quote与输入原文对应;不截断正文或计算金额。 引用校验不能证明金额语义完全正确,仍需真实样例评测。两类合成真实模型样例已验证,不代表全部政策稳定性。

support_highlight={text,citations,status,error?},status为generated/fallback/unavailable。 调用或结构/引用失败时保留卡片并提示扶持标准见详情;记录support_highlight_errors, result_ready.support_highlight_error_codes及会话degraded均能反映失败,不把原文或异常正文写日志。 原资格说明仍在eligibility_status,eligibility/conditions保持。旧规则法及“不新增模型调用”说明已作废。 新请求重启生效,历史结果不回填。每张卡片增加一次模型调用,延迟和调用量增加;不自动重试此短总结。

F051 引用来源与定向重试(2026-09-17)

分析提示明确citations/card引用及match_basis.policy_path/policy_quote只用本批evidence, match_basis.fact_path/fact_quote使用subject_facts,不得把企业地址或荣誉路径填入政策引用。 结构及逐字校验保持,最多两次尝试,不自动移动、忽略或放行错误引用。

引用校验失败时,第二次模型输入的validation_feedback包含issues与本批policy_paths/subject_paths。 issues按location和expected_source指出wrong_source、path_not_found或quote_not_found; 反馈作为数据传递,模型返回内容不插入系统指令。可选空条件引文不产生引用修正问题。 格式或服务失败没有可解析引用时仍按原错误码处理,不编造字段诊断。

validation_attempts.references新增source_side;主体引用保留原fact_path/fact_quote(记录为path/quote) 及主体侧字面检查结果,失败尝试新增subject_evidence和feedback,补齐此前主体匹配定位缺口。 详细数据仅在会话检查点/最终result中,终端仍只输出安全错误计数;旧请求不回填。 提示精简重复格式说明,保留字段顺序、顶层match_basis和card末尾闭合约束;未改变预算或分块。 真实用户新请求待重启后验证,不以合成重试成功宣称模型不会再引用错放。

F050 青浦发展场景与地区优先(2026-09-17)

企业咨询不默认只判断现有主体现在能否申报。对于以现有企业地址/行政区事实为依据的地区判断, 在未确认青浦落地方式时转为“待确认”,相关地区match_basis冲突转unknown,保留原条件引文和企业事实。 已明确青浦区地址的主体、个人场景不套此转换;其他明确不满足或过期继续排除。 需有需求、行业或资质关联才可入选,政策卡片来源白名单不变。

入选项标记regional_context=qingpu_development,recommendation_status说明 “在青浦发展后的支持线索,适用条件待核验”;卡片答案和综合说明突出适用前提。 分公司、新设主体或迁址是否适用须按原文独立法人、注册、纳税及其他要求核验,不承诺落地即获支持。 优先问拟在青浦的地点/园区、落地方式或是否先了解政策,不把已知当前注册地址重复当未知信息。 follow_up_questions在去重及前5项截取前按地区优先;next_actions在前3项截取前按地区优先, summary.text沿用现有下一步展示通道,前端无需增加事件。模型已提出含计划/拟/落地的地区补问时保留原问法。 具体语义与用户已明确计划的去重效果仍需真实请求复验;外地地址不证明所有地区条件都可通过迁址改变。

F049 候选排除诊断(2026-09-17)

新请求的 recommendation.candidate_diagnostics 按召回顺序保存每个候选的 source_id/title/knowledge_type/snapshot/policy_card_allowed/analysis_complete/error、 最终 outcome、used_in_knowledge_answer 和 analyses。 analyses 是通过结构与引用校验、尚未合并筛选的逐块结论,含相关性、条件、 user_evidence、原文引文和 match_basis;不是模型隐藏推理或原始响应。 分析失败时清空该候选的已接受analyses,未通过校验的内容仅进入下述诊断,不作为回答依据。

candidate_diagnostics[].validation_attempts 按块/尝试保存 chunk_index、attempt (均从1开始)、status(accepted/rejected/model_error)、error 和 references。 引用诊断含模型字段位置location、原始path/quote、path_required、path_exists、quote_matches; 覆盖正文引文、条件引文、卡片引文和match_basis的政策引文。 rejected记录还保存本次模型收到的原文 evidence(path/offset/text),不截断, 便于核对路径错误、逐字差异或跨块引用。条件引文原协议不要求path,按path_required=false解释。 这些布尔值仅表示字面检查,不代表资格或语义正确;没有引文的可选条件也可能quote_matches=false。 重试成功仍保留首轮拒绝及第二轮引用;两次失败均保留。不保存模型隐藏推理、整段响应或传输异常正文, 无法解析JSON或模型服务失败时只有model_error与安全码,没有可解析引文。旧记录不回填。

excluded_items 原有 source_id/reason 保持,卡片筛选排除项新增 title/knowledge_type/eligibility/conditions/match_basis/match_reason/citations,保留合并后的判断。 同题QA优先排除项仍使用原字段,其逐块依据可从 candidate_diagnostics 查找。 outcome 包括 selected、ineligible、expired、reference_only、subject_conflict、 insufficient_personal_match、duplicate_name、exact_qa_answer、not_relevant、analysis_failed。 标签表示程序本次处理结果,不证明真实资格判断正确;待用户重启新请求后逐项审阅。

详细诊断随图检查点保存到当前会话Redis,并出现在SSE最终 result.data.recommendation; 不追加到回答正文或卡片列表,不增加模型调用,不改变筛选规则,旧记录不回填。 诊断含当前用户事实,只按现有会话结果权限处理,禁止复制到开发文档或公共日志。

F046(2026-09-16):cards.policy_card_allowed按完整source.file白名单及raw_record.is_policy is True判断卡片资格。允许reference下的人才政策和服务.json、涉外政策.json、惠企政策.json、上海虹桥国际中央商务区管理委员会政策和申报指南.json;不依赖候选分库、模型推测、名称或顶层派生标记。分析提示限定policy卡片,代码在分析校验前屏蔽非政策卡片,并在汇总时再次检查来源及卡片kind,防止模型越权。非政策有据answer进入knowledge_answers,不因无卡片丢弃;六库检索、原文来源与过期/资格规则保持。该规则替代下文历史金融/服务卡片范围。

F045追加修正(2026-09-16 16:24):最新复发仍为model_invalid_content_json。现在仅对已知分析对象在EOF缺一个外层右花括号、且顶层/卡片字段集合完全符合预期的情况修复;若match_basis唯一错嵌card则移回顶层。所有文本原值不变,其他JSON损坏不修复,后续仍执行原引用/条件/卡片校验。16384输出、4000字节分块与最多一次格式重试保持。此规则替代此前完全不补括号的说明,不是宽松通用JSON修复。

F045修正(2026-09-16 16:18):输出上限保持16384。候选原文分块预算从15000字节降至4000字节,超长字段按1000字符无损切分,保留path/offset;最多12块的停止边界保持。明确顶层字段顺序,match_basis先于最后的card,避免嵌套错位和外层括号未闭合。无效JSON/非对象最多重试一次,与引用/结构修正共享两次总尝试;继续严格JSON解析和逐字引文校验,不自动补括号或改写原文。用户已授权原两条失败候选发送当前模型复验,审批阻塞已解除。

2026-09-16 16:11 更新(F044/F045):最新输出预算改为16384,作用于JsonModel共用的查询规划、候选分析和综合总结,上下文预留随常量同步;意图分类仍为2048。111项第三步、35项API及离线基线通过。无效JSON/非对象增加最多一次格式重试,与原引用校验共享两次总尝试,仍失败保留具体错误。未重启服务。F045真实候选复验因自动审批拒绝将Redis资料重发外部模型而待用户授权,尚不能宣称实际排水证问题修复。

F044(2026-09-16 16:06):F044:JsonModel输出上限4096→8192,作用于查询规划、候选分析和综合总结;上下文预留同步提高,不修改模型上下文配置或意图分类2048预算。候选分析错误及API日志区分HTTP状态、超时、网络、响应JSON/结构、内容JSON/结构、输出token截断和内容过滤;异常正文不输出。29项第一步、107项第三步、35项API回归及离线初始化通过。未更改自动重试,未调用真实模型或重启服务。

候选分析失败的 analysis_errors[].code 现细分为:

错误码 含义
model_http_400 / 401 / 429 / 5xx 上游HTTP状态码;实际保留具体三位数字
model_request_timeout 请求超时
model_network_failure 其他网络错误
model_invalid_response_json 上游HTTP响应不是合法JSON
model_invalid_response_schema 上游choices/message等结构异常
model_invalid_content_json 模型生成内容不是合法JSON
model_invalid_content_schema 模型生成JSON不是对象
model_output_token_limit finish_reason=length,输出达到token限制
model_content_filtered finish_reason=content_filter
model_incomplete_generation 其他非stop结束原因
model_response_too_large 上游响应超过读取上限
model_request_failed / model_unexpected_error 未列明的传输/内部异常,保留安全兜底

原引用校验错误码保留;历史model_service_failure不能回填细分原因。规划/总结既有降级错误包装保持。默认输出上限增加到8192,不代表强制生成更长回答,也不能解决网络或鉴权失败。共享transport将network_or_timeout拆为request_timeout/network_failure,第一步原有重试判定保持。

F043(2026-09-16 15:56):公司检索后,当前用户公司线索与唯一候选的Name或CreditCode完整精确相等时,直接获取工商/荣誉并继续回答,不发送company_selection中断。仅去除线索首尾空白,不忽略内部字符、括号、后缀或大小写;简称、多个完全匹配、无结果及失败保持确认/补问。补充全名后再次搜索也适用;工商返回仍核对KeyNo/信用代码。旧等待确认的检查点仍沿原动作恢复,新问题清空旧画像。

F042最新规则(2026-09-16):默认回答正文不附参考文献、资料依据、资料名称或原文摘录;原文、source_ids、citations及参考链接仍在结构化来源中保留。用户明确要求依据或原文时,按需提供相关短引文。此前自动展开来源的说明由本规则替代,SSE去重保持。

F037(2026-09-15 15:50):persona.SERVICE_VOICE供闲聊与证据分析/总结共用,推荐开场取已生成总结首段,失效时取原有分析答复;政策了解单独总结提示避免个人资格补问。同题QA先原答案引文后来源;summary.text使用Markdown并保留三项动作。report使用markdown-it-py安全渲染(显式依赖,锁文件更新,无新版本变动)。资格满足仍降级待确认,但已有证据且无必要问题时不再自动添加泛化补问。惠企政策排序、引用及召回预算不变。合成真实模型检查:python -X utf8 -m src.step3_question_answer.service_voice_check,不访问Milvus/QCC。

F036(2026-09-15 15:25):推荐item新增knowledge_type和is_policy_library,按候选实际type生成。cards.select_cards先按policy库分组优先,再按原匹配优先级(政策了解组内保留检索顺序),原筛选条件保持。同名候选合格时优先惠企来源;全文sources不删。CLI/HTML显示“惠企政策库”标识。候选召回预算未改,排序仅作用于入选推荐,具体字段见 接口文档。

F035(2026-09-15 15:13):next_actions.py将具体需求入选推荐中的有据待确认条件整理为三项下一步动作,缺额使用阅读/选择事项动作;无推荐或政策了解为空。三项动作追加到summary.text末尾,CLI/HTML只随总结展示一次;结构化动作及引文保留。不新增模型调用,不改变资格判断。presentation.order为items/summary,前端沿用总结即可,API规则见 接口文档。补问增量重算未实现。

F026已增加 第四步流式HTTP接口,复用这里的图和Redis检查点,启动预热并提供单进程多会话并发。下文F017–F025的“无Web接口/并发尚未验收”属于当时边界,最新接口能力与限制以第四步说明为准;跨轮指代理解已由F057补充,见下文上下文章节。

代码位于 src/step3_question_answer/。默认CLI已接入企查查、Milvus和DeepSeek;企业输出相关知识完整记录与LLM匹配原因,个人回答同样附完整来源。政策适用性尚需核验,当前交付为本地CLI、结构化JSON和离线HTML来源页,不是生产Web服务。

使用

F034现行规则见下方三类分流;单纯身份/能力介绍均属闲聊,不查询知识库。

.\.venv\Scripts\python.exe -m src.step3_question_answer
# 手工填写公司需求,跳过意图识别LLM;检索规划和推荐仍调用LLM
.\.venv\Scripts\python.exe -m src.step3_question_answer --manual
# 保留仅公司画像模式,完全跳过政策检索和推荐
.\.venv\Scripts\python.exe -m src.step3_question_answer --manual --company-only
.\.venv\Scripts\python.exe -m unittest discover -s src/step3_question_answer/tests -v

交互中输入公司候选序号确认,支持新关键词、/next、/retry、/cancel;主问题输入/quit退出。每轮重置当前画像,仅明确延续同一已确认公司时恢复;多公司联合分析尚未实现。用户补充关键条件后可将其写进新问题重查,当前补问输出未实现同一候选的增量重算。

LangGraph流程

flowchart TD
    A[保留原问题并重置状态] --> R[识别会话目的]
    R -->|闲聊含身份能力介绍| S[依据角色信息由LLM自主回应]
    R -->|政策了解或分类失败降级| P[按原问题检索六库含QA并回答]
    R -->|具体需求| B[识别是否需要公司事实]
    B -->|无需公司| H[主体与需求交接]
    B -->|缺少线索| C[interrupt补问]
    B -->|有公司线索| D[886模糊搜索]
    C --> D
    C -->|无需公司| H
    D --> E[interrupt等待用户选择]
    E -->|补充或翻页| D
    E --> F[410工商信息及身份核对]
    E -->|取消公司查询| H
    F --> G[1001荣誉有界分页]
    F -->|失败| H
    G --> H
    H --> I[保留原问题并按独立需求拆解]
    I --> J[六类库召回并校验完整原文]
    J --> K[LLM逐条分析与引用校验]
    K --> L[回答、匹配原因、完整记录与可查看来源]
    P --> L

公司未确认或查询失败时仍可搜索一般政策线索,但明确无法判断企业资格。模型输出与数据不得改变节点权限;公司选择只能使用当前候选KeyNo。中断确认节点没有网络操作,恢复不会重跑已完成的候选查询。

三类请求分流(F034)

类别 标识 处理
闲聊(含身份、能力、使用方式、问候和未说明主题的咨询开场) smalltalk LLM依据现有角色信息自主回复,不调用企查查、检索、推荐或生成来源
政策了解(含政策、指南、材料QA及一般事实问答) policy_overview 按原问题检索六库,包含qa;基于原文回答,不画像、不拆解个人需求或判断用户资格
具体需求(实际困难、个人/企业目标、自身适用资格) specific_need 按需确认公司、获取工商和荣誉、需求拆解、跨库检索与适用性分析,依据原文回答

角色信息目前由persona.py的SYSTEM_PROMPT提供,来源是现有角色规范及已实现能力;未接入独立知识图谱角色查询。闲聊由意图识别的同一次LLM调用生成direct_response,仅输出失败时使用固定兜底。不能把知识资料中机构的服务当成助手自己的接口能力。

“你能干嘛”归闲聊;“营业执照变更需要哪些材料”归政策了解;“我开店缺资金,能申请什么支持”归具体需求。混合问题按实质业务内容分类。一般事实咨询仍走知识问答,无依据不使用模型常识补答。“我想咨询一下”没有主题时在闲聊中自然补问,不增设第四个类型。

图只接受这三个枚举;模型异常、非法JSON或旧类型输出均降级为policy_overview,保留intent_analysis_failed错误并按原问题检索,不猜测企业信息。旧Redis记录仍可读,新的完整问题重置旧类型/画像/检索;未增加历史指代理解或自动画像继承。企业确认中断与显式/retry恢复保持原行为。

非闲聊统一依据知识库(F033)

本节QA证据规则继续有效;F033早期把能力咨询强制检索的范围已由F034三类规则替代。政策了解与具体需求均通过同一个Retriever检索policy、finance、qa、article、service_guide、service_catalog六库。不能按“政策了解”名称排除QA库。

明确要求列举办理事项/情形/指南时,检索先按原有六库12候选上限执行;若已核验的办事指南在结构化基本信息.其他业务办理项列出其他情形,再对最多8个缺失情形只查service_guide库,每个情形最多看8个索引命中。仅完整回读哈希正确、事项名称/区划名称/情形名称均精确相同的独立记录加入候选;补查异常显式标记检索不完整。candidate_limit在触发补查时为20,base_candidate_limit仍为12。其他问题不触发补查,关联文字本身不作为独立指南或链接来源。

QA无推荐卡片仍保留knowledge_answers、原文引用和完整source。同题QA保留原答案,多个同题答案冲突明确说明;非同题答案由模型基于原文分析并校验逐字引用。无依据与服务失败区分,不能用无关内容填充答复。answer和summary可能含相同答复,前端不得机械重复拼接;前端去重未在本次修改范围。

政策了解不做用户资格补问,eligibility=not_evaluated;具体需求才按相关画像和原文核验条件。检索到资料不等于具备资格。QA来自实际检索记录,本地或合成替身不作为远端Milvus成功证据。

验证入口为python -m src.step3_question_answer.intent_check,固定样例conversation-v5-three-kinds包含33条;真实DeepSeek分类,下游为调用观察替身。第三步/第四步unittest另验证实际跨库代码包含QA、原答案/来源进入图和SSE、公司确认与错误分支。真实远端QA召回质量仍以F033证据为准。

--manual继续作为操作人员显式绕过分类的具体需求模式。服务启动Embedding预热不等于请求触发知识检索。修改代码需重启现有服务才能生效。

推荐优先级与前端所需数据(F024)

用户最终要求:取消推荐最多6项的限制,按推荐优先级排序;本轮只获取和返回所需信息,暂不修改CLI/HTML渲染,也不建设前端接口。将来前端按卡片在前、综合说明在后展示。

具体需求模式的检索规划现在接收当前问题和按需获取的工商/荣誉事实;泛问惠企政策时可根据已有行业或资质形成相关检索方向,不编造融资、招人等实际计划。个人信息来自当前及明确延续的历史用户自述,未接个人外部信息接口。原问题仍完整保留,查询拆解的evidence要求本轮或历史用户发言逐字依据,不能引用历史助手回答。

分析输出match_basis逐项比较主体事实与政策条款,校验双方引文与路径。公司事实仅选择当前相关字段,荣誉保留取得/截止日期;可用时带企查查接口编号、获取时间。无完整有效日期或已过期的荣誉不能作为现行资质支持。用户自述标记为user_statement,不当外部核验事实。登记经营范围不代表实际行业收入或项目资格,注册地址不代表项目、户籍或纳税所在地。

针对性推荐须有需求、行业或资质方面的支持线索;只因同地区、企业存续或主体类型一致不够。已明确条件不满足、有主体冲突、过期、纯查询入口或缺少具体名称/支持内容的资料不进入推荐卡,但完整原文仍保留在sources。只按同一完整名称去重,保留优先项;不把不同版本的金额与条件拼成一个政策。

排序依次考虑实际需求支持、公司行业/荣誉资质支持、有效比较维度覆盖,同等依据保留检索顺序。返回priority.rank和排序依据,数值只表示展示顺序,不是资格分数或获批概率。这是有界规则排序,尚未完成总体排序质量评测。

推荐层不截断已入选卡片条数;F056最终恢复每条查询每库3条/合计12候选上限。相关政策经原文及适用条件核验后全部进入排序;实际业务召回质量仍需评测。

后端返回契约

recommendation.items[]按优先级排列,旧字段保留,每项新增:

字段 含义
card.kind F046新卡片固定policy;金融/服务资料仍参与有据回答,不生成卡片
card.name 原文完整正式名称,text必须等于一条原文引文
card.department 政策主管/实施部门;金融产品为提供机构,不等同转载方
card.support_objects 支持对象
card.support_methods_standards 支持方式、金额/比例/利率等原文标准
card.application_conditions 政策申报条件,与用户资格核验分开
card.match_reason 针对主体事实的匹配原因、政策引文及subject_policy_comparisons
match_basis dimension、status、fact_path/fact_quote、policy_path/policy_quote、explanation、fact_origin及provenance
priority rank从1开始,basis说明规则

card.name及四个政策信息字段为{text, citations:[{path,quote}]};缺失信息为null,后续界面可展示“原文未明确”。不会补造部门、名称、标准或用户事实。引用能被逐字找到不代表全部语义与资格已核验。

summary独立返回text、source_ids、status和notices,供最后展示综合结论、主要匹配方向及下一步。仅使用入选卡片及其主体比较信息,避免重复发送引用元数据;发生预算、生成或结构失败时返回确定性备用说明并标记fallback/error,不影响已校验卡片。notices保留检索/分析/公司信息不完整等事实。

excluded_items仅记录未展示来源ID和原因(expired、ineligible、reference_only、subject_conflict、insufficient_personal_match、duplicate_name),不发起这些条目的资格补问。sources继续保留全部实际返回的相关/未完成分析记录及完整原文。presentation.order=[items,summary]是后续前端契约,当前CLI和HTML顺序未修改。

合成验证入口

.\.venv\Scripts\python.exe -m unittest discover -s src/step3_question_answer/tests -q
.\.venv\Scripts\python.exe -X utf8 -m src.step3_question_answer.card_check
.\.venv\Scripts\python.exe -X utf8 -m src.step3_question_answer.matching_check

后两项调用真实DeepSeek,但政策、公司、荣誉与个人信息均为固定合成数据,不访问真实QCC/Milvus。输出仅保存在忽略目录output/checks;最终状态与结果见F024 evidence。该验证与用户真实企业的推荐复验、整体排序指标、前端展示验收分开。

企查查接口

官方接口:886模糊搜索、410工商信息、1001企业荣誉。

接口 路径与参数 规则
886 GET /FuzzySearch/GetList;searchKey、pageIndex 每页最多5条;每个问题最多5次搜索,含手动翻页/重查/失败重试
410 GET /ECIV4/GetBasicDetailsByName;keyword 用确认候选全名,回包KeyNo与已知信用代码一致才使用
1001 GET /HonorQualification/GetList;searchKey、pageSize、pageIndex 全名查询,每页20条,默认最多3页;保留已成功页面,未取完明确标记

query key和headers Token/Timespan按官方大写MD5签名。接口地址由配置提供且只接受无凭据、无查询参数及片段的HTTPS URL;禁止重定向,有超时与响应体大小限制,异常不记录URL/密钥/响应正文。成功响应解析Status/Result,分页依据Paging.TotalRecords;荣誉解析VerifyResult/Data,保留官方BegingDate拼写及其他原字段。F041补修:886模糊搜索Status=201且Result缺省/null/空数组时规范化为空候选,保留来源;真实响应已核对为查询无结果。其他未知非200状态仍视为服务失败,不按Message文字猜测;非搜索接口不套用此规则。

2026-09-11:公开供应商测试企业的三个接口均真实返回200,工商身份核对通过。荣誉仅取一页20条,用page_limit验证未取全分支;此企业仅为测试样本,不代表用户所属公司。真实调用并不保证今后额度、权限和服务持续可用。

配置由.env读取且环境变量优先:QCC_KEY、QCC_SECRET_KEY、QCC_SEARCH_URL(默认https://api.qichacha.com/FuzzySearch/GetList)、QCC_BASIC_URL(默认https://api.qichacha.com/ECIV4/GetBasicDetailsByName)、QCC_HONOR_URL(默认https://api.qichacha.com/HonorQualification/GetList)、QCC_TIMEOUT_SECONDS(默认20,1–120)、QCC_HONOR_MAX_PAGES(默认3,1–10)。当前交付的.env已配置三个URL;修改后重启API生效。凭证按用户授权保存在Git忽略的.env,不写开发文档。

检索与完整原文

retrieval.py消费第二步已发布manifest,不猜测集合版本、不重建索引。校验complete、索引契约、维度、数据库/集合名和本地模型文件哈希。查询与入库共用EMBEDDING_MODEL_PATH(默认models/bge-large-zh-v1.5)、BGE CLS池化/L2归一化和长文本分窗汇总,添加中文检索指令。权重指纹包含.bin,旧Qwen快照不兼容新契约;全量重建成功后重启后端加载新manifest。详见知识入库。

按独立需求拆解:LLM返回need、用户原问题逐字evidence与query,并通过related_queries的need_index/relationship/query给出与当前需求有具体联系的相邻方向。程序校验下标及原问题依据,保存父需求及依据,查询去重但不截条数;不因用户企业画像扩展无关政策,搜索假设不成为用户已有项目或资格事实。规划失败退回原问题;政策了解不额外规划需求。并发仅限制同时执行数量,任务排队。

F056最终按用户15:32确认恢复原策略:每条查询在六库分别search(limit=3),按record_id合并同库多查询结果并保留最高相似度;先取有结果的各库首项,再按相似度补足最多12候选。仅回读这12项的完整原文,全部分段批量读取和哈希校验保留;不做整库扫描。per_type_limit=3、candidate_limit=12。惠企优先、问题关联、类别分散及首六卡总结保持。

数量上限约束送入原文分析的候选,不能保证最终卡片数;相关性、资格、原文失败均可能减少卡片。上下文/原文块预算及失败记录保持。只读冒烟入口保留历史模块名full_retrieval_check,当前验证3/12预算而非全量扫描。

按稳定record_id获取所有物理存储段,经数量/顺序/哈希校验恢复完整JSON,再核对索引record_hash。失败库与原文损坏明确记录,不包装为空结果。检索只读取服务,无新建库/集合或写入操作;每库固定独立Milvus客户端,不切换数据库;两层并发由.env控制:RETRIEVAL_QUERY_CONCURRENCY=4(范围1–64)控制查询任务,RETRIEVAL_BANK_CONCURRENCY=6(范围1–6)控制每个查询内部库任务。原问题也作为一个查询任务;最大同时搜索请求数为两者乘积,默认24。环境变量优先,修改.env后重启实例,非法值阻止初始化。模型编码和同实例不同请求仍串行,候选完整内容回读仍串行;按查询顺序及固定库顺序合并保持结果稳定。单个查询/库失败保留其他成功结果,failed_queries记录query_index与type,失败不能当作无结果。

“全部返回”指每条实际返回的政策/知识保留全部入库内容,而不是把数据库所有政策无条件返回。sources[].full_record与Milvus完整记录一致,包括data、raw_record、sections、source和未知字段;不会用摘要替代原文。知识库本身若只含某一申报事项或片段,不能宣称它是官方政策全文;原始URL存在时另外给出链接。

LLM分析、引用及条件

recommendation.py复用已有DeepSeek连接。用于分析的事实排除模型建议和生成摘要;公司仅提供地区、范围、企业类型、状态、成立时间、资本和荣誉名称/级别/起止日期等字段,不发送凭证。原始公司信息的完整来源仍保留在handoff中。

事实按字段路径分组,长文本分为3500字符证据单元,每批约15000 UTF-8字节;逐条最多12批、候选并发4。请求按配置上下文预算保守检查,单次输出4096 token、必须正常stop与合法JSON;引用/结构校验失败最多修正1次。超过预算或调用失败不会截断原文并伪装成功:完整记录保留为未完成分析候选,不成为推荐。

相关条目必须含针对原问题的reason、answer及逐字引文;引文必须存在于指定字段,引用或结构不合法时最多重新生成1次,再不通过即拒绝该分析。地区、主体、行业、时间、其他条件分开列出。模型“满足”不自动当作已核实,统一保守降为待确认;证据能够被逐字找到,不代表它在逻辑上证明全部资格。明确的“本办法/本实施意见…至某日止”等过期执行条款由确定性规则标为历史资料,替换当前申请建议,不把普通申报截止日期误当整份政策失效。该规则并不覆盖所有日期格式或续期情况,仍需原文与现行政策复核。

系统保留模型分析的局限:自动逐字引用校验不能证明每个解释都准确;多份政策版本冲突没有自动裁决,同名条目分别展示;未完成全面效力核验,不输出确定获批结论。关键词补问最多5条,目前不做自动增量资格重算。

返回契约与点击查看

  • recommendation.items[]:source_id、title、answer、match_reason、citations(path/quote)、conditions、eligibility、recommendation_status。个人和企业都使用引用,不能凭空生成政策标题或来源URL。
  • recommendation.sources[]:对应条目的完整full_record、来源、snapshot、detail_anchor、analysis_complete。标题和链接由真实记录填入,不采用模型输出的链接。
  • retrieval_analysis_complete表示此次有限候选的检索与分析成功;complete还要求所需企业画像与荣誉获取完整。两者都不是“找到了所有适用政策”或“资格已满足”。
  • CLI将结果保存到Git忽略的output/consultations/,一份JSON和一份独立HTML。页面点击“查看完整知识原文与来源”跳到对应内容并展开;有原始URL可另开来源网页,无URL仍可查看完整入库内容。原文按纯文本转义,拒绝javascript等非HTTP(S)来源URL。

HTML只是本地结果查看器,没有网络服务、外链脚本或生产鉴权。浏览器工具的安全策略阻止打开本地file URL,本轮验证了HTML内容、锚点与转义,未通过自动浏览器实际点击验证。Redis同步检查点由F025实现;thread_id鉴权绑定和同会话并发控制仍由后续宿主实现。

Redis上下文持久化(F025)

CLI从.env读取REDIS_URL(必填,redis/rediss URL)与REDIS_CONTEXT_TTL_SECONDS(默认1296000秒,即15天,允许1–31536000秒),同名环境变量优先。不会输出连接信息,也不把密码写入文档;缺失/非法配置或Redis故障时明确失败,不自动退回内存而丢失上下文。底层build_graph仍允许注入checkpointer,未注入时保留内存模式供离线测试。

启动打印随机会话ID;退出后以相同运行模式和--session-id <ID>重新启动,可恢复未完成的公司需求澄清/公司候选确认。已有完整结果和历史检查点可通过get_state/get_state_history读取。ID不存在或过期时明确报错;CLI不提供新建或清除会话命令,后续由前端控制生命周期;底层delete_thread保留供宿主集成,当前未新增前端接口。尚未输入问题的新ID没有持久化记录。Ctrl+C退出后已完成的检查点仍保留,故障后的最后节点可能重跑;不保证外部服务调用恰好一次。

context.py实现LangGraph同步检查点接口,保存原问题、当前路由、公司候选及已确认画像/来源日期、检索推荐状态、父检查点与中断待写数据。每个会话一个带版本前缀和ID哈希的Redis Hash,命名空间分开;普通Redis即可,无需RedisJSON/RediSearch。数据使用LangGraph类型序列化加base64封装,不使用pickle回退。Lua原子写入并续期,普通任务写入幂等,控制写入可替换;所有检查点和待写数据共用一个TTL,不留下孤立记录。写入成功续期,读取不续期;每次写入从当时重新计算15天,持续使用的会话历史可能保留超过15天。

连接显式使用RESP2兼容当前服务,连接与命令各5秒超时,错误只返回固定代码。redis-py超时参数见官方文档。当前实现保存完整历史,读取整个会话Hash;长会话容量、历史裁剪、跨版本迁移、异步流式接口、同会话并发调用及生产鉴权尚未验收。宿主必须按用户绑定ID并串行操作同一会话;ID哈希不是鉴权。不同会话可以独立使用。清除Redis不删除既有本地导出的JSON/HTML。

F025最初仅实现状态持久化与流程恢复;F057(2026-09-17)已补充三类回答共用历史。每轮prepare先收集上一轮问题、回答和政策标题/位置,再重置本轮输出。旧会话首次从同thread检查点只读恢复(最多扫描100个检查点);新状态保留最近9轮,模型最多使用8轮且历史预算6000 UTF-8字节,优先缩短历史回答,必要时省略条目并标记。实际政策原文不因此截断。

意图模型接收历史并输出context_relation、context_query和reuse_company。原问题保留,解析后的追问检索表达只是检索假设;规划、逐项分析、政策总结及知识综合均接收历史。延续问题允许引用历史用户自述作为主体依据,历史助手回答不能作主体事实或政策引文。明确延续同一已确认企业才恢复其画像,切换公司仍走确认/获取流程,不跨thread使用。补问后仍重新检索分析,不是同一候选的增量重算。

政策总结继续仅使用最终前6卡的已验证answer/citations及卡片信息,历史仅帮助理解本轮意图,不能引入未展示政策结论。169项第三步、37项API合成回归通过;三类纯合成真实模型追问通过,旧会话两轮只读恢复通过。需要重启后端并在原会话发新请求完成用户验收。

验证入口:python -m src.step3_question_answer.context_check,仅通过配置的Redis写入随机合成会话,用独立Python进程恢复中断,验证TTL、隔离和删除;另用1秒TTL验证实际过期,结束仅清理本次随机键。不会调用QCC、Milvus或DeepSeek。

验证与证据边界

固定首批无政策名场景在src/step3_question_answer/tests/discovery_cases.json;覆盖个人培训、创业、设备资金、人才研发、交叉主体和保证获批的不合理请求。它们是场景种子,尚未全部完成独立人工政策标注或Recall@K验收。

真实冒烟入口(会访问服务、可能计费):

.\.venv\Scripts\python.exe -X utf8 -m src.step3_question_answer.live_check --mode personal
.\.venv\Scripts\python.exe -X utf8 -m src.step3_question_answer.live_check --mode enterprise

已实测个人无公司路径和公开测试企业确认后检索生成路径;逐条原文与本地增强知识核对、模型引文校验结果见F018证据。首次审阅暴露过期条件与模糊地点过宽认定,已加保守处理和回归。真实资料仅存忽略目录,不写维护文档。有限真实样例与合成测试不代表总体召回率、推荐质量或生产可用性达标。

启动预热(F019)

默认CLI和真实冒烟入口在接收问题前调用Retriever.warmup():验证模型文件契约、加载本地模型,并用固定合成文本执行一次向量推理,提前完成设备初始化。成功后显示“检索模型已就绪”,随后才输出欢迎语并接收输入;失败时终止启动,不将未就绪状态暴露给用户。

同一Retriever实例的预热在锁内执行且幂等,后续问题复用该模型。--company-only跳过加载。预热不连接Milvus、不调用QCC或DeepSeek;Milvus连接仍在首次检索时建立。直接集成Retriever的宿主应在启动生命周期中调用warmup,并复用实例;当前项目仍为CLI,没有Web服务生命周期实现。进程重启后需要重新加载,耗时是从首次提问移到了启动阶段。

2026-09-11本机实测:首次warmup约5.535秒(含模型校验、加载与推理),重复约0.000003秒且复用同一模型。这不是跨机器延迟承诺,后续检索和LLM仍有自身耗时。32项第三步测试覆盖预热并发幂等、失败可重试、输入前完成与仅公司模式跳过。

2026-09-11 查询拆解与并发验证

F020:真实固定查询串并行结果完全一致(12候选、零失败库),预热后各测三次,中位数7.3993秒和5.5992秒,约减少24.3%。仅为本机该查询的检索耗时,不含LLM,不是端到端延迟承诺。

F021:合成问题中的设备更新、融资周转、研发招聘、产品出海四需求,经真实LLM生成四条独立搜索表达;合成回归验证原问题加四需求均进入六库。search_plan在图状态及回答JSON中保留需求映射和失败码;规划失败在overview与HTML显示。查询是搜索假设,不代表政策存在或用户资格。候选合并仍最多12条,可能有需求没有进入最终候选;未完成按需求召回率、候选配额或语义覆盖评测。

F021最终两层并发实测:四个合成独立需求加原问题共5查询,12候选;并行5.081秒、全串行14.199秒,结果完全一致,无失败查询。单次测量且并行包含首次连接,不能作为稳定性能或端到端承诺;43项第三步回归通过。

公司信息返回与Redis(F040)

图状态新增 compang_info:工商成功后保存 {company, profile, honors: null},荣誉结束后更新完整 honors。沿用完整检查点的Redis持久化及会话TTL;不依赖后续推荐成功才保存。prepare在新问题开始时重置为空字典,防止跨轮串用。API的 result.data.company_info 从内部旧键 compang_info 映射,兼容既有Redis检查点。契约见 接口文档。

知识正文统一归纳(F047)

非同题QA的多来源、多块或长回答统一生成summary.text,混合卡片不再先生成总结后追加知识回答。默认目标150–350字,上限600字;明确详细/完整/原文请求上限1800字,不硬截断。单条350字内无换行答案直接保留;同题QA仍按既有原文/冲突规则展示。summary.source_ids与citations关联实际采用来源;完整sources、knowledge_answers和卡片保留,不应再把knowledge_answers追加到正文。归纳失败为status=fallback、error=summary_generation_failed,正文明确说明整理失败,原文仍可查看。接口字段不变;源ID合法和引文逐字存在不保证归纳语义完全正确。

F047预算扩容与分批归纳

2026-09-16 17:56:本地共享SUMMARY_CONTEXT_TOKENS从32768提高为131072(其余配置文本不变);JsonModel输出仍16384。该共享项也影响未来第一步摘要预算,未重新生成知识。官方模型上下文说明:https://api-docs.deepseek.com/quick_start/pricing/ 。本地保护仍使用UTF-8字节保守上界,不把字节当实际token。

统一汇总超预算时,按实际提示/问题/JSON大小装批;超大单条连续完整切片,中间笔记保留来源、地区、限制和冲突,再统一生成最终正文。最多4层及32次模型调用;不收敛或超过预算为summary_reduction_limit/analysis_context_limit,不截断原文或发布部分成功。中间笔记上限1800字,最终仍原600/1800字规则。原完整引文保留;多阶段模型归纳仍可能遗漏或重复语义,需要业务复验。API并发包装器现在传递模型预算,summary_diagnostics新增model_calls、max_call_input_bytes、reduction_levels。

F047取消字数限制(2026-09-16 18:09)

按用户最新要求,最终统一回答、中间证据笔记和政策综合说明不再用字符数拒绝,也不按长度额外重试或截断。原600/1800/2000字说明作废;提示词仅要求精简、美观、去重并保留关键条件。summary.diagnostics不再产生text_limit,output_chars仅作观测。输入上下文预算、模型输出token上限、分批停止条件及来源/结构校验仍保留。此修复针对1046字被错误丢弃的已定位原因,需重启后新请求验证。

F074附件与问答(2026-09-20)

API将本轮incoming_attachments传入图,prepare接收后清空输入槽,attachments保存本轮提取结果;公司中断恢复保留,新问题显式重置,避免串用。有限原文摘录进入需求识别/规划/主体比较,完整提取文字及视觉笔记进入有界联合综合;附件来源不生成政策卡片、不能独立确认身份或资格。同题QA有本轮附件时也走联合回答,失败状态明确返回。原问题不拼接附件,不将下载链接放入模型或Redis。详见附件契约。

F077 候选分析恢复

字段精确诊断、缺引用/名称差异定向修正、分块证据合并、单块失败隔离及需求相关性约束见候选分析恢复。多块全部通过后才合并卡片;失败候选的已核验片段留在partial_answers,不进入最终推荐或综合。需重启后端,旧记录不回填。