# Argo v2.7.3 发布说明 **版本**:2.7.3 **定位**:在 2.7.2 基础上,新增「实时索引」数据源引擎,并把「发布时间维度 + 时间窗过滤」做成 argo 通用能力;同时收编外部索引 CLI 的工程侧形态(结构化输出、声明式接入)。 > **后续更新(2026-08-10)**:本版本号下追加发布「引擎激活 + 体验修复」批次——引擎层 HttpClient 接入、TF-IDF 强语义注入激活 25 个垂直引擎、70 域 TTL 全覆盖、垂直源中英双语覆盖、快讯触发词修复、百科条目页兜底等,详见文末「本轮追加」。 --- ## 本轮追加(2026-08-10:引擎激活 + 体验修复) ### A1. 引擎层 HttpClient 接入:UA 敏感引擎不再超时空转 **以前**:引擎请求走裸 urllib,UA 固定。arxiv 这类对 UA 敏感的源间歇性 SSL 失败,实测 5s 超时后 0 条结果。 **现在**:HTTP/HTML 引擎 GET 请求统一走 `http_client` 层——UA 轮换 + Cookie 积累 + 429/503 Retry-After 尊重 + 指数退避重试 + 重定向跟随(修复了 `follow_redirects` 无效死参数)。实测 arxiv 从「5s 超时空返回」变为「2s 内 10 条有效结果」;devto 等间歇慢源稳定在 1.3-1.6s。 **回退开关**:`ARGO_ENGINE_HTTP_CLIENT=0` 整体回退 urllib(灰度/诊断用)。 ### A2. TF-IDF 强语义注入:25 个垂直引擎真正用起来了 **以前**:marginalia / wiby / searchmysite / open_meteo / usda / gov_policy / cnii / ndl / qiita 等 25 个垂直引擎有 TF-IDF 文档但正则域命中后永远选不中(注入只对 catch-all 域生效),只能 `--engine` 强制指定。 **现在**:TF-IDF 高分推荐(≥0.6)放宽到所有域,注入位置在 primary 扶正之后(串行 early-stop 下真正执行)。实测「独立博客 长尾」→ marginalia(3.7s 4 条)、「营养成分 热量」→ usda、「国务院 政策」→ gov_policy、「日本 学术论文」→ cnii、「天气 气温 预报」→ open_meteo。通用引擎(byted/bocha/octen 等)黑名单跳过,域主源保留备位。 ### A3. env 占位缺失过滤:github 引擎从 401 恢复 **以前**:未配置 `{GITHUB_TOKEN}` 时把字面量 `Authorization: token {GITHUB_TOKEN}` 发给 GitHub → 401,github 引擎永久不可用。 **现在**:env 缺失替换为空 + 过滤空/认证前缀残留头(`token ` / `Bearer ` 后无凭据)。实测 github 无 token 时匿名 API 0.55s 返回 3 条结果;bocha/byted/tavily/zhihu 等 10 个用 env key 的引擎同样受益。 ### A4. 70 域 TTL 全覆盖:实时数据不再缓存 1 小时 **以前**:48/70 个域没有 TTL 映射,全部落到默认 3600s。「今日金价」卡片缓存 1 小时后过期 55 分钟,财联社电报 / 同花顺热点同样。 **现在**:全部域按时效归类——modal_card(油价/金价/车票)/ 快讯 / 天气 900s,行情/宏观 300s,学术稳定型 7200s,百科/法律/地理 86400s。 ### A5. 垂直源中英双语覆盖:worldbank / eurostat 英文查询命中 **以前**:国家映射和指标关键词纯中文。实测「China GDP」「US inflation」「Japan population」全部 0 条。 **现在**:国家映射补英文别名 + 缩写(含 us/uk 等短别名词边界匹配防误伤),指标词补英文(population / unemployment / inflation / gdp growth 等)。实测 China GDP 19.5 万亿美元、Japan population 1.23 亿人、US inflation +2.95% 全部命中。 ### A6. 快讯类引擎触发词放行 + 百科条目页兜底 **以前**:「快讯」「美股」查询被当关键词过滤,快讯标题里没有这两个字 → 全量榜单被滤空返回 0 条;萌娘百科等搜索直接跳转条目页时列表选择器不命中 → 恒空。 **现在**:纯触发词(快讯/美股/资讯等白名单)放行全量榜单,具体主题(美联储/AI)才过滤且拉取量放大 3×;HTML 引擎容器未命中时兜底提取 `` + 正文首段 + canonical URL 返回单条。实测「快讯」3 条、「融资」1 条过滤命中、moegirl 初音未来 / 东方Project 各 1 条。 ### A7. 其余修复 - 熔断 empty 语义:查询无结果不再累计 opens,易空引擎不会被误判为持续故障而静默禁用 - 国际引擎中文查询 URL 编码修复(18 处专用 builder,cnii/ndl/qq_music 等中文查询全部恢复) - open_meteo geocode 加 language=zh:中文地名「北京」从恒空恢复为 2 条 - europeana 禁用(官方 demo key api2demo 已失效 401,路由不再选中空转) - 查询改写去重(「Python async Python 编程语言」残留修复)、research 顶层 query 保持原查询 - 慢源超时收紧(fast/auto 非 deep 6s)、wave-2 并行累计足够即提前终止、自适应 TTL 键匹配修复 - 抓取链升级(crawl/extract 走 fetch_v3 降级链)、fetch_page_v3 raw 模式绕过缓存取完整 HTML - 版本号统一 2.7.3、单一真源文档修正(engines/specs/ 外置目录说明) ### A8. 证据闭环 P0(2026-08-12) **以前**:搜索给「证据候选 + snippet 级快评分」,但 fetch 正文后不回填、无 URL→证据分缓存、无「该核验哪些」的可编程信号。Agent 高后果下结论只能靠纪律,系统不帮它证明,也不度量证明成本。**证据闭环是开环。** **现在**:证据闭环闭环化(新模块 `scripts/evidence_loop.py`): 1. **fetch 证据回填**:`fetch_v3` 成功抓取后同步提取正文级证据分(absorption / quality / word_count / evidence_flags),写 URL→证据分独立缓存(`SearchCache.get/set_evidence`,与 fetch 正文缓存 kind 隔离,互不污染)。 2. **高后果门控**:查询命中高后果域(finance:stock_query/fund_query/macro_data/crypto_search 等;health:medical/chem_search;legal:legal/us_legal/wenshu_query;事实核查与航空气象)时输出 `fetch_required=true`。 3. **可编程核验信号**:每条结果带 `fetch_suggested` / `has_fetched_evidence` / `post_fetch_absorption`;顶层 `evidence_loop` 汇总 `suggested / verified_count / pending_count`。深度研究包输出 `evidence_loop.pending_fetch`(子查询 top1 待核验列表)。 4. **`--verify` 核验模式**(CLI 与 research):对 top-k 未核验结果显式 fetch,回填证据分,输出 `verify.revision_summary`(improved/unchanged/degraded/mean_delta),已核验结果不重复打网(`skipped_cached`)。 **实测闭环**(本机真实搜索「贵州茅台股价」):搜索 → `fetch_required=true`、`suggested=[新浪财经]`;`--verify 1` → fetch 成功(http、content_ok),absorption 0.0→0.42(delta +0.42);二次搜索 → 自动回填 `post_fetch_absorption=0.42`、`verified_count=1`、`pending_count=0`、不再建议核验。**snippet 级分 0 vs 正文级分 0.42 的实测差异,实证了「snippet 评分不可靠、高后果必须 fetch」的假设。** **验证**:新增 `tests/test_evidence_loop.py` 14 项全过(证据提取 / 缓存隔离 / 回填 / 高后果门控 / verify 模式 / fetch_v3 自动写证据缓存);全量回归 790 passed、18 skipped。 --- ## 这次更新有什么 ### 1. 新增实时索引引擎:realtime_index **以前**:搜「刚发布的内容」要靠通用网页引擎碰运气,结果里也没有发布时间这个维度,判断新旧只能点开链接自己看。 **现在**:新增 `realtime_index` 引擎,免 Key 直连,输出结构化结果,每条自带 `published_at` 发布时间,适合「最近几天有什么新东西」这类时效性查询。 **怎么用**:默认不进日常组合,需要时显式指定引擎: ```bash # 用实时索引引擎搜索 python3 scripts/search.py "rust async" --engine realtime_index # 只看最近 7 天 python3 scripts/search.py "rust async" --engine realtime_index --since 7d # 指定绝对日期区间 python3 scripts/search.py "rust async" --engine realtime_index --since 2026-08-01 --until 2026-08-05 ``` ### 4. 抓取合规第一波:尊重限速停止信号 **以前**:目标网站返回 429(限速)/ 503(过载)时,抓取链会把它当成普通失败,继续「换着花样重试」——换 UA、换 TLS 指纹、上浏览器,直到把对方惹毛或自己超时。这是最典型的爬虫行为。 **现在**:429/503 是服务器明确的「请停止」信号,与请求方式无关,继续升级只会放大负载。三处整改: - **按服务器指示等待**:响应带 `Retry-After` 头且等待时间在可接受范围(≤10s)时,等它说的时间再试一次;无头或要等太久,直接放弃不再重试。 - **不再升级重链**:收到 429/503 后,抓取链立即终止,不再换 TLS 指纹、不再走 Wayback、不再启动浏览器。 - **TLS 层不再徒劳轮换**:指纹轮换只针对与指纹相关的拒绝(403 等);429/503 与指纹无关,轮换纯属徒劳。 ### 5. robots.txt 尊重层(合规抓取门禁) **以前**:不管目标网站是否在 robots.txt 里声明「某些路径别抓」,一律照抓。 **现在**:抓取前先查目标域的 robots.txt,明确禁止的路径直接返回「robots.txt 禁止抓取」,不发起请求。三个边界: - **拿不到就放行**:robots.txt 不存在(404)、暂时不可用、或网络异常时,不拦正常抓取——避免因一次抓取失败让整站瘫痪。 - **通配规则匹配**:用 `User-agent: *` 通用规则判定(本技能 UA 轮换,匹配通配规则最保守合规),抓 robots.txt 时自报身份,不用随机 UA。 - **可关闭**:`ARGO_RESPECT_ROBOTS=0` 关闭本层,默认开启。 ### 2. 时间窗过滤成为通用能力 **以前**:想限定「发布时间范围」,没有任何统一入口,每个数据源各写各的。 **现在**:`--since` / `--until` 成为 argo 通用参数(接受 `7d` 相对值或 `2026-08-01` 绝对日期),CLI 与 MCP `argo_search` 都能传;只有声明支持时间窗的引擎才会收到这两个参数,其余引擎不受影响。 缓存也按时间窗隔离:同一句话用不同时间窗搜,不会互相串结果——不会出现「我限定到 8 月 5 号之前,却拿到 8 月 7 号的条目」这类错误。 ### 3. 引擎接入更省事:CLI 桥接零 Python **以前**:接一个新数据源,要么是标准 HTTP API(写 YAML 就行),要么就得写 Python 插件。 **现在**:本机已装的命令行工具,只要输出 YAML/JSON 结构化结果,就能纯声明式接入——`output_format: yaml` 走通用 YAML 解析器(自动认 `results`/`items`/`data`,字段别名 `title|name`、`url|link`、`snippet|description|content`,保留 `published_at`);`filter_args` 声明时间窗参数映射,`--since`/`--until` 来了就自动拼进命令。模板在 `engines/_template_cli.yaml`。 顺带修了一个配置校验的坑:命令写裸名(在 PATH 里)的 CLI 引擎,以前会被误判成「文件不存在」而自动禁用,现在会用 PATH 兜底查找,裸命令和绝对路径都行。 --- ### 6. 新增免 Key 天气引擎 **以前**:问天气要么靠通用网页搜索碰运气,要么接和风天气这类要申请 API Key 的服务,门槛高、Key 也未必有。 **现在**:内置免 Key 天气引擎,直接说「上海天气」就返回当前天气与未来预报(wttr.in 主用、Open-Meteo 兜底,纯标准库实现)。天气域组合为 `qweather + weather`:有和风 Key 时和风为主,没 Key 时免 Key 引擎顶上,任何情况下都有结果。 **怎么用**:无需配置,天气域自动命中;也可显式指定: ```bash python3 scripts/search.py "上海天气" --engine weather ``` ### 7. 新增免 Key 航空气象引擎 **以前**:查机场 METAR / TAF(航空气象例行报告)不知道去哪查,拿到原始报文也看不懂。 **现在**:内置免 Key 航空气象引擎,直连美国 FAA 官方公开接口,按 ICAO 机场代码(如 KLAX、ZBAA)查询实时 METAR,输出结构化字段:机场名、原始报文、报告时间。查询词不是 ICAO 代码时自动降级到通用搜索。 ```bash python3 scripts/search.py "KLAX" --engine aviation_weather python3 scripts/search.py "ZBAA" --engine aviation_weather ``` ### 8. 新增免 Key 火车票引擎 **以前**:查车次、余票要么打开购票软件,要么依赖需要申请 Key 的第三方查询服务。 **现在**:内置免 Key 火车票引擎,直连 12306 官方查询接口(两步:取会话 Cookie → 查余票),返回结构化车次信息:车次号、出发/到达站、发到时刻、历时、各席别余票(商务/一等/二等/卧铺/无座)、可购状态。默认查明天;支持「今天/明天/后天」「YYYY-MM-DD」「X月X日」日期与「高铁/动车」车次类型。 **怎么用**:火车票查询词自动路由到模态卡组合 `bocha_ai + bocha + train`,无需配置;也可显式指定: ```bash python3 scripts/search.py "北京到上海高铁" --engine train ``` 站点名有本地缓存(7 天过期,仅提升速度,不影响功能)。 ### 9. 垂直结构化路径不再被预算裁剪 **以前**:模态卡域组合加入新引擎后,预算截断会把声明好的兜底引擎顶掉,结构化结果不稳定。 **现在**:修正保底语义——声明组合内的引擎互相不顶位,预算紧张时优先替换非保底成员;火车票引擎归入垂直能力族,不再与通用网页引擎混排。 --- ## 验证 - 新增回归测试 `tests/test_time_window_cli.py` 18 项全过(YAML 解析、filter_args 拼参、裸命令路径校验、缓存时间窗隔离) - 新增合规回归:`tests/test_stop_signal.py`(Retry-After 解析、等待重试/放弃、TLS 停止信号、主链门禁、robots 门禁)与 `tests/test_robots_guard.py`(Disallow 命中/放行、失败容错、缓存复用、开关)共 32 项全过 - 核心回归 91 passed;引擎与缓存相关 47 passed、8 skipped(网络依赖 live 用例) - 全量回归 640 passed、18 skipped、19 subtests passed - 三引擎收编回归:`tests/test_aviation_weather.py` 14 项、`tests/test_wx.py` 13 项、`tests/test_train.py` 29 项全过(含 5 项 live 在线用例);在线冒烟实测:北京天气(wttr.in 26°C)、北京南→上海虹桥 G531、KLAX METAR 均返回真实数据 - `realtime_index` health 准入通过(latency ~0.8s),`--since 7d`、绝对日期窗口实测过滤生效,`published_at` 字段贯通