当前契约核对日期:2026-10-26(F163)。本页按Feature保留演进说明;实际路由与校验以
src/step4_api/app.py、runtime.py为准。当前正文支持增量SSE,前端应使用下方的answer_start/delta/end/abort协议;较早章节中“结果全部生成后才发送”“不是逐token输出”等说法仅为当时实现,不再描述现行正文流。服务的路由总览见第四步服务说明。
金融产品详情、办事指南及网上办理入口统一放在对应说明段落之后;办理渠道链接在渠道说明后、材料或流程栏目之前。金融链接显示“具体产品名(产品详情)”,办事链接沿用“具体事项及情形(办事指南/网上办理入口)”。同段采用多个来源时,各链接带自身名称,不集中到无关章节或全文末尾。
综合阶段内部link_sections以来源ID、章标题及正文原样末句after定位段落,程序校验位置并绑定来源的真实网址。缺少有效段落映射时可按唯一对应章节补在说明后;归属不明的链接仅保留在完整来源中,不生成孤立的正文尾部链接。此规则替代下文历史“章标题下”和“末尾具名兜底”的放置方式。
接口字段保持,summary.detail_links仍为source_id/title/url。前端按answer_end.text替换临时正文,勿把链接再次集中追加;本次无新事件或额外前端字段。更新代码并重启后对新请求生效,历史回答不回填;未验证线上模型实际映射质量或前端呈现。
F114(2026-09-23):知识原文中的<image-scope>图片URL</image-scope>可按语义放在summary.text的对应正文位置,前端就地渲染该标记,不另建末尾图片列表。例如:
这是该小程序的二维码:
<image-scope>https://example.invalid/code.png</image-scope>
进入后按页面提示操作。
没有后续说明时可以直接以图片结束。本轮支持源资料已有image-scope标记:模型选择来源内的图片及位置,后端从已完成分析、最终采用的来源绑定HTTP(S)地址,相关图片的原文路径和标记保留在citations中;未选择的图片不自动追加。内部图片占位符不会发到answer_delta,图片URL在校验后的answer_end.text、summary.text和最终result中返回;前端沿用operation=replace覆盖同一回答块,避免继续显示“扫码”草稿或重复插入。无需新增图片事件。后端不下载/生成二维码,外部前端负责实际图片渲染;需重启后新请求生效。同题QA原文中的标记按既有原样回答契约保留。
F113(2026-09-23):summary.text中的办理链接改为“具体事项及情形(办事指南/网上办理入口)”,summary.detail_links.title同步采用原文情形名称。URL仍由后端按来源绑定,字段结构不变;前端按返回的Markdown链接文字展示,勿覆盖为统一“查看办事指南”。单项时限等短问题可直接回答并附一个相关入口,无需固定三栏。需重启后端,新请求生效,历史回答不回填。
区域前提作为首段delta,最终校验后的末尾建议在end前补入delta;正常纯追加路径delta拼接与end一致。独立answer提示移到summary后,去掉重复的总结开头。end仍整块替换、summary按stream_id更新同一块、result仅校准;不要把每个text都直接追加。引用失败或链接绑定仍可能最终替换草稿。需重启后端,见流式协议。
有政策时,完整 source / item 先返回,再输出综合讲解的 answer_start / answer_delta。前端收到item即可在正文上方展示卡片,不等result;节点结束不重复发卡片,result仅校准最终快照。首6张及展开规则不变,讲解降级时保留已校验卡片。后端需重启,详细顺序及边界见正文流式协议。
F109(2026-09-23):pictures、files 可传相对路径,由后端按 .env 的 API_ATTACHMENT_BASE_URL 补为下载地址;当前本地前缀为 http://121.43.55.7:10081/dms/。完整HTTP(S)链接保持原样,空前缀不接收相对路径。详见附件接口契约。
请求新增可选pictures与files链接数组,均可省略或为[];例如{"thread_id":"chat-1","question":"请结合附件分析","pictures":["https://files.example.com/image"],"files":["https://files.example.com/document"]}。支持静态JPEG/PNG/GIF/WebP、Excel(XLSX/XLSM/XLS)、DOCX、文字PDF,按实际内容识别,无需URL扩展名。附件与知识证据联合回答,原question不改写。
新增attachments处理状态事件、progress.stage=attachments及result.data.attachments;完整提取内容通过原有source事件和recommendation.sources返回,类型user_attachment,不是政策卡片。失败和超限明确提示,超长文字按模型预算分块综合。公司确认/恢复时请省略附件或传空数组,原轮附件会保留。后续新问题不自动继承旧附件全文。格式范围、下载限制、token预算和前端字段见附件接口契约。依赖安装后需重启后端,生产下载及外部前端尚待联调。
F111(2026-09-23):任一附件下载、格式或读取失败,SSE在attachments状态事件后直接返回error.code=attachment_processing_failed,error.data.message指出“图片N”或“附件N”及原因;不再做分类、检索或部分回答,也不返回result。前端应显示错误消息,并让用户替换附件后重新提交本轮问题。PDF任一页无可提取文字同样终止。
链接语法或协议在接纳前无效时仍为HTTP 422,JSON响应的message与attachment指出具体序号;前端需同时处理这一入口错误。
保留原阶段事件,新增 answer_start / answer_delta / answer_end / answer_abort。前端在 answer_delta.data.text 到达时追加正文,在 answer_end 用完整text替换;失败撤回临时正文。外层仍为thread_id/request_id/data。原answer/summary继续返回完整文本,可选stream_id用于关联同一正文并避免重复。仅监听旧事件仍会等完整答案;接入规则、样例、失败处理与验证见正文流式协议。后端需重启,外部前端需接入事件,result结构不变。
先匹配DMS基础信息草稿;唯一全名/信用代码精确匹配直接读取基础资料,其他匹配展示最多3家供选择。基础资料确认并读取成功后才按信用代码查询荣誉,多条逐条返回,无记录为空列表。DMS无候选自动查询企查查,错误降级保留诊断。
DMS候选列表interrupt.result.candidates末尾自动追加“搜索更多公司”,最多3家公司加1个操作项,无需新增按钮。该项KeyNo为action:search_more_companies,其他公司字段为null。沿用原列表选择方式,保持thread_id,提交该项序号、名称、KeyNo或候选JSON字符串即可,也支持/more;actions.more保留兼容。操作项不会进入company_info或被当作公司查询。随后使用原线索查企查查,仍按精确匹配/候选确认规则处理;原有序号选择和企查查/next翻页保持。不要把action对象直接放进question。
company_info内部company/profile/honors结构保持,DMS业务字段转换为企查查命名并排除额外标签。DMS候选KeyNo使用dms:1888:<记录ID>;source.provider为DMS并提供栏目/记录ID及获取时间,document_url=null。前端不要假定所有KeyNo都是企查查ID或所有source都是企查查。详见查询契约与字段映射。后端需重启,前端沿用原列表渲染和选择方式;历史结果不回填。
SSE result 事件的 data.cipa 为布尔值,与 response、company_info、recommendation、errors 同级。用户询问CIPA、海外服务平台,或表达出海服务需求时为 true,否则为 false。复用需求识别LLM同次调用进行语义判断,不使用关键词匹配,不增加模型调用。
{"response":"回答正文","cipa":true,"company_info":{},"recommendation":{},"errors":[]}
各类回答及公司补问的result均提供该字段。结合必要历史理解指代,每个新问题重新判断;公司确认中断恢复保留原问题的判断。明确否定且未询问平台、国内业务和一般海外旅游/留学不触发。仅询问平台本身也触发,无需已提出办理需求。
模型缺失字段、返回字符串/数字等非布尔值或识别调用失败,走既有 intent_analysis_failed 降级,cipa=false;此时false不是成功判定不需要出海。旧检查点/手工模式无判断时默认false。前端读取 result.data.cipa,无需解析回答正文。需重启后端生效,历史不回填;该标记不代表服务办理、资格或政策匹配成功。
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仍保留原文路径,政策与其他知识联合正文保持。
每个采用且有有效地址的金融产品,按F163在对应介绍后显示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链接支持;后端重启后新请求生效,历史不回填。
F056(2026-09-17):items仍返回全部入选政策,前端初始展示按数组顺序取前6项。首6项优先覆盖不同支持类别,同类别优先惠企来源,再按问题关联与主体依据;其余政策后移而不删除。新增items[].policy_category(主要支持类别)及relevance_level(direct/adjacent/unspecified)。F064更新:正文的政策范围仍为最终items[:6];同时存在相关非卡片知识时,共同生成summary.text,实际采用来源关联source_ids与citations,完整原文保留在sources参考资料。地区前提、政策补问和下一步仍依据首六政策。联合整理失败明确说明失败并保留参考资料。无卡片及同题QA仍走原知识问答。presentation.summary_policy_limit=6;展开更多卡片不会自动重写已有总结。retrieval.per_type_limit=3表示每条查询每库取3条,candidate_limit=12表示多查询六库合并后最多12候选。新请求需重启后端加载,历史结果不回填。
F162(2026-10-26):所有来源中,原条目 raw_record.is_policy 严格为JSON布尔 true 的知识均可生成政策卡片,不再检查来源文件白名单。字段缺失、false、字符串 "true"、数字 1 或顶层派生标记不能授予此资格。article等分库类型不限制明确标记的政策;knowledge_type及is_policy_library仍表示实际分库。准入后继续核验相关性、有效性、条件及引用,card.kind仅为policy,不保证所有标记记录最终进入items。其他有据知识仍可贡献正文、引用及完整来源。此规则替代F046的四来源限制;人才接口原有已验证事项与原文关联规则保持。需替换代码并重启后对新请求生效,已入库记录已有正确原始标记时无需重建知识库,历史结果不回填。
F043(2026-09-16 15:56):公司检索后,当前用户公司线索与唯一候选的Name或CreditCode完整精确相等时,直接获取工商/荣誉并继续回答,不发送company_selection中断。仅去除线索首尾空白,不忽略内部字符、括号、后缀或大小写;简称、多个完全匹配、无结果及失败保持确认/补问。补充全名后再次搜索也适用;工商返回仍核对KeyNo/信用代码。旧等待确认的检查点仍沿原动作恢复,新问题清空旧画像。
F042最新规则(2026-09-16):默认回答正文不附参考文献、资料依据、资料名称或原文摘录;原文、source_ids、citations及参考链接仍在结构化来源中保留。用户明确要求依据或原文时,按需提供相关短引文。此前自动展开来源的说明由本规则替代,SSE去重保持。
10:18补修:企查查886实际以业务状态码201及空Result表示无结果,适配器现正确转换为 not_found,不再错误返回 search:provider_failure 和重试提示。其他服务错误仍单独提示失败。旧会话已保存的错误不会自动改写;新查询使用新规则,运行中的服务需重启加载代码。
公司搜索无候选时返回 interrupt.data.kind=company_need,表示需要补充信息;仅有候选可选时返回 company_selection。interrupt.data.status:not_found为正常查询无候选,failed为服务失败(同样使用company_need),found为有候选待确认。空结果不等于公司不存在。
初次询问是否需要公司信息的company_need没有result;搜索后的company_need带有result/status/actions。两者通过相同thread_id和question继续,服务端按是否存在搜索result选择正确恢复协议。无需前端构造内部action;旧检查点的company_selection仍可补充名称或跳过,下一次生成中断时使用新kind。
not_found 时 interrupt.data.question、answer.data.text 和 result.data.response 同步返回:
本次未检索到与您提供的名称或代码匹配的企业。请核对并补充工商注册全名或统一社会信用代码;也可以输入“跳过公司查询”,先按原问题了解相关政策。
此时 company_info={}、done.status=needs_input,actions为 refine/skip/cancel。前端按question或answer展示一次提示,不重复追加response。保持相同thread_id,通过question发送新名称/代码继续查询,或发送“跳过公司查询”、/skip、“不需要”、“无需公司信息”跳过画像并按原问题继续;不代表企业身份或资格得到确认。
failed时明确说明查询服务暂时未能完成、无法判断是否有匹配企业,保留错误码并提供 /retry。两种情况均暂停等待用户,不自动重查;同一轮至多查询5次,下次查询尝试触发 search_limit 并退出公司确认。既有 /cancel 保留。
此字段可直接作为 POST /api/company/classify 请求体,返回六角度多标签分类;无需外层包装。见 公司分类接口。
SSE result 事件的 data 新增字典 company_info(2026-09-18纠正原拼写compang_info),与 response、recommendation、errors 同级。用户确认公司、工商查询成功后返回以下结构:
{
"company_info": {
"company": {"KeyNo": "synthetic-key", "Name": "合成公司"},
"profile": {
"data": {"KeyNo": "synthetic-key", "Name": "合成公司"},
"source": {"provider": "企查查", "api_code": "410", "fetched_at": "2026-09-16T01:00:00+00:00"}
},
"honors": {
"records": [],
"sources": [{"provider": "企查查", "api_code": "1001", "fetched_at": "2026-09-16T01:00:01+00:00"}],
"complete": true,
"error": null
}
}
}
这是合成字段片段;profile.data 保留工商接口的全部原始字段,profile.source 保留来源与获取时间。honors.records 每项为 {data, source},保留各条荣誉原始字段及对应页来源;honors.sources 为查询页来源。成功但未查到荣誉时 records=[]、complete=true;查询失败或页数上限保留已查到的记录,complete=false、error 标明原因。工商已成功但荣誉尚未执行时 honors=null。
未查询、候选尚未确认、取消或工商查询失败时 company_info={};失败仍通过既有 errors 报告,不能把失败当作没有资料。旧会话没有新增字段时也返回 {},不回填历史结果。
工商和荣誉节点分别将此字典写入图状态,由现有 RedisContextSaver 保存到当前会话检查点,默认随会话写入续期15天(REDIS_CONTEXT_TTL_SECONDS)。读取方式为 graph.get_state(config).values['compang_info'],其中 config.configurable.thread_id 为当前窗口ID。无需新增Redis配置或独立全局公司缓存。新问题先重置当前公司字段,F057仅在明确延续同一已确认企业时恢复上一轮画像;旧检查点仍随会话保留到过期。仅原有 result 事件新增字段,无独立公司信息事件。
summary.data.text 和最终 recommendation.summary.text 为Markdown正文,保留回应问题的首段结论,按需使用 ### 小标题、**重点**、无序列表及末尾三项编号动作。F042不再额外发送与总结重叠的answer开场,独立备用结论或提示除外。不使用外层代码围栏;简单无依据答复可以只有一段,不强行凑栏目。同题QA原答案保持引用块,先答案后资料名称。
summary末尾示意(格式示例,非真实政策):
这项支持可以帮助您了解开店准备和经营管理。
### 可以先了解的支持
- **创业培训**:具体内容以对应原文为依据。
### 下一步建议
1. **确认相关地区**:具体问题由已检索到的条款生成。
说明这项信息为什么影响申请判断。
实际具体需求仍输出三项动作;上例只展示一项的排版。结构化next_actions与来源仍保留,不新增事件。前端继续读取summary.text,使用Markdown渲染并禁用/清理不可信HTML,不要再显示独立动作块。CLI输出Markdown文本,本地HTML支持标题/列表/加粗/引用,禁用Markdown内嵌HTML、图片与链接,原始来源仍由专门的安全链接展示。
progress.data.stage/status/message字段与时序不变,只更新用户文案:查阅资料、对照原文、了解情况等;accepted为“收到,我先了解一下您的问题。”,heartbeat为“还在为您准备答复,请再稍等一会儿。”。不把用户原话插入提示,不声称已找到政策、已满足资格或已经办理。
每个 item 新增 knowledge_type(实际来源库类型)和 is_policy_library(是否来自惠企政策库,布尔值)。例如 {"knowledge_type":"policy","is_policy_library":true}。这两个字段来自检索候选的type,不依赖模型生成的card.kind或名称;其他库中的政策卡片也会返回false。政策正式名称保持不变,前端可根据true显示“惠企政策库”标识;CLI/HTML已显示该标识。
推荐 items 及SSE的item事件按以下顺序返回,priority.rank连续编号:
F056当前先按惠企来源、direct/adjacent/unspecified问题关联、主体证据排序,再用每个支持类别的最高优先项组成前六卡,不足六类按基础顺序补足,剩余政策保留。同类政策仍惠企优先;为覆盖不同类别,其他来源的新类别可排在惠企重复类别前。政策了解不比较用户资格。presentation.sorted_by=category_diversity_then_policy_library_relevance_evidence。同名去重优先保留合格的惠企政策库版本,其他全文来源保留。
来源优先级不绕过过期、不适用、主体冲突、缺少个人匹配依据等筛选规则;标识代表来源库,不代表已获批或已实时核验效力。六库召回范围和候选预算不变,排序只针对本轮已召回并入选的推荐。summary末尾三项动作规则不变,其选取随新的推荐顺序执行。
具体需求有入选卡片时,三项下一步建议以“下一步建议:”及1/2/3编号追加到现有 summary.text 末尾,保留原综合结论。前端沿用现有总结字段即可展示,无需新增区域或展开政策详情。顺序仍为 items → summary。政策了解、纯QA和无推荐不追加。
SSE现有 summary 事件的 data.text 和最终 result.data.recommendation.summary.text 均包含下一步建议,不再发送独立 next_actions 事件。recommendation.next_actions仍保留结构化数据与引文供追溯,前端无需消费或重复渲染。summary.source_ids包含原结论与动作的来源并去重;动作编号仅在本轮内有效。
每项字段:id(本轮编号)、kind(动作类型)、title(标题)、description(具体动作或待回答的问题)、reason(原因)、source_ids(关联政策来源)、citations(source_id/path/quote,逐字原文依据)。source_id 对应已有 sources[].id,可据此打开详情。
优先按推荐顺序提取有原文引文的待确认条件,同维度且条件说明去除空白后相同则合并来源,最多三项;剩余位置提供比较支持内容、查看申报条件、选择事项或整理疑问等阅读动作。不是语义同义去重,也不表示已核实模型条件解释。复用现有分析,不增加模型请求;原有 follow_up_questions 保留兼容,页面不必同时重复展示。
这是建议展示数据,不是自动执行指令,也不触发申请或补问中断。F057已支持同thread追问承接,无需每轮重复全部原问题;“是/否”仍需根据前文确定所指条件,有歧义时澄清,不能直接视为已完成资格更新。继续咨询会重新检索分析,不是同一候选增量重算。仓库不包含外部前端,本次仅完成后端、CLI和本地HTML。
看不懂英文key或value时,先查 字段与取值中文对照表:逐层说明字段中文名称、状态/类型/原因的含义,以及前端该展示哪些内容。
服务名称:青浦区营商助手。本页最初建立于F026–F028,已随当前接口更新至F118;下方示例以合成数据说明字段,具体时序以本页当前事件总览和正文流式协议为准。启动与部署配置见第四步服务说明。
一次请求返回一串SSE事件,不是一个普通JSON响应。 所有事件使用相同外层结构;普通聊天返回文字,政策与具体需求还会返回来源、卡片、综合说明。本文政策和企业名称均为合成示例,不代表存在对应政策或用户具备资格。标注“片段”的示例仅展示部分字段。
| 项目 | 说明 |
|---|---|
| 方法 / 路径 | POST /api/chat |
| 地址 | http://<API_HOST>:<API_PORT>/api/chat;客户端使用实际服务IP/域名,不使用监听地址0.0.0.0 |
| 请求类型 | Content-Type: application/json |
| 建议响应类型 | Accept: text/event-stream(当前不强制校验) |
| 成功响应 | HTTP 200,Content-Type: text/event-stream; charset=utf-8 |
| 请求追踪 | 应用处理的成功/拒绝响应增加 X-Request-ID,与服务端日志及成功SSE的request_id一致 |
| 默认配置 | 本机127.0.0.1:8000,监听地址和端口由环境配置控制 |
{
"thread_id": "window-20260914-001",
"question": "我想开一家小店,但启动资金不够,有什么办法?"
}
| 参数 | 类型 | 必填 | 约束与含义 |
|---|---|---|---|
| thread_id | string | 是 | 窗口标识,1–128字符,仅ASCII字母、数字、_、- |
| question | string | 是 | 本轮输入,不能为空或全空白,最多8000字符 |
| pictures | string[] | 否 | 图片下载链接数组,默认[];与files合计最多8个 |
| files | string[] | 否 | Excel/DOCX/文字PDF下载链接数组,默认[] |
只接受上表四个字段,多余字段也返回422。请求体最多65536字节,读取请求体超时15秒。新窗口可生成 crypto.randomUUID();同一窗口复用ID。未存在或Redis已过期的ID开始新会话。当前ID不是用户鉴权凭证。附件细节见附件契约。
网络上的一条事件如下,最后一个空行是事件结束标记:
event: progress
data: {"thread_id":"window-20260914-001","request_id":"a78b17a3b38241fa83c8ee91f40ec608","data":{"stage":"retrieve","status":"running","message":"正在检索相关政策和配套服务……"}}
event: 指定事件名称;data: 后面才是可用 JSON.parse() 解析的JSON:
{
"thread_id": "window-20260914-001",
"request_id": "a78b17a3b38241fa83c8ee91f40ec608",
"data": {
"stage": "retrieve",
"status": "running",
"message": "正在检索相关政策和配套服务……"
}
}
| 外层字段 | 类型 | 说明 |
|---|---|---|
| thread_id | string | 本轮所属窗口,等于请求值 |
| request_id | string | 服务端为本次HTTP请求生成的32位十六进制ID;同一流内保持一致,下一次请求会改变 |
| data | object | 事件业务内容,由event名称决定 |
事件名称不在JSON对象中,没有 type、event 或 code=200 这类统一业务字段。除完整网络示例外,下文各事件的JSON示例都只展示这个内层 data对象。
一个网络数据块可能包含半条事件或多条事件,中文UTF-8字符也可能跨块;不可对每次 reader.read() 的结果直接执行 JSON.parse()。
| event | 主要data字段 | 前端用途 |
|---|---|---|
| accepted | message | 立即显示“已收到问题” |
| progress | stage、status、message | 更新当前处理阶段 |
| heartbeat | status、message、elapsed_seconds | 等待期间更新已耗时 |
| answer_start / answer_delta | stream_id、target、sequence及增量text | 创建正文块并追加临时内容 |
| answer_end / answer_abort | operation及最终text或撤回原因 | 替换最终正文或丢弃临时正文 |
| attachments | items | 返回本轮附件逐项处理状态 |
| answer | text | 普通对话正文、补问或不与总结重复的独立提示;推荐时可能省略 |
| source | id、title、full_record等 | 保存完整来源,供引用详情查看 |
| item | source_id、card、answer、conditions等 | 渲染单张政策/服务推荐卡片 |
| summary | text、source_ids、status、notices | 显示末尾综合说明 |
| interrupt | kind、question、input_help等 | 提示用户补充公司信息或确认候选 |
| result | response、attachments、cipa、recommendation、company_info、errors | 当前轮次的完整最终快照 |
| done | status | 本次流正常结束或等待输入 |
| error | code,可选message | 本次流异常结束 |
正常顺序(…仅表示零个或多个事件,不是协议字符):
普通对话:accepted → progress… → [answer_start → answer_delta… → answer_end] → answer → result → done
政策/需求:accepted → progress… → source… → item… → [answer_start → answer_delta… → answer_end] → summary → result → done
公司补问:accepted → progress… → interrupt → result → done(needs_input)
流中失败:accepted → 已产生的事件… → error
F042:后端省略与summary相同或已包含在其中的answer正文,前端无需判断二者是否重复。缺少总结、独立备用结论或部分失败提示仍可在source前发送answer。summary为空时不发送summary事件。result仍是完整快照,不作为新的正文追加。
耗时期间可穿插heartbeat,失败可能发生在任一阶段。不保证有source/item;不保证每次请求都经过所有progress阶段。error之后不保证有result或done。
这是阶段、正文增量与最终结果的事件流。临时answer_delta在模型公开正文生成时到达,最终引用、链接与图片绑定可能修正正文;始终以answer_end.text替换临时块。source/item在推荐卡片完成核验后可先于综合正文发送,summary/result用于最终校准,不能重复追加。完整规则见正文流式协议。
{"message":"已收到您的问题,正在处理……"}
表示已接纳请求,不表示模型调用或业务处理成功。
{"stage":"retrieve","status":"running","message":"正在检索相关政策和配套服务……"}
| status | 含义 |
|---|---|
| running | 阶段开始,先通知再执行耗时节点 |
| completed | 该阶段执行结束;不等于政策符合或所有依赖成功 |
| waiting_input | 需要用户输入,随后有interrupt |
| failed | 节点抛出异常,随后终止错误;已被业务捕获的失败仍可能表现为completed并在结果中说明 |
| stage | 阶段 |
|---|---|
| session | 读取会话 |
| prepare | 整理问题 |
| analyze | LLM需求识别;普通对话回复也在这次调用生成 |
| direct | 输出普通对话答复 |
| clarify | 准备公司信息补问 |
| search | 查询公司候选 |
| confirm | 整理公司候选供用户确认 |
| basic | 获取已确认公司的工商信息 |
| honors | 查询荣誉与资质 |
| handoff | 整理需求与已有信息 |
| plan | 规划政策检索方向 |
| retrieve | 检索相关政策与服务 |
| recommend | 原文分析、条件比较和回答整理 |
前端优先直接展示message。相同阶段可能因恢复或重新查询再次出现,不能将stage当作全会话唯一事件ID。不提供百分比或预计剩余时间。
{"status":"processing","message":"问题仍在处理中,请稍候……","elapsed_seconds":20}
无可发送结果且任务仍执行时按配置间隔发送,默认约10秒;不是严格定时器。elapsed_seconds是本次请求累计耗时的整数秒,不是当前节点耗时,也不是剩余时间。收到done/error后停止等待动画。
F034仅三类:闲聊smalltalk、政策了解policy_overview、具体需求specific_need。闲聊含问候、身份、能力介绍,由LLM依据现有角色信息自主回答;例如“你能干嘛”。政策了解检索六库含QA;具体需求按需画像、拆解、检索和适用性分析。
answer.data:
{"text":"辛苦了,先歇一歇,喝点水,给自己留一点放松的时间。"}
result.data:
{
"response": "辛苦了,先歇一歇,喝点水,给自己留一点放松的时间。",
"recommendation": {},
"company_info": {},
"errors": []
}
done.data:
{"status":"completed"}
answer.text和result.response是同一回复,后者不要再追加一次。纯闲聊没有item/source/summary,其内部smalltalk分类不单独暴露。其他咨询按知识库结果处理,可能没有item但有answer/source/summary,不能因卡片为空隐藏答复。
非闲聊统一走检索。recommendation新增knowledge_answers列表,每项包含source_id、title、answer、citations(path/quote)与exact_qa。同题QA保留原答案,summary.status=exact_qa;同题答案冲突为qa_conflict并并列原文;非同题有引用答复为knowledge_answers。summary新增可选citations,每项多带source_id,关联source.full_record的具体字段。
没有卡片时知识答复通过summary.text发送;后端不再同时发送相同answer。overview和result.response仍保留完整快照字段。资料依据明确标注资料名称与逐字原文;正文已经是原答案时说明其原文身份,不再复制一遍。sources提供完整原记录,原始链接缺失也不丢弃答复。不提供无依据的常识补答;无依据为no_evidence,检索/分析失败为unavailable。summary.notices及complete继续反映部分失败。旧no_recommendations仍是底层卡片摘要状态,不能据此认定没有知识答案。
模型调用或生成格式失败时,可能仍收到固定兜底文字、result及done=completed。应检查result.errors,例如 intent_analysis_failed 或 direct_response_unavailable,不能只凭done判断内容生成成功。
两类共用推荐数据结构,区别如下:
| 内容 | 了解政策 | 具体需求 |
|---|---|---|
| 示例 | “有哪些创业扶持政策?” | “我想开店但资金不足” |
| recommendation.conversation_kind | policy_overview | specific_need |
| audience | general | individual或enterprise |
| 卡片顺序 | 保留原检索顺序 | 按需求与主体依据优先级排序 |
| eligibility | not_evaluated | 当前入选条目通常为待确认 |
| conditions | 通常为空,不做用户资格判断 | 地区、主体、行业、时间等条件核验 |
| follow_up_questions | 空数组 | 需要确认的关键条件,最多5条 |
| 公司确认 | 不需要 | 仅在当前需求需要企业事实时触发 |
卡片正文在item.answer及item.card,完整结论在summary.text。 与总结重叠的answer由后端省略,不能只显示answer。
以下为“成功检索但没有相关依据”的合成示例;有推荐时items/sources用后续小节的对象填充:
{
"response": "当前知识库未找到足够相关的原文依据,不能据此认定不存在相关政策。请补充具体需求。",
"attachments": [],
"cipa": false,
"company_info": {},
"recommendation": {
"overview": "当前知识库未找到足够相关的原文依据,不能据此认定不存在相关政策。请补充具体需求。",
"conversation_kind": "policy_overview",
"audience": "general",
"items": [],
"sources": [],
"follow_up_questions": [],
"summary": {
"text": "本轮没有筛选出可展示的具体推荐。可补充希望解决的事项,例如融资、设备更新或人才招聘,以便进一步查找。",
"source_ids": [],
"status": "no_recommendations",
"notices": []
},
"excluded_items": [],
"presentation": {"order":["items","summary"],"sorted_by":"subject_policy_evidence"},
"retrieval_analysis_complete": true,
"complete": true,
"company_context": {"profile_verified":false,"honors_complete":null,"errors":[]},
"analysis_errors": [],
"retrieval": {
"queries": ["合成主题查询"],
"failed_databases": [],
"failed_queries": [],
"content_failures": [],
"complete": true,
"snapshot": "0000000000000000000000000000000000000000000000000000000000000000",
"searched_types": ["policy","finance","qa","article","service_guide","service_catalog"],
"candidate_limit": 12
},
"search_plan": {"needs":[],"queries":[],"error":null}
},
"errors": []
}
这里的snapshot为占位值;searched_types实际为当前检索类型列表,不应据本例写死。retrieval为后端诊断数据,降级时部分键可能不存在。示例中的推荐子字段说明形状,不保证每一种路径都返回相同子字段。
| 字段(相对recommendation) | 类型 | 说明 |
|---|---|---|
| overview | string | 与result.response一致的概述;流式answer可能省略重叠正文或仅发送独立提示 |
| items | array | 已筛选并排序的展示条目,不额外限制6条;当前检索仍有候选预算 |
| sources | array | 完整来源,不一定与items一一对应;可能含仅供参考或分析未完成的来源 |
| summary | object | 综合说明;独立summary事件与这里相同 |
| follow_up_questions | string[] | 资格待确认问题列表,不是LangGraph中断 |
| excluded_items | array | 未入选条目的source_id与reason,适合详情或诊断 |
| presentation | object | 建议先显示items再summary;实际顺序以items数组/priority.rank为准 |
| retrieval_analysis_complete | boolean | 本轮有限候选检索和逐项分析是否完整;不表示总体召回充分 |
| complete | boolean | 在上项基础上考虑必要企业信息完整性等;不表示获批,且不包含所有降级状态 |
| company_context | object | profile_verified、honors_complete和errors;不是完整企业画像 |
| analysis_errors | array | 各候选分析错误,通常为record_id/code |
| retrieval | object | 查询、失败库/查询/内容、快照等诊断;无候选全文数组 |
| search_plan | object | needs、queries、error;needs每项有need/evidence/query,均为检索假设 |
result.errors只包含会话/图层错误,不能替代recommendation.analysis_errors、retrieval、summary.status/error等字段。
下面是政策介绍模式的合成item.data,展示完整顶层字段:
{
"source_id": "k_000000000000000000000001",
"title": "合成创业服务示例",
"card": {
"kind": "service",
"name": {"text":"合成创业服务示例","citations":[{"path":"/title","quote":"合成创业服务示例"}]},
"department": null,
"support_objects": {"text":"拟创业人员","citations":[{"path":"/raw_record/content","quote":"面向拟创业人员"}]},
"support_methods_standards": {"text":"提供创业咨询","citations":[{"path":"/raw_record/content","quote":"提供创业咨询"}]},
"application_conditions": null,
"match_reason": {
"text": "服务内容与咨询的创业主题相关。",
"citations": [{"path":"/raw_record/content","quote":"提供创业咨询"}],
"subject_policy_comparisons": []
}
},
"match_basis": [],
"match_reason": "服务内容与咨询的创业主题相关。",
"answer": "这项服务面向拟创业人员,提供创业咨询。",
"citations": [{"path":"/raw_record/content","quote":"面向拟创业人员,提供创业咨询。"}],
"conditions": [],
"eligibility": "not_evaluated",
"recommendation_status": "相关政策与服务介绍",
"priority": {"rank":1,"basis":"原检索顺序"}
}
| card字段 | 展示内容 |
|---|---|
| kind | 新卡片固定policy;历史结果可能包含financial_product / service |
| name | 完整政策、产品或服务名称,读取name.text |
| department | 主管/实施部门或金融提供机构 |
| support_objects | 支持对象 |
| support_methods_standards | 支持方式及原文明示的标准 |
| application_conditions | 原文申报条件,不等于用户符合条件 |
| match_reason | 相关/匹配理由及主体—政策比较 |
name及四个业务字段采用 {text, citations} 对象,不是字符串;后四项可能为null,可显示“原文未明确”或隐藏。当前入选items要求有有效card,前端仍应容错缺失字段。item.title是来源标题,展示正式名称优先使用card.name.text。
item.match_reason是字符串;card.match_reason是对象,含text、citations、subject_policy_comparisons。item.citations与card各字段citations中的path/quote指向该item.source_id对应的完整来源。path是记录内字段定位,不是HTTP地址。
priority.rank从1开始且数值越小越靠前;它不是分数或获批概率。不满足、明确过期、主体冲突和不适合推荐的条目会被筛出items,可查看excluded_items和sources。reason当前包括expired、ineligible、reference_only、subject_conflict、insufficient_personal_match、duplicate_name。
以下为具体需求item的字段片段(并非完整item),展示数组元素结构:
{
"eligibility": "待确认",
"recommendation_status": "相关线索,资格待核验",
"conditions": [
{
"dimension": "主体",
"status": "待确认",
"quote": "面向拟创业人员",
"user_evidence": "我想开一家小店"
}
],
"match_basis": [
{
"dimension": "需求",
"status": "supports",
"fact_path": "/question",
"fact_quote": "我想开一家小店",
"policy_path": "/raw_record/content",
"policy_quote": "面向拟创业人员,提供创业咨询。",
"explanation": "创业咨询与用户开店准备需求相关。",
"fact_origin": "user",
"provenance": {"type":"user_statement"}
}
]
}
入选item.conditions最多三项,不足不补齐;按关键申报门槛优先,优先使用申报条件引文,同等证据下待核验优先,保留模型重要性顺序。去除重复引文和无原文占位。每项仅dimension、status、quote、user_evidence四键,前端展示三部分:信息方向(dimension · status)、原文要求(quote)、已知信息(user_evidence)。不再返回requirement/question/evidence_path;补问仍使用next_actions/follow_up_questions。user_evidence为空时显示“暂无相关信息,待确认”。quote为完整保留限定的连续原文,不裁剪改写。维度为地区/主体/行业/时间/其他条件,状态为满足/不满足/待确认,模型“满足”仍保守转为“待确认”。完整分析与排除依据保留在candidate_diagnostics/excluded_items,不受三项展示上限影响。旧会话结果不回填。
match_basis维度为需求/地区/行业/资质/主体/时间/其他,状态为supports/conflicts/unknown;fact_origin为user/company/honor,provenance按来源可能有api_code、fetched_at、page_index。supports仅表示有关联依据,不表示全部条件满足;不要与conditions的中文状态混用。
follow_up_questions不等于interrupt。 前者是回答内容,通常仍done=completed;目前再输入答案会开始一个新问题,并未实现基于旧卡片的增量资格重算。需要补充时前端可让用户同时带上原问题和新条件。
source事件及recommendation.sources中的同一对象结构如下,full_record在此只展示部分字段:
{
"id": "k_000000000000000000000001",
"title": "合成创业服务示例",
"type": "policy",
"source": null,
"full_record": {
"id": "k_000000000000000000000001",
"title": "合成创业服务示例",
"raw_record": {"content":"面向拟创业人员,提供创业咨询。"}
},
"snapshot": "0000000000000000000000000000000000000000000000000000000000000000",
"analysis_complete": true,
"detail_anchor": "source-k_000000000000000000000001"
}
实际full_record保留入库的完整原始字段,各知识类型结构不同,不能写死只有raw_record.content。source是原始来源对象或null;实际URL、文件等定位信息应按该对象展示,无URL时不要自行拼接地址。
source.id与item.source_id关联。detail_anchor是建议使用的页面锚点,不是后端详情接口,/api/chat也不会生成CLI的本地HTML报告。前端可以把full_record放入可展开来源详情,并按path/quote显示引文。snapshot为知识快照标识,不代表政策生效日期。
{
"text": "本轮服务可供筹备创业时进一步了解,具体办理条件可查看原文。",
"source_ids": ["k_000000000000000000000001"],
"status": "generated",
"notices": []
}
status为generated(模型生成)、fallback(生成失败使用备用说明)或no_recommendations(没有入选推荐)。fallback时可能有 error: "summary_generation_failed";notices包含本轮不完整或同名来源处理等提示。summary.source_ids可用于跳转来源。summary降级并不一定使recommendation.complete=false,需独立检查。
interrupt.data示例:
{
"kind": "company_need",
"question": "本次是否需要结合具体公司情况?如需要,请补充公司名称或信用代码。",
"schema": {"needs_company":"boolean","company_hint":"string"},
"input_help": "输入公司名称或信用代码;不需要则输入“不需要”。"
}
随后仍有result和 done.data={"status":"needs_input"},result.response可能为空。前端应展示interrupt.question,不能把空response当作失败。
下一次POST仍只传两个字段:
{"thread_id":"window-20260914-001","question":"合成示例有限公司"}
无需公司信息则question填“不需要”“无需公司信息”或 /skip。schema是内部补问说明,不要将needs_company/company_hint作为额外HTTP参数提交。
以下interrupt.data为部分字段示例:
{
"kind": "company_selection",
"question": "请选择您所指的公司;也可以补充名称重新检索或取消。",
"result": {
"candidates": [
{"KeyNo":"synthetic-company-key","Name":"合成示例有限公司","CreditCode":null,"Address":null,"Status":null}
],
"may_have_more": false
},
"page": 1,
"input_help": "输入候选序号确认,或输入新关键词;支持/next、/retry、/cancel。"
}
实际还包含actions等信息;候选可能有StartDate、OperName、No,缺失值为null。result.source可携带来源与获取时间,查询失败时result.error为错误码且candidates可能为空。空候选与查询失败需分别展示。
| 用户操作 | 下一次question |
|---|---|
| 选择显示的第1家公司 | "1",从1开始;不要重排候选后仍按原序号提交 |
| 换关键词 | 新名称或代码 |
| 下一页 | /next,仅may_have_more=true有效 |
| 查询失败重试 | /retry |
| 取消公司查询 | /cancel,继续以现有信息给出一般线索,不是取消HTTP |
F038:question仍必须是字符串。同一个thread_id下,除序号外,也支持当前候选的准确全名、KeyNo、信用代码,或 JSON.stringify(candidate) 得到的JSON字符串。推荐前端直接使用 question: selectedCompany.KeyNo,避免展示顺序变化。也支持 JSON.stringify({action: "select", key_no: selectedCompany.KeyNo})。不要把对象直接赋给question。
后端只匹配该会话当前候选,JSON中的身份字段须一致且匹配唯一公司,CreditCode为null允许忽略;额外资料不会用于画像。重名或无效JSON选择保留确认状态,不重复搜索;普通新关键词仍用于重新检索。确认成功后恢复原咨询问题,继续工商、荣誉与政策检索,不将公司信息当成新的政策问题。存在补问时下一次输入用于回答补问,不能同时作为新咨询;要另问可换thread_id。
也兼容前端将候选显示字段用空白拼接,例如 "合成示例有限公司 SYNTHETIC-CREDIT 存续 合成人员"。整行每一项必须属于同一个当前候选,并包含全名、KeyNo或信用代码之一且唯一匹配;仅经营状态/法人、夹杂其他公司的代码或额外指令不会确认。无需为了这种已有显示格式改前端;新接入仍推荐直接传KeyNo字符串。
{"error":"thread_busy"}
这不是SSE,也不带统一thread_id/request_id封装;可从响应头X-Request-ID取得日志追踪ID。由代理或Uvicorn在进入应用前返回的错误不保证有该响应头。
| HTTP状态 | error | 说明 |
|---|---|---|
| 415 | application_json_required | Content-Type不正确 |
| 422 | invalid_request | JSON或thread_id/question/pictures/files字段不符合约束 |
| 413 | request_too_large | 超过64KiB |
| 408 | request_timeout | 请求体读取超时 |
| 409 | thread_busy | 同窗口的上一请求还在执行 |
| 429 | server_busy | 问答并发容量已满或正在关闭 |
| 503 | service_unavailable | 无法提交后台任务 |
应用的409/429/503分支附 Retry-After: 2,只是建议重试间隔,不保证2秒后完成。Uvicorn、代理或网关也可能返回503/其它错误及纯文本,前端不能假设每个非200响应都有JSON。
event: error
data: {"thread_id":"window-20260914-001","request_id":"a78b17a3b38241fa83c8ee91f40ec608","data":{"code":"stream_timeout"}}
| code | 说明 |
|---|---|
| processing_failed | 本轮处理抛错,有通用message;不能据此认定没有相关政策 |
| stream_timeout | 超过流持续时长上限,可能只有code,没有message |
| unfinished_turn | 上轮有未完成的非补问节点;同ID输入/retry恢复,或换ID提出新问题 |
此时HTTP可能仍为200。error是终止事件,之后不保证有done。未收到done/error就断开,前端显示连接中断,不能假装回答已完成;不支持Last-Event-ID重放或按事件断点续传。
items=[]、complete=true:可能没有对应依据,也可能全部条目被筛除;结合overview、sources和excluded_items解释,不说“政策不存在”。complete=false或analysis_errors非空:存在检索/分析/必要企业信息等缺口,不是正常无结果。done.status=completed只表示本轮流程结束,不能代替这些业务判断。满足条款、推荐排序、完整检索均不等于获批。
可将progress/heartbeat放在独立状态栏;answer为正文或开场,item为卡片,summary为结尾。将source按id缓存用于引用详情。result是最终快照:可以用它替换之前拼装的数据,不要把它再次追加成第二份回答/卡片。
正文可能包含换行或Markdown,但没有单独format字段;纯文本安全展示即可,使用Markdown渲染时关闭或清理原始HTML。字段null不应显示成“null”,空数组不表示错误。不要将thread_id当作所有请求的唯一ID,回调时用request_id区分旧流与新流。
原生EventSource不能发送此JSON POST,可使用以下fetch解析器。它处理网络分块、UTF-8跨块、LF/CRLF分隔及非JSON HTTP错误;回调接收事件名和完整外层对象:
async function chat(threadId, question, onEvent, signal) {
const response = await fetch('/api/chat', {
method: 'POST',
headers: {'Content-Type': 'application/json', 'Accept': 'text/event-stream'},
body: JSON.stringify({thread_id: threadId, question}),
signal
});
if (!response.ok) {
let code = `http_${response.status}`;
try { code = (await response.json()).error || code; } catch {}
throw new Error(code);
}
if (!response.headers.get('content-type')?.includes('text/event-stream')) {
throw new Error('unexpected_content_type');
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '', terminal = false;
try {
while (true) {
const {value, done} = await reader.read();
buffer += done ? decoder.decode() : decoder.decode(value, {stream: true});
let boundary;
while ((boundary = /\r?\n\r?\n/.exec(buffer)) !== null) {
const block = buffer.slice(0, boundary.index);
buffer = buffer.slice(boundary.index + boundary[0].length);
const lines = block.split(/\r?\n/);
const event = lines.find(line => line.startsWith('event:'))?.slice(6).trim();
const data = lines.filter(line => line.startsWith('data:'))
.map(line => line.slice(5).replace(/^ /, '')).join('\n');
if (!event || !data) continue;
const payload = JSON.parse(data);
onEvent(event, payload);
if (event === 'done' || event === 'error') terminal = true;
}
if (done) break;
}
if (!terminal) throw new Error('stream_disconnected');
} finally {
try { await reader.cancel(); } finally { reader.releaseLock(); }
}
}
onEvent须处理error事件;函数正常解析到error不自动抛出服务错误。AbortController可以中止前端连接,但后台已发出的同步调用不能强制取消,会话锁保留到执行线程真正结束,立即重发可能409。新问题不要无条件自动重试,以免重复生成或外部调用。
当前单进程运行,同会话排他;默认同时16个问答,超额拒绝,不保证真实业务QPS。默认流超时600秒。会话保存在Redis,默认写入后15天过期;新问题重置本轮主体,未实现普通聊天历史理解。ID不存在/过期不会返回404,而是新建状态。
尚未实现跨进程会话锁、用户登录/归属校验、跨域CORS、历史列表或删除接口;前端通常通过同源代理接入。反向代理需关闭响应缓冲并配置合理超时。本接口没有新增天气、实时新闻或办理进度查询能力。
非同题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合法和引文逐字存在不保证归纳语义完全正确。
最终正文短结论开场,简单问题可无标题;通常1–2个三级短标题、最多3个,步骤编号、材料/条件列表,标题和列表前后空行,局部加粗。不强凑栏目、重复来源或泛化结尾。下一步建议保留既有三项结构,正文紧凑显示;必要补问保留理由,通用理由仅在next_actions.reason保留。旧示例中每项后另起一段通用理由的展示方式已替代。来源、同题QA原文及接口字段不变;模型仍可能少量重复,外部前端视觉效果未验收。
按用户最新要求,最终统一回答、中间证据笔记和政策综合说明不再用字符数拒绝,也不按长度额外重试或截断。原600/1800/2000字说明作废;提示词仅要求精简、美观、去重并保留关键条件。summary.diagnostics不再产生text_limit,output_chars仅作观测。输入上下文预算、模型输出token上限、分批停止条件及来源/结构校验仍保留。此修复针对1046字被错误丢弃的已定位原因,需重启后新请求验证。
F052(2026-09-17):入选政策item.recommendation_status现为最高扶持/支持标准短文案,尽量10字内, 不再作为资格状态展示。原状态文案移到eligibility_status;eligibility和conditions不变。 新增support_highlight={text,citations}用于短文案来源追溯;可继续直接展示recommendation_status, 例如“最高100万元”“最高20万元/年”,未明确金额时为支持方式或详情提示。不可将金额标签解读为已符合资格。
F050(2026-09-17):企业地区差异按拟在青浦发展场景待核验,相关政策不单因当前外地地址被剔除。 原follow_up_questions和next_actions均在截取数量前优先地区补问,summary.text下一步建议同步。 相关item新增regional_context=qingpu_development,其eligibility为待确认(其他明确不满足仍排除), recommendation_status和summary突出落地后的适用前提。分公司/迁址不是已符合资格的承诺。
最终 result.data.recommendation.candidate_diagnostics 保存全部召回候选的处理结果和
通过校验的逐块分析依据;excluded_items 的卡片筛选排除项新增具体条件、用户证据、
原文引用和匹配依据。详细字段见 第三步F049。这些是诊断字段,
不要求前端新增正文或卡片展示;原 source_id/reason、items、summary字段兼容。
新请求随会话检查点保存,旧请求不回填;终端只输出 candidate_outcome_counts 计数。
2026-09-18字段更正:对外result.data只返回company_info,不再返回compang_info,前端需同步。内部图状态/Redis保留旧键compang_info,接口读取后映射为company_info,兼容已有检查点且无批量迁移。历史已保存的问答结果不回填。未查询时仍为{},company/profile/honors内部结构不变。