为什么你需要一个新闻Agent,而不是手动读标题

今天的新闻消费者面临两个极端:要么被算法推荐的信息茧房包裹,要么在多个来源间手动比对,耗时且容易遗漏。对于开发者,更常见的是需要从大量实时新闻流中提取结构化信息——比如监控竞品动态、追踪突发事件、或为内部知识库生成每日简报。传统的RSS抓取+关键词匹配方案无法理解语义,更无法判断可信度。而单次LLM调用只能处理固定输入,无法自动探索、验证和多步规划。

一个能自主规划、调用搜索工具、记忆历史处理状态、执行多步骤验证的Agent,可以解决这些痛点。 本文将以你看到的这条新闻(ABC World News Tonight摘要)为示例输入,演示如何用LLM Agent从原始新闻流自动生成结构化、可信的事件报告。

news agent planning diagram

Agent架构拆解:四个核心模块

我们的News Agent系统包含以下模块,每个模块对应一个可复用的组件:

1. 规划层(Planning)

  • 职责:根据用户查询(或定时任务)制定多步行动计划。例如:
    • 步骤1:搜索给定新闻标题的原始来源
    • 步骤2:提取关键人物、地点、时间、事件
    • 步骤3:搜索至少两个不同来源交叉验证相同事件
    • 步骤4:计算每项声明的置信度评分
    • 步骤5:生成最终结构化报告
  • 实现:将计划描述为JSON步骤列表,Agent逐条执行。每条步骤包含tool(工具名)和args(参数模板)。

2. 工具层(Tools)

  • Tavily Search:实时新闻专用搜索API,返回结构化新闻结果(标题、URL、摘要、发布时间)。比通用搜索引擎更精准。
  • Webpage Reader:读取给定URL的全文,支持PDF、HTML等。
  • Date Validator:检查事件的日期/时间是否一致,排除过时或预测性内容。
  • Database Store:存储已处理新闻的hash,避免重复处理。
  • LLM Caller:用于语义提取、对比和评分。

3. 记忆层(Memory)

  • 短期记忆:当前处理步骤上下文(如已提取的事件列表)。
  • 长期记忆:存储已处理新闻的指纹(基于标题+来源的哈希)、可靠性评分历史。用于去重和来源信誉度估算。
  • 工作记忆:当前置信度评分推理链,用于最终报告。

4. 执行层(Execution & Retry)

  • 循环遍历规划步骤,调用对应工具。
  • 如果工具返回错误(如超时、404、内容被截断),重试最多3次,每次间隔指数退避。
  • 如果某个步骤连续失败,标记为“验证失败”并在最终报告中注明。

核心流程图与伪代码

text
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
Input: 原始新闻标题/摘要 (例如上述ABC新闻)

1. 规划 -> [
   "search(topic='Laos cave rescue missing men')",
   "search(topic='Virginia I-95 crash bus driver charged')",
   "search(topic='US Iran war negotiations Ian Pannell')",
   "read(url1)", "read(url2)", ...,
   "cross_verify([event1, event2, ...])",
   "score_confidence(events)",
   "generate_report()"
]

2. 执行循环:
   for step in plan:
       result = execute(step)
       if result.status == 'fail':
           retry.attempt +=1
           if retry > MAX_RETRY:
               mark as 'unverified'
       else:
           update_short_term_memory(result)

3. 生成最终结构化JSON:
   {
     "events": [
       {
         "category": "Rescue",
         "summary": "...",
         "sources": [...],
         "confidence": 0.85
       },
       ...
     ],
     "overall_verification": "High",
     "missing_validation": [...]
   }

关键实现细节与踩坑记录

1. 去重与时效性过滤

新闻Agent最容易被同一事件的不同版本刷屏。我们用title_similarity + source_domain + publish_date做复合去重。相似度>=0.7且同一天发布则视为重复。实现使用Sentence-BERT编码标题,计算余弦相似度。

2. 多源交叉验证的置信度评分

这是Agent区别于简单摘要的核心。我们设计三级置信度:

  • 高(0.9-1.0):至少两个独立新闻机构(非同一集团)包含相同事实陈述,且无矛盾。
  • 中(0.7-0.9):至少两个来源,但有部分细节不一致(如数字差10%以内)。
  • 低(0-0.7):仅单来源,或来源有明显偏见倾向(可根据历史评分降权)。

踩坑:LLM在判断“矛盾”时经常过度敏感,把不同角度报道认为是冲突。我们改用基于事实三元组(Subject-Predicate-Object)的结构化比较,再由LLM判断逻辑一致性,减少幻觉。

