main_fan 在我们自己的框架内执行,陕西局网关负责对外管理和转发。默认联合研判同矿井、同组的两台主通风机,比较检测报告参数、实测性能数据,以及有真实时序输入时的切换前后稳定风量和风压。
业务 Skill 为 skills/main-fan-equivalent-capability-assessment/SKILL.md。当前模式是沙箱自主探索:Agent 自行编写文档解析、取证、计算、图表和报告生成代码,在会话沙箱中执行,根据真实输出修改方法。原七阶段、文档识别器、事实登记器和独立计算器不在默认工具集中;旧服务仅用于显式兼容脚本。
当前仅注册四个入口:
| 工具 | 职责 |
|---|---|
prepare_main_fan_task |
绑定身份,导出原始输入、规则和交付 schema |
fetch_main_fan_data |
通过宿主网关取得原件、设备与运行记录 |
run_python |
隔离执行 Agent 自己编写的代码,保存真实输出和执行记录 |
submit_main_fan_report |
核验交付文件与执行记录、映射平台格式并归档 |
文档文本提取、页面渲染和字段整理使用 Agent 自编 Python;扫描件由它渲染 PNG 后通过通用 read_file 看图。中间事实结构由 Agent 自行设计,不再登记到固定 DocumentFacts。标准库、numpy、pypdfium2、Pillow 和 cv2 已可使用;沙箱不联网、不注入服务端凭证、不运行时安装依赖。业务要求、单位和阈值写在 Skill 与本轮冻结的 rules.json。
macOS 使用 sandbox-exec,Linux 需要 bubblewrap;缺少沙箱时报不可执行,不回退为宿主裸执行。默认单次最长120秒、单会话最多40次。配置项为 AGENT_PYTHON_MAX_SECONDS、AGENT_PYTHON_MEMORY_MB(仅Linux地址空间)、AGENT_PYTHON_MAX_RUNS。
Agent 用代码生成 Markdown、AgentAssessment JSON 及需要的附件,声明 output_paths 并带 workflow_id 执行。提交时必须关联本轮成功 run_id,报告、JSON、附件的哈希必须仍与声明输出一致。宿主只核验身份、原件与可信输入指纹、来源归属、文件格式及执行记录,不重新 OCR、不复算窗口或核心指标、不改写结论和正文。业务结论和平台摘要来自 Agent 的 JSON;算法与文字正确性由 Agent 按 Skill 核对,执行成功本身不证明结论正确。
原始输入、规则版本、实际操作和最终结果保存在 main_fan_workflows、main_fan_analyses。派生文件在会话 /workspace/,宿主另存受保护的代码快照和执行凭据。工作台显示实际操作,不预设七阶段;探索步骤预算默认480,由 AGENT_EXPLORATION_RECURSION_LIMIT 控制。详细交付格式见 Skill 下的 references/workbench.md。
563 项离线回归通过,包含实际 macOS 沙箱中的 PDF 渲染、库加载、文件/网络隔离、执行失败反馈、输出哈希、来源归属,以及真实 Agent 图的写代码/执行/提交与协调委派。网关取数连接保留,默认测试 API 使用完整 Agent。
真实 qwen3.5-35b-a3b 扫描件实测中,Agent 自行渲染并查看原页、编写解析/切换分析/报告脚本,得到合成样例的6分钟切换间隔、3800→3610 m³/min稳定风量与5%差异。测试程序随后直接提交其未修改的脚本输出,宿主归档及平台映射通过;这一步不是模型自行完成提交。
最后模型调用被提供方 429 insufficient_quota / Allocated quota exceeded 中断,文本PDF最终用例与扫描PDF的完整自动提交尚未完成验收。扫描件报告仍发现电动机型号字段吞入下一行、Measured误标为折算两处质量问题;已补强Skill自检,因配额不足未复测。不得将上述记录表述为真实业务准确性已经验收。
机器可读记录位于 data/main_fan_live/20261019_sandbox_verification.json,含测试范围、已验证指标、已知问题及恢复配额后的复测命令。测试使用独立SQLite和checkpoint、合成PDF与时序,未连接真实取数网关或推送正式结果。
最终答复是主通风机与备用风机一致性整体报告,按实际数据动态选择基础参数、性能数据、切换工况和已有资料差异章节。没有数据的项目不进入正文,不列缺件清单,不添加“(需复核)”标签。两机参数来自各自报告,额定功率的组合表达式由 Agent 编写代码解析;性能差异在共同实测风量区间内插值,禁止外推。角度未知时仅输出同频报告数据差异,不判定同角度曲线等价。
综合结论只采用基础参数一致、切换间隔≤10分钟、切换前后稳定风量差≤10%三项,全部通过即为 NORMAL。一般明确偏差为 WARNING;风量差达到15%且对应数据有效为 ABNORMAL;关键比较数据无法形成有效对照时为 UNDETERMINED。严重间隔及严重参数条件尚未设定。普通OCR说明、未知叶片角度/台账状态、补充性能曲线或风压差异不额外否决综合结论,表图差异单列说明。阈值来自 examples/main_fan/equivalence_rules.json,按版本保存到每次工作流。
报告使用 m³/min、Pa、kW 和 Hz,保持原始值及转换公式;Agent 根据有效数据决定是否绘制双机性能图、切换图或比较表,图表由其代码或实际计算结果生成。切换分析只使用经确认归属、有明确来源的时序数据和整台风机状态/切换记录;单级开停截图、单点风速不作切换窗口或风量依据。模拟数据在报告与来源栏明确标注。只比较风量时,报告不把风压也写成已判定通过。
规则和阈值配置位于 examples/main_fan/equivalence_rules.json,可通过 MAIN_FAN_RULES_FILE 替换。初始配置来自需求中的建议值,不表述为法规限值。执行状态与综合判定状态分开:部分项目有结果时报告只陈述这些结果,Agent 应在交付 JSON 中明确未评估项目和证据限制。
自主模式的提取事实与计算细节保存在 assessment.agent_result.details,来源引用在 assessment.evidence,代码执行记录在 assessment.exploration;不再由固定算法生成 analysis。网页工具详情默认折叠,文件来源保留显示;最终正文恢复 Agent 实际提交的原件。
单机报告版本的历史实测记录位于 data/main_fan_live/20261014_report_style_5eda22f9/;该版本当时只分析1号,当前默认流程已改为双机。显式设置 paired_assessment=false 仅用于旧单机接口兼容。
双机版本网页实测记录:data/main_fan_live/20261014_pair_verified_20a71196/。实际请求为“审核众源煤业主通风机及备用是否一致”,从原件模拟网关下载26页PDF和两张系统截图,16次实际视觉模型调用(含一次图注分类回读),未使用旧缓存或人工转录。两台各44行数据,88行公式检查;30、40、50Hz均形成共同风量区间的数据比较。截图识别出另一矿井的设备与风速,未混入本矿井报告。正文约2500字符(含Markdown表格,不计SVG编码),只含有数据的参数、性能和实际资料差异章节。
文档识别对风量原文单位、轴功率含义和表图工况分类进行一致性检查,疑似记录自动放大回读原页;仍缺明确单位或轴功率依据的行退出计算,原值不按公式反算修正。缓存升级至v4,旧识别记录不自动复用。
下列原件核验和历史实测基于此前固定服务,不代表本次自主探索改造已完成模型联调或测试。
当前目录有一份 26 页扫描 PDF,风机数据截图/ 子目录内有两张裁切截图。原件模拟网关递归建立文件索引。PDF 包含陕西众源煤业集团有限公司的 1、2 号主通风机报告,编号分别以 0003、0004 结尾;检验日期为 2022-03-18、2022-03-17,报告所载建议下次日期为 2025-03-17、2025-03-16。
截图属于神木市瓷窑塔矿业有限公司,不能与上述报告合并。只转录完整可见行:设备 00000540 为“地面主通二号二级/开”,00000541、00000542 为“一号一级/停”“一号二级/停”;开停截图未提供采集时间。测点 2000000TJFJ010038 为“一号风机风速”,值 0 m/s、状态正常,时间 2026-10-13 10:13:00;下方温度行不完整,未转录。
reviewed_sample.json 是旧离线联调夹具,保存人工核验转录、原文件 SHA256 和 PDF 物理页码;生产自动识别和原件实测不加载它。mock-ci、mock-zy 是模拟编码,实际矿井编码未知。
1 号报告物理页 8 的现场运行表工况静压为 523.57 Pa、效率 64.77%;物理页 11 曲线图注为 511.73 Pa、63.30%。自动识别把图注与数据表分开保存,保留两处差异供复核。旧离线夹具只覆盖身份和各 7 行 30 Hz 现场数据。
| 输入 | 实际处理 |
|---|---|
| 矿井编码或名称冲突 | 排除记录;不模糊合并公司名称 |
| 名称、编号、位置线索 | 同矿井风机号形成 candidate;PLC1、一级/二级不作风机号 |
| 人工确认关联 | 须提供 point_code、fan_id、confirmed_by、reason;冲突仍阻断 |
| 重复、断线、缺时、过期、未来时间、未知单位 | 保留发现,排除当前计算 |
| 单点风速 | 不直接换算风量;缺断面与平均风速时说明缺件 |
| “风压”、电输入功率 | 不冒充风机静压增量或轴功率 |
| 当前效率 | 唯一、已确认关联、有效且同步的 Q、静压、轴功率才计算 |
| 历史报告 | 同矿井且对应目标风机时复核同一行,不混用现场和折算值 |
| 建议检验日期已过 | 提示核查更新报告,不直接认定当前不合格或违法 |
| 开停快照 | 不根据单台/单级停机推断全矿停风或备用能力 |
静压效率:eta = Q[m3/s] × p_static[Pa] / (1000 × P_shaft[kW]) × 100%。支持显式 m3/min→m3/s、kPa→Pa、W→kW 换算。不把静压功率/电输入功率误称为风机轴功率效率。
时效默认 600 秒,同步窗口 120 秒,分别配置 MAIN_FAN_FRESHNESS_SECONDS、MAIN_FAN_SYNC_SECONDS;它们是数据筛查参数,不是工程安全限值。无时区时间按 Asia/Shanghai 解释。evaluation_time 可指定回放时刻并保存在输入;默认当前时间。
status=completed 表示初步筛查完成;judgment_scope=preliminary_screening,工程状态保持 review_required 或 insufficient_data,不自动生成红橙黄蓝等级。没有任何本矿井可用资料时为 needs_materials。结果保存 main_fan_analyses,发布时恢复数据库原件;模型不能改写工具数值后推送。队列工具使用服务端输入,不能自行增加人工绑定。
历史规范仅作为原报告事实保留。当前规程基准核对了应急管理部第 17 号令、2026-02-01 施行的《煤矿安全规程》第 177–179 条。连续运转、备用、改造/换叶片后测定、反风能力需要配置、试验或过程记录;样例不足以核验,不用历史条款数值做当前自动执法判定。规则核对日期:2026-10-14。
.venv/bin/python scripts/run_main_fan_document.py \
--document '/Users/gaoshutao/Project/煤科/陕西局代码/测试数据/通风机性能测定报告.pdf' \
--mine-name '陕西众源煤业集团有限公司' --fan-name '1号通风机' --agent
默认 document_cache_policy=refresh,创建独立 SQLite 与 checkpoint,调用实际 main_fan LangGraph 和业务工具。矿井名称只用于任务身份筛查,不作为识别模型的预填答案。不导入人工转录,不使用已有识别缓存,不调用真实陕西局网关。原件复制到本会话附件目录,并验证运行前后的 SHA256 一致。
结果保存在新的 data/main_fan_live/<id>/result.json。--agent 使用自主模式,Agent 自行选择证据范围,脚本、事实、选页审计及模型原始响应留在本会话 workspace/exploration/<workflow_id>/,受保护的代码快照留在同会话 python_runs/。不加 --agent 才直接调用历史固定服务,其 document/<附件标识>/facts.json、audit.json 和 call-*.json 保存自动提取与逐页调用记录。--output 可指定新目录,已有实测数据库不覆盖。
2026-10-14 在本机配置的 deepseek-flash 上完成真实模型验证:
| 输入与记录目录 | 实际识别 | 业务执行 |
|---|---|---|
原始 通风机性能测定报告.pdf → data/main_fan_live/20261014_scan_verified/ |
26 页全部走视觉、13 次实际识别调用;2 份报告、88 行性能数据、2 条数字图注 | 实际 main_fan 图;目标 1 号风机 44 行公式复核,最大效率偏差 0.0071 个百分点 |
合成带文本层 PDF → data/main_fan_live/20261014_native_verified/ |
1 页走文本、1 次实际识别调用,未发送图片 | 实际 main_fan 图;合成数据复核 60% |
原件 SHA256 为 46eb24ec6c0f23907b4dc6f67af00f7907fa15d7acbf04ce13d142a247cfc92a,扫描识别调用用量合计 76,071 tokens。两种实测均为 cache_used=false、transcript_seed_loaded=false,数据库缓存方法为 automatic_extraction;缓存是在本次完整识别后才写入的。文本 PDF 是独立软件测试输入,不是把原扫描报告转录后冒充可解析 PDF。混合 PDF 另有逐页路由回归测试。
抽查原件物理页 3、8、11、16、21、24 的身份、日期、运行工况和图注。保留 1 号表格 523.57 Pa/64.77% 与图注 511.73 Pa/63.30% 的原件差异;这属于资料复核,不能用历史“合格”结论证明当前设备状态。完整事实未逐字人工验收。全量 381 项测试、结构自检、依赖锁及打包白名单校验通过。
.venv/bin/python scripts/demo_main_fan.py \
--data-dir '/Users/gaoshutao/Project/煤科/陕西局代码/测试数据'
该兼容脚本用两个临时本地端口启动取数网关和独立结果接收平台,在新的 data/main_fan_demo/<id>/ 创建业务 SQLite、checkpoint、接收平台 SQLite 和 result.json,不读取/修改本机 .env。会话附件进入框架 data/workspaces/,不改变原测试目录。脚本显式调用历史固定服务,经持久化队列、HTTP下载和独立结果推送进行离线联调;不调用外部模型或真实陕西局服务,也不验证自主探索能力。
默认三场景:original 原截图与异矿报告,report 原报告历史复核,synthetic 合成量及合成确认(60 m3/s、500 Pa、50 kW→60%)。随后验证本地业务 stop/start,检查网关没有收到注册、上传或结果推送请求。第三种来源标注 synthetic。可用 --scenario original|report|synthetic 单独运行;--output 指定新目录,已有演示库不覆盖。
原 PDF 按真实哈希核验,离线识别用人工转录缓存。这验证业务与计算,不能替代视觉模型识别质量验收。
.venv/bin/python scripts/mock_shaanxi_gateway.py \
--data-dir '/Users/gaoshutao/Project/煤科/陕西局代码/测试数据' --port 8766 --raw-files
默认仅监听 127.0.0.1。--raw-files 按当前测试目录直接建立 PDF/图片原件索引,不加载人工转录 JSON;文档中的事实由业务智能体实际识别。启动脚本另外加载下述两份明确合成的时序JSON及其风机身份,不从人工转录夹具填充报告或监测值。原件变动后需重启网关刷新索引。不加该参数则沿用旧离线夹具。业务配置示例:
SHANXI_GATEWAY_ENABLED=1
SHANXI_GATEWAY_URL=http://127.0.0.1:8766
SHANXI_GATEWAY_TOKEN=mock-internal-token
SHANXI_FILE_BASE_URL=http://127.0.0.1:8766
MAIN_FAN_AGENT_CODE=mock-main-fan
MAIN_FAN_DEVICES_PATH=/mock-platform/main-fan/devices
MAIN_FAN_POINTS_PATH=/mock-platform/main-fan/points
MAIN_FAN_REPORTS_PATH=/mock-platform/main-fan/reports
MAIN_FAN_SERIES_PATH=/mock-platform/main-fan/series
MAIN_FAN_OPERATION_LOG_PATH=/mock-platform/main-fan/states
这些路径、凭证只属于模拟服务。取数身份在网关中预先授权,应用无需运行时注册。真实路径、字段和取数编码需同事提供,没有预设陕西局存在 /mock-platform/ 接口。
结果接收另起 .venv/bin/python scripts/mock_result_platform.py(8767端口),配置 RESULT_PLATFORM_ENABLED/URL/TOKEN 后独立推送。正式结果格式、四种编码及推送查询接口见 独立结果平台。
新增 examples/main_fan/mock_switch_states.json 和 examples/main_fan/mock_airflow_series.json,统一声明 schema_version=1、data_kind=synthetic、矿井身份、时区、采样间隔和 series。每条曲线有 fan_id、samples=[{"observed_at":"带时区时间","value":数值}]。开停曲线是整机级,state_scope=whole_fan,0为停、1为开;风量曲线另有 sensor_id、unit=m3/min 和显式的 mapping_confirmed。两台设备绑定 mock-zy 下的 mock-report-fan-1、mock-report-fan-2。
默认回放2026-10-14 09:20至11:00,每60秒一条,每类数据两台各101点。1号10:00停机,2号10:06启动,双停过渡6分钟。1号切换前风量均值3800 m³/min,2号切换后3610 m³/min,差异5%;停机零值和启动过渡也保留在原始曲线中。
网关代理 /mock-platform/main-fan/states 返回整机状态记录,/mock-platform/main-fan/series 返回两条风量序列;智能体从状态变化识别切换,不使用预写的切换结论。原始JSON可查看 http://127.0.0.1:8766/mock/main-fan/curves/switch-states 和 /mock/main-fan/curves/airflow。更换样例目录使用 --operating-data-dir。
两项规则独立计算:原机停机至另一台启动的非负间隔 ≤10分钟;|切换后稳定均值-切换前稳定均值| / 切换前稳定均值 ×100% ≤10%。等于边界也通过;涨幅、降幅均按绝对差异判断。先启动再停机时另外记录重叠时长,停机等待间隔计0。前窗口取首次切换动作前5分钟之外的30分钟,后窗口取切换完成后5分钟之外的30分钟,默认有效样本完整率≥90%、变异系数≤5%。切换前风量为0不形成比例结论。
整机未知、冲突或连续状态记录缺测超过两个采样间隔时,不跨缺口推断停启时间;未来样本不能补足窗口。没有可比风量时仍能单独保留已证明的切换间隔;只有切换时刻而无停机、启动时刻的旧记录,不自动判定间隔合格。两项通过只表示本次切换与风量规则通过,不替代整体同等能力判识。上述10分钟/10%为本次用户指定业务规则,规则版本随配置归档。
本地网页测试可打开 http://127.0.0.1:8080/,在新会话选择“矿井主通风机研判智能体”,只需发送“审核众源煤业1号主通风机”。无需填写矿井编码、工具名或网关/缓存参数,也无需手动上传:业务工具从模拟网关取得目录和文件鉴权,直连下载原 PDF,实际调用视觉模型重新识别。网页聊天的结果保存在当前应用 SQLite;平台推送另由业务任务 API 或网关事件任务触发。
prepare_main_fan_task 支持目标文字或 {"target":"众源煤业1号主通风机"};业务任务 API 的 input 同样只需一个 target 字段。target 也可以是已配置的风机标识。完整 MainFanInput 协议仍兼容。
{"input":{"target":"众源煤业1号主通风机"},"publish":false}
服务端设置示例:
MAIN_FAN_TARGETS_FILE=examples/main_fan/mock_targets.json
MAIN_FAN_DEFAULT_DOCUMENT_CACHE_POLICY=refresh
目标目录保存矿井名称、经明确配置的别名、矿井编码、风机名称及标识;不包含报告日期、监测数值或人工转录。当前测试目录配置众源煤业 1、2 号风机。自然语言前后缀和“一号/1号/1#”可归一化,但不会模糊搜索公司名称或根据文件内容猜平台编码。未唯一匹配时先询问业务对象,未确定身份前不会取数或分析。
简短请求未带本地材料且网关启用时自动 use_gateway=true,默认刷新原件识别。明确提供的附件和显式 use_gateway/document_cache_policy 会保留;关闭全局网关不会暗中启用 Mock。完整协议输入维持原默认值,队列以服务端已验证输入为准,模型不能通过改写目标或人工绑定改变任务。
测试目标目录明确绑定 http://127.0.0.1:8766;真实环境需配置正式身份目录并更新其网关绑定,不能把 Mock 编码用于真实网关。新增矿井在目录里增加身份与别名即可,不需要修改业务 prompt。地址和凭证仍由服务配置决定,用户一句话不能切换网关环境。
2026-10-14 已在运行中的网页仅发送“审核众源煤业1号主通风机”验证完整链路,无附件、无技术参数:自动网关取数和直连下载,实际识别 26 页、13 次文档模型调用,对目标风机复核 44 行;cache_used=false、transcript_seed_loaded=false。实测记录位于 data/main_fan_live/20261014_short_request/,网页会话为 0a159bbb91dc43c39f9296f35c0fa821。目标文字、单 target 对象及模型偶尔返回的 JSON 字符串都可解析;全量 411 项测试通过。
用网关内部 Bearer 和 X-Agent-Code: mock-main-fan 向 POST /mock/tasks 发送 {"scenario":"original","taskId":"local-001"},产生 main_fan.judgment 事件。须业务端已注册并订阅;单独启动模式使用你配置的真实语言模型,演示脚本才是离线编排器。
管理模拟:GET /openapi/agent/manage?agentCode=mock-main-fan&action=stop&token=mock-platform-manage-token,action 支持 start/stop/restart/status/logs。停止关闭 SSE,重连返回 403;本业务执行和推送暂停,启动后恢复订阅。对方真实网关的指标/日志口径仍按双方约定。
独立 PDFium 进程逐页判别,不按文件名选择识别方式:
| 页面 | 处理 |
|---|---|
| 可读、完整的文本层 | 直接提取文本,由 MAIN_FAN_TEXT_MODEL 整理结构;不发送图片 |
| 空文本、损坏字符、零散水印或大图配少量文字 | 渲染为 PNG,由 MAIN_FAN_VISION_MODEL 读取原页 |
| 曲线图页 | 走视觉;仅录印出的工况数字,不猜曲线像素 |
| 文本与扫描页混合 | 分别按每页路由,合并到同一文档事实 |
默认最多 32 页,扫描页最长边 2200px,截图最长边 1700px;同一路由每批 2 页。文字模型默认沿用主模型,视觉模型必须明确配置且支持图像。以下设置可独立指定模型、接口和凭证;留空的接口/凭证沿用项目设置:
MAIN_FAN_VISION_MODEL=deepseek-flash
MAIN_FAN_TEXT_MODEL=deepseek-flash
MAIN_FAN_VISION_BASE_URL=
MAIN_FAN_VISION_API_KEY=
MAIN_FAN_TEXT_BASE_URL=
MAIN_FAN_TEXT_API_KEY=
MAIN_FAN_DOCUMENT_TIMEOUT=180
MAIN_FAN_DOCUMENT_BATCH_PAGES=2
MAIN_FAN_DOCUMENT_MAX_TOKENS=20000
MAIN_FAN_MAX_DOCUMENT_PAGES=32
MAIN_FAN_ALLOW_MANUAL_CACHE=0
DeepSeek 的文档识别显式关闭思考,使用 JSON 输出模式。视觉与文本分别计入 main_fan_ocr、main_fan_document_text,不作为主回答流输出,也不重复计费;部署时配置对应模型单价,提供方没有 usage 时标记 estimate。
提取结果校验 schema、PDF 物理页、日期标签及单位,按报告编号累积。JSON/schema 结构异常会重新读取同批原页一次,仍失败则报缺件;截断输出直接报错,避免把不完整结果缓存为成功。数据行或图注的数值与其印出的效率相差超过 0.5 个百分点时,扫描页增加原图放大区域,再读一次;公式只触发复读,不反算覆盖数字,仍不一致则保留原值并提示核验。每次复读同样记录实际模型响应与用量。
旧服务缓存版本为 main-fan-facts-v4,支持 document_cache_policy=auto|refresh|off;自主工作台只保留本轮识别,不读写共享缓存。不同页出现真实字段冲突时清除该字段并保留候选值与页码;当前自主模式由 Agent 修改自己的提取代码和派生事实后重新执行,代码快照和交付文件哈希留作追溯。制造年月不能替代检验日期,缺 Q/静压/轴功率的行不进入公式复核。
证据方法区分 text_extraction、model_extraction,保留源文件 SHA256、原文和物理页码。自动识别仍需核对原页,公式正确不证明 OCR 数字正确。业务结果以 SQLite 原件为准,Agent 的代码、派生输出和报告都有各自记录;当前自主模式的平台编码来自 Agent 脚本交付,不由宿主重新计算。
离线调试需要时可以导入已核验的转录:
.venv/bin/python scripts/import_main_fan_facts.py \
--document '/Users/gaoshutao/Project/煤科/陕西局代码/测试数据/通风机性能测定报告.pdf' \
--facts examples/main_fan/reviewed_sample.json
该命令写当前配置的本地库,验证哈希、物理页码和原文,不修改原件。自动识别默认拒绝该缓存;旧 demo_main_fan.py 才显式开启人工缓存。其他人工转录使用 DocumentFacts JSON 和 --sha256 原文档哈希。
JSON 适配在 extensions/main_fan/data_source.py,目前接受 items、data.items 或 data 数组;字段使用业务 schema 的 snake_case/明确声明的 camelCase。真实响应不同需增加明确映射。报告目录只需文件 ID、版本和下载路径,由我们取鉴权、直连下载、存文件和索引;模拟网关拒绝拿内部凭证直接下载。
algorithms/main_fan/:事实 schema、确定性关联/筛查/计算、隔离 PDF 渲染。extensions/main_fan/:工具、网关 JSON 适配、文档提取、结果和提示词。db/main_fan_store.py:文档缓存、分析原件;business_files 存队列下载索引。mock_gateway/main_fan.py:取数鉴权、JSON代理和文件系统;旧协议接口仅保留兼容测试。extensions/result_platform/:独立结果平台的地址、鉴权、回执校验及客户端。mock_result_platform/:独立结果接收服务,SQLite存档、幂等及冲突检测。tests/test_result_platform.py:四种编码契约、实际规则映射、取数/结果解耦、重试、导出及所有权校验。tests/test_main_fan.py:原始数据边界、量纲/身份/时效/同步、真实图、PDF 渲染、原件及模拟网关。tests/test_main_fan_documents.py:文本/扫描/混合路由、真实调用协议、缓存隔离、字段冲突与截断处理;其中 PDF 是合成测试输入,不是原报告转录。运行 .venv/bin/python -m pytest 和隔离存储配置下的 scripts/selfcheck.py,无需真实网关或模型。