VALIDATION.md 6.8 KB

find_agent 工具验证报告

验证日期:2026-07-23

验证口径

  • 真实通过:实际调用当前配置的外部接口,并检查关键字段。
  • 契约通过:使用模拟接口/Repository 检查参数、分页、解析和错误格式。
  • 受阻:缺少密钥、数据库表或明确授权,不能宣称真实可用。

本轮回归结果

  • find_agent 与 LLM 重试定向测试:19 passed
  • Ruff 与 git diff --check:通过;
  • 三张 MySQL 表结构、列、唯一键和索引:真实检查通过;
  • 持久化测试数据:按专用 run_id 全部清理,残留数为0;
  • 项目全量 pytest:在两个非 find_agent 模块的收集阶段中止,分别是缺少 agents.demand_grade_orchestrator_agent.common.plan_builder,以及 supply_infra.scheduler.jobs.grade_demand_pool 未导出测试引用的 _execute_plan_tasks_with_retries

真实 Agent 干跑

测试输入为“个人养老金税收优惠”,模型为 google/gemini-2.5-flash

第一次运行在第5轮收到 OpenRouter/Google 的 MALFORMED_FUNCTION_CALL。原框架将该供应方错误解析为空答案并提前结束。现已在同步和 异步 LLM 调用中增加最多2次有限重试,重试耗尽后显式抛错;对应3个测试均通过。

修复后第二次运行完成了:

  • 27次工具调用;
  • 3个自主搜索词;
  • 6个已保存搜索页,并执行了分页;
  • 候选详情、批量双侧画像和6条视频内容解析;
  • 候选评分持久化、流程审计和状态恢复;
  • 工具参数错误后的自主修正:首次评分漏传 run_id、首次审计多传 run_id, Agent 均在下一次调用中修正。

但完整 Agent 验收未通过

  • 最后一次审计 can_finish=false
  • 仍有3个生产性搜索页未完成后续翻页;
  • 5个已入池候选在审计输入中缺失视频画像/作者画像“已尝试”标记;
  • Agent 未调用 normalize_age_portraits
  • 搜索轨迹只有 demand / pagination,没有形成标签扩展分支;
  • 审计未通过时模型仍停止,并输出“接下来重新获取详情和画像”的过程性半截文本, 没有给出最终主推荐或补充推荐表。

两次运行的数据库测试记录均已按实际 run_id 清理,残留数为0。

工具逐项结果

工具 验证方式 结果
load_skill 实际调用不存在技能 通过错误契约;当前 skills 目录无可用技能
douyin_search 真实搜索“个人养老金税收优惠”第一页、第二页 真实通过;8/0条,cursor 0→10;第二页关闭分页
douyin_search_tikhub 真实搜索“老年人高血压管理”两页 真实通过;7/6条,cursor 0→8→16,search_id/backtrace 可用于翻页
douyin_user_videos 使用 TikHub 结果中的真实 sec_uid 查询作者最热作品 真实通过;返回20条,统一候选结构与下一页游标完整
douyin_detail 真实查询视频 7665332856776764843 真实通过;详情、标签、分享数、播放地址齐全
get_content_fans_portrait 真实查询上述视频 接口通过;该样例没有内容画像,正确返回 has_portrait=false
get_account_fans_portrait 真实查询上述作者 真实通过;返回年龄桶且被标准化为强老年信号
batch_fetch_portraits 对上述候选真实请求双侧画像 真实通过;内容侧缺失时作者侧仍成功返回
normalize_age_portraits 使用本轮真实双侧返回测试 通过;输出 account_only、作者侧 strong、E上限0.65
audit_video_discovery_process 完整流/提前停止/备选误删场景 通过;能阻止少根词、未翻页、未扩标签和E/S双高误删
qwen_video_analyze 使用本轮详情播放URL、需求和相关点 真实通过;返回530字分析,耗时约21秒
create_video_discovery_run 真实 MySQL 端到端测试 真实通过;运行记录成功创建
record_video_search_page 真实 MySQL 保存与重复页测试 真实通过;3条候选入库,重复保存新增数为0
batch_save_video_candidate_evaluations 真实主推荐/补充候选/淘汰分池测试 真实通过;三类候选各1条,运行计数正确
query_video_discovery_state 真实查询运行、搜索树和三类候选 真实通过;返回1个搜索页和3条候选

真实样例观察

  • 搜索首条视频分享数为 304,973,详情接口返回值一致。
  • 作者作品接口首条作品分享数为 917,007,说明作者分支能找到关键词搜索之外的高传播内容。
  • 作者年龄画像实际使用 50- 表示50岁以上,占比 19.63%、TGI 84.84; 因此不能只识别“50岁以上”文字。
  • 内容画像可能没有数据,双侧画像工具的作者兜底是必要能力。
  • 千问视频分析能从真实视频中提取全国实施、缴费上限、税收优惠及提醒亲友等转发动机。
  • 本轮内部搜索第一页声明 has_more=true,第二页返回0条并关闭分页;Agent 应保存空页 和停止信号,不能把“无新增”误写成调用失败。
  • TikHub 第二页与第一页出现1条重复,说明跨页去重不能依赖供应方; 当前 (run_id, aweme_id) 唯一键和幂等合并逻辑能够处理。
  • MySQL 端到端测试覆盖创建运行、保存搜索页、重复页幂等、三类分池和状态查询; 测试记录已按 run_id 清理,残留数为0。

当前阻塞

  1. TikHub Key、三张 MySQL 表和全部持久化工具均已完成真实验证,没有相关阻塞。
  2. 完整 Agent 干跑已经执行,但最终审计未通过,当前不能宣称 Agent 可稳定完成任务。
  3. 持久化候选没有保存 detail_verified / content_portrait_attempted / account_portrait_attempted / content_analysis_verified 等审计状态,导致状态恢复后的 候选不能直接满足审计输入契约。
  4. AgentLoop 没有 find_agent 完成守卫;模型可以在 can_finish=false 时直接返回文本。

下一步修复

  1. 为候选表增加详情、双画像尝试、视频解析和年龄标准化状态,并由 query_video_discovery_state 原样恢复;搜索状态同时补回 parent_search_id
  2. 给 find_agent 增加确定性完成守卫:最后一次审计不是 can_finish=true 时,禁止 AgentLoop 接受最终文本;搜索或候选变更后必须重新审计。
  3. 将年龄标准化合并到批画像或候选保存流程,避免模型跳过强制证据处理。
  4. 调整搜索/详情/解析预算。当前详情按每条约10秒串行,且一次解析6条视频,真实任务 延迟偏高;应先用分享量、相关性和画像可得性做更强预筛。
  5. 完成上述修改后,使用同一输入重新干跑,直到最终审计通过并输出完整双池报告。