feat: Phase 2 新闻打分去重与 Agent 输入池裁剪

标题相似度合并、信源/时效/昨日重复加权排序,Agent 模式扩大 LLM 新闻候选池并记录抓取失败源。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-03 14:53:30 +08:00
parent 728bd1b9d1
commit 391f887d73
6 changed files with 370 additions and 46 deletions

View File

@@ -61,33 +61,47 @@ def _slim_news_items(
prepare=prepare_wecom_news_items,
) -> list[dict[str, Any]]:
items: list[dict[str, Any]] = []
for item in prepare(ai_news):
items.append(
{
"link": item.get("link", ""),
"title": item.get("title", ""),
"source_name": item.get("source_name", ""),
"published_fmt": item.get("published_fmt", ""),
"summary": item.get("desc_short") or "",
}
)
for item in prepare(ai_news, limit=limit):
payload = {
"link": item.get("link", ""),
"title": item.get("title", ""),
"source_name": item.get("source_name", ""),
"published_fmt": item.get("published_fmt", ""),
"summary": item.get("desc_short") or "",
}
if item.get("score") is not None:
payload["score"] = item.get("score")
items.append(payload)
if len(items) >= limit:
break
if items:
return items
for item in (ai_news.get("flat") or [])[:limit]:
items.append(
{
"link": item.get("link", ""),
"title": item.get("title", ""),
"source_name": item.get("source_name", ""),
"published_fmt": item.get("published_fmt", ""),
"summary": item.get("summary", ""),
}
)
flat = sorted(
ai_news.get("flat") or [],
key=lambda row: float(row.get("score") or 0),
reverse=True,
)
for item in flat[:limit]:
payload = {
"link": item.get("link", ""),
"title": item.get("title", ""),
"source_name": item.get("source_name", ""),
"published_fmt": item.get("published_fmt", ""),
"summary": item.get("summary", ""),
}
if item.get("score") is not None:
payload["score"] = item.get("score")
items.append(payload)
return items
def _news_pool_limit(wecom_limit: int, *, env_key: str, default_pool: int, agent_mode: bool) -> int:
if not agent_mode:
return wecom_limit
pool = env_int(env_key, default_pool)
return max(wecom_limit, pool)
def _wecom_skill_pool() -> int:
return max(10, env_int("DAILY_WECOM_SKILL_POOL", 200))
@@ -105,10 +119,21 @@ def build_llm_input(
ai_news: dict[str, Any],
cn_ai_news: dict[str, Any],
wecom_limits: dict[str, int],
agent_mode: bool = False,
) -> dict[str, Any]:
"""供 Cursor 编辑的精简 JSON不含完整 markdown"""
news_limit = wecom_limits.get("ai_news", 10)
cn_news_limit = wecom_limits.get("cn_ai_news", 8)
news_limit = _news_pool_limit(
wecom_limits.get("ai_news", 10),
env_key="DAILY_AGENT_NEWS_POOL",
default_pool=40,
agent_mode=agent_mode,
)
cn_news_limit = _news_pool_limit(
wecom_limits.get("cn_ai_news", 8),
env_key="DAILY_AGENT_CN_NEWS_POOL",
default_pool=30,
agent_mode=agent_mode,
)
depth = compare_depth()
trend_cmp = trending[:depth]
hot_cmp = hot[:depth]