VALIDATION.md 7.4 KB

find_agent 工具验证报告

真实接口验证日期:2026-07-23

当前契约同步日期:2026-07-28

当前 find_agent 明确不使用视频理解。qwen_video_analyze 未注册,视频画面、语音、 字幕及多模态解析不属于在线能力。数据库和 ORM 不包含视频理解相关列。

最终等级只允许 primary / rejectedpending_evaluation 仅为过程状态,不存在 backup、补充推荐或人工备选。

验证口径

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

本轮回归结果

  • 2026-07-28 移除工具错误分类后,find_agent、AgentLoop、工具框架和失败声明 定向测试合计 39 passed;Ruff 与 git diff --check 通过;
  • 调度测试文件全量为 4 passed, 3 failed;失败来自既有测试环境问题:两个 SQLite 用例未为 MySQL BIGINT 主键提供自增兼容,一个测试夹具使用普通 object() 代替 FindDemandContext。三项均与本次故障终止修改无关;
  • 2026-07-23 历史 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个已保存搜索页,并执行了分页;
  • 候选详情和批量双侧画像;
  • 候选评分持久化、流程审计和状态恢复;
  • 工具参数错误后的自主修正:首次评分漏传 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 完整流/提前停止/错误淘汰场景 契约已同步为仅审计 primary / rejected,不再要求视频理解
audit_video_discovery_run 注册与完成顺序契约测试 已注册;候选评估后执行,且仅 can_finish=true 可进入最终状态查询
create_video_discovery_run 真实 MySQL 端到端测试 真实通过;运行记录成功创建
record_video_search_page 真实 MySQL 保存与重复页测试 真实通过;3条候选入库,重复保存新增数为0
batch_save_video_candidate_evaluations 候选分池契约 当前只接受 primary / rejectedbackup 会返回输入错误
query_video_discovery_state 查询运行、搜索树和候选 当前返回主推荐、淘汰候选及过程中的 pending_evaluation

真实样例观察

  • 搜索首条视频分享数为 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 / age_portraits_normalized 等审计状态;视频理解字段不 属于当前审计契约。
  4. find_agent 完成守卫已启用;正常结果仍要求完整成功顺序。Agent 明确输出 任务未完成(工具故障) 时允许失败结束;程序不解析工具返回,也不判断错误是否 可恢复。

下一步修复

  1. 确保候选表的详情、双画像尝试和年龄标准化状态由 query_video_discovery_state 原样恢复;搜索状态同时补回 parent_search_id
  2. 将年龄标准化合并到批画像或候选保存流程,避免模型跳过强制证据处理。
  3. 调整搜索和详情预算。当前详情按每条约10秒串行,真实任务延迟偏高;应先用分享量、 相关性和画像可得性做更强预筛。
  4. 使用同一输入重新干跑,直到最终审计通过并输出完整 primary / rejected 报告。