3. 工具调用失败处理

Tavily对某些冷门新闻可能返回空结果。我们的Agent不应直接报错,而应回退到通用Google搜索,或者标记为“未找到替代来源”,保留原来源但降低置信度。同时对Pdf阅读器要处理OCR失败情况。

4. 记忆管理:避免重复检索已处理事件

在Agent长期记忆中维护一个processed_hashes集合。对于相同事件(如“老挝洞穴救援”),如果已经处理过,直接返回上次结果,节省API费用。代价:新闻可能更新(如两名失踪者被找到)。解决方案:设置ttl(time-to-live),超过24小时则重新搜索。

confidence matrix example

简化版动手实现:用LangChain搭建20行核心Agent

下面是一个最少化可运行示例,使用LangChain 0.3.x(2026年版本)和Tavily工具。注意需要安装langchain, langchain-community, tavily 并设置TAVILY_API_KEY

python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
from langchain.agents import AgentExecutor, create_react_agent
from langchain.tools import tool
from langchain_community.tools.tavily import TavilySearchResults
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.memory import ConversationBufferMemory

# 1. 定义工具
@tool
def cross_check(claim: str) -> str:
    """交叉验证一个事实声明,返回置信度评分和来源。"""
    # 这里可调用Tavily搜索并LLM分析,简化版直接返回
    return f"Claim: {claim} - Confidence: 0.85 (2 sources verified)"

tavily_search = TavilySearchResults(max_results=3)
tools = [tavily_search, cross_check]

# 2. 初始化LLM(以GPT-4o为例)
llm = ChatOpenAI(model="gpt-4o", temperature=0)

# 3. 创建Agent
prompt = PromptTemplate.from_template(
    """You are a news verification agent. You have access to tools: {tool_names}.

Human: Given the news summary: {input}

Determine the key claims, search for original sources, cross-verify, and output a structured report including confidence scores.

Assistant: {agent_scratchpad}"""
)

agent = create_react_agent(llm, tools, prompt)
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)

agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    memory=memory,
    verbose=True,
    max_iterations=10,
    handle_parsing_errors=True
)

# 4. 运行示例
input_text = """ABC World News Tonight: 
- Two men missing after flood cave rescue in Laos (5 rescued days earlier)
- Bus driver charged with manslaughter after I-95 crash killing 5, focus on speed in work zone
- US and Iran: any closer to ending war? Report by Ian Pannell"""

response = agent_executor.invoke({"input": input_text})
print(response["output"])

运行后,Agent会自动决定先搜索每个新闻点,读取完整文章,然后调用cross_check验证,最后生成类似下面的报告:

json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
{
  "events": [
    {
      "id": 1,
      "title": "Laos cave rescue: two men still missing",
      "summary": "Five rescued, two remain missing as of May 31 2026. Search continues.",
      "sources": ["ABC News", "BBC", "Reuters"],
      "confidence": 0.92,
      "last_updated": "2026-06-01T03:10:00Z"
    },
    ...
  ],
  "verification_notes": "All key claims cross-verified with at least 2 independent sources. No contradictions found.",
  "missing_info": ["Exact location of cave not specified in most sources"]
}

调参建议

  • max_iterations:对于多事件新闻,建议设到15-20,防止Agent在验证某个事件时循环。
  • handle_parsing_errors:务必设为True,否则LLM偶尔格式错误会导致整个Agent崩溃。
  • 记忆长度:如果新闻量大,用ConversationSummaryMemory代替BufferMemory,避免超出上下文窗口。

个人观点与延伸思考

这个架构不只是给新闻聚合用的。同样的规划-工具-记忆-执行模式可以移植到任何“从非结构化信息中提取结构化知识”的场景:比如从法律文件中提取条款冲突,从科研论文中验证实验结论,甚至从用户反馈中自动生成产品需求。Agent的真正价值不在于单次回答,而在于它能够自主执行你无法手动完成的验证链条

但是,当前的Agent决定论题(比如“应该搜索哪些来源”)仍然依赖LLM的规划能力。我不建议完全放权给模型:最好预设好验证策略(如“至少两个非社交媒体来源”),将策略编码进工具或Prompt中,减少幻觉。相信工具,怀疑模型——让模型做它擅长的语义理解和生成,让确定性逻辑(去重、时间校验、置信度评分)交给规则代码。

如果你正准备构建自己的新闻监控Agent,建议从单事件入手,逐步增加多事件并行处理。不要一开始就追求全面,先把一个链条跑通。当你的Agent能准确区分“已救援”和“尚在失踪”的状态时,它的价值已经超过手动刷新闻了。