article_finding_strategy.md 4.8 KB


name: content_finding_strategy

description: 内容搜索方法论(Harness 架构:两轨搜索 + 搜索期预过滤)

内容搜索方法论


⚡ Harness: Fallback — 前置验证(快速失败)

在调用任何搜索工具前,先验证以下前置条件。任一失败则立即终止,不继续执行。

检查项 通过条件 失败处理
demand_analysis 已完成 起点策略.精准词候选主题下钻候选 至少一个非空 回退:用用户原始 query 分词后作为精准词候选,记录警告
目标数量有效 target_count >= 1 终止,告知用户"请指定目标文章数量"
搜索工具可用 weixin_search 工具存在 终止,告知用户"搜索工具不可用"

📋 Harness: Planner — 执行计划(开始前打印)

执行前输出以下计划,消除"盲盒"感:

[SearchPlanner]
  目标文章数 M         = {target_count}
  候选目标量 P         = M × 3 = {target_count * 3}
  第一轨(精准词)     = {精准词候选列表},期望贡献 P × 60%
  第二轨(下钻词)     = {主题下钻候选列表},仅在一轨不足时启用
  搜索期淘汰规则       = 时效 >18月 / 标题命中淘汰风险点 / 同biz >3条

💰 Harness: Budget — 预算约束

预算项 限制 超出处理
候选上限 P target_count × 3 达到 P 立即停止搜索,不再调用 weixin_search
关键词轮询上限 精准词 + 下钻词全部使用完 用完后不再补充关键词,将已有候选交付筛选
单关键词最多翻页 2 页(首页 + next_cursor 续页) 单词超 2 页不再翻页,换下一个关键词
单关键词保留上限 3 条(按阅读量降序) 每个搜索词最多保留 3 篇最优质文章,保证结果多样性
同一 biz 保留上限 3 条 超出丢弃,防止单一账号垄断候选

⚙️ Core Execution — 核心执行

步骤 1:两轨串行搜索

第一轨:精准词直搜(高确信,优先)

  • 来源:demand_analysis.起点策略.精准词候选(按顺序逐个)
  • 首页 cursor = "0";结果 < 5 条时用 next_cursor 取第二页
  • 候选量 ≥ P × 60% 后停止第一轨

第二轨:主题下钻词(补量,仅在一轨不足时启用)

  • 来源:demand_analysis.起点策略.主题下钻候选
  • 策略同第一轨;候选总量 ≥ P 后停止

数据读取(强约束,禁止解析 output 文本):

metadata.search_results[i].title           文章标题
metadata.search_results[i].url             文章链接(逐字符完整复制)
metadata.search_results[i].statistics.time 发布时间(秒)
metadata.search_results[i].nick_name       账号名称
metadata.search_results[i].biz             账号 biz(去重键)
metadata.search_results[i].cover_url       封面图(有值=带图)

步骤 2:搜索期预过滤(与步骤 1 同步执行,零额外 API)

每条结果收到后立即判断,命中任一条则丢弃

条件 判断方式
链接缺失 url 为空或非 http 开头
标题缺失 title 为空或仅空格
时效过期 statistics.time 距今 > 18 个月
命中淘汰风险点 标题含 demand_analysis.筛选关注点.淘汰风险点 中任意词
url 重复 相同 url 已在候选池中
同 biz 超额 相同 biz 已保留 3 条

通过预过滤的文章做标题清洗(去 HTML 标签;英文 " 替换为 " / ")后加入候选池。

步骤 3:工具调用失败处理

工具已内置 3 次自动重试。若 ToolResult.error 仍非空:

  • 当前关键词视为失败,跳过,换下一个关键词
  • 所有关键词均失败:终止搜索,进入 Observer 报告失败状态

📊 Harness: Observer — 观测与交付

候选池交付给 article_filter_strategy

每条记录固定包含:

{
  "title": "标题(已清洗)",
  "url": "完整文章链接(原样)",
  "statistics": { "time": 1710000000 },
  "nick_name": "账号名称",
  "biz": "账号 biz",
  "cover_url": "封面图链接或空字符串"
}

搜索摘要(写入日志 / 传递给下游)

[SearchObserver]
  关键词使用数       = {used_keywords} / {total_keywords}
  搜索原始返回条数   = {raw_count}
  预过滤淘汰条数     = {filtered_out}
  候选池最终数量     = {candidate_count} (目标 P = {P})
  状态              = 充足 / 接近目标 / 不足(< P × 60%)
候选量 C 状态判断 下游行为
C ≥ P 充足 直接进入筛选
P × 0.6 ≤ C < P 接近目标 进入筛选,筛选层判断是否补量
C < P × 0.6 不足 通知筛选层"候选不足",筛选层可触发回搜