news 2026/5/16 7:51:17

基于LLM的AI新闻智能体:自动化信息采集与周报生成实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于LLM的AI新闻智能体:自动化信息采集与周报生成实战

1. 项目概述:一个能自动追踪AI新闻的智能体

最近在GitHub上看到一个挺有意思的项目,叫ai-news-weekly-agent。光看名字,你大概能猜到它是个和AI新闻相关的自动化工具。没错,它的核心目标就是扮演一个“AI新闻周刊编辑”的角色,自动从互联网上抓取、筛选、整理并生成一份关于人工智能领域最新动态的周报。

我自己也经常需要关注AI领域的前沿进展,无论是为了技术选型、寻找灵感,还是单纯保持对行业的敏感度。但信息爆炸的时代,每天都有海量的论文、产品发布、技术博客和行业新闻涌现,手动去追踪和筛选,不仅耗时耗力,还容易遗漏关键信息。这个项目正好切中了这个痛点——它试图用代码和智能体(Agent)技术,将“信息收集-处理-输出”这个繁琐的流程自动化。

简单来说,ai-news-weekly-agent是一个基于大语言模型(LLM)驱动的智能体系统。它每周会自动运行,通过预设的规则或指令,去指定的信息源(如技术社区、新闻网站、论文预印本平台、知名博客等)爬取内容。然后,利用LLM的理解和总结能力,对这些原始信息进行重要性排序、去重、分类,并最终生成一份结构清晰、重点突出的中文周报,可能以Markdown、PDF或邮件订阅的形式交付给用户。

这个项目的价值在于,它将一个信息工作者的核心工作流(信息感知、筛选、整合、报告)进行了程序化封装。对于开发者、研究者、产品经理,甚至是投资分析师来说,拥有这样一个“永不疲倦的AI信息助理”,能极大地提升信息获取的效率和质量,让你把精力更集中在深度思考和决策上,而不是淹没在信息的海洋里。

2. 核心架构与工作流拆解

要理解ai-news-weekly-agent是如何工作的,我们需要深入其内部,拆解它的核心架构。一个典型的自动化新闻聚合智能体,其工作流可以抽象为四个核心阶段:信息采集、内容处理、报告生成与任务调度。

2.1 信息采集层:数据源的规划与获取

这是整个流程的起点,决定了周报内容的广度和质量。一个设计良好的采集层需要兼顾覆盖面和精准度。

2.1.1 核心数据源选择

项目通常会预设一个高质量的信息源列表。这些源站的选择至关重要,它们必须是AI领域信息的一手或高质量聚合地。常见的来源包括:

  • 学术前沿:arXiv(cs.AI, cs.CL, cs.CV, cs.LG等子版块)、Papers with Code。这里能获取最新的研究论文。
  • 技术社区与博客:Hacker News的AI板块、Reddit的r/MachineLearning、知名公司的技术博客(如OpenAI Blog, DeepMind Blog, Anthropic Blog)、以及一些顶级研究者的个人博客。
  • 行业新闻与资讯:TechCrunch, The Verge的AI板块,以及一些垂直媒体如MIT Technology Review的相关报道。
  • 开源项目动态:GitHub Trending中与AI相关的仓库,或者关注特定组织(如huggingface, langchain)的更新。

注意:数据源的配置需要谨慎。过多的源站会导致信息过载和运行缓慢,过少则可能遗漏重要新闻。一个好的实践是建立一个“核心源”(必读)和“扩展源”(可选扫描)的层级列表,并在运行中根据历史反馈动态调整。

2.1.2 采集技术实现

采集通常通过API和网络爬虫结合的方式实现。

  • API优先:对于提供开放API的平台(如GitHub API, arXiv API, Hacker News Firebase API),应优先使用。这更稳定、更友好,且通常有速率限制,需要代码中做好请求间隔和错误处理。
  • 爬虫作为补充:对于没有API或API信息不全的网站,则需要使用轻量级爬虫。常用的工具包括requests+BeautifulSoup(静态页面)或Playwright/Selenium(动态渲染页面)。这里必须遵守网站的robots.txt协议,并设置合理的请求头(User-Agent)和请求间隔,避免对目标服务器造成压力。
  • RSS订阅:许多博客和新闻网站仍提供RSS源,使用feedparser这样的库来解析RSS是最简单高效的方式之一。

ai-news-weekly-agent的实现中,可能会为每一类数据源编写一个独立的“采集器”(Collector)模块,每个模块负责处理特定站点的数据获取和初步解析(如提取标题、链接、发布时间、摘要等),并输出结构化的数据条目。

2.2 内容处理层:从数据到信息的提炼

采集到的原始数据条目是杂乱无章的。内容处理层的任务就是利用LLM的智能,将这些数据转化为有价值的信息。

2.2.1 去重与聚类

同一事件可能被多个源站报道。首先需要进行去重。简单的基于标题或链接的精确匹配效果有限,更智能的方法是使用文本嵌入(Embedding)。例如,使用OpenAI的text-embedding-3-small或开源的BGE模型,为每个条目的标题和摘要生成向量,然后计算向量之间的余弦相似度。相似度超过某个阈值(如0.85)的条目可以被视为同一事件,进行合并,并保留最早或最权威的来源信息。

2.2.2 重要性评估与过滤

不是所有抓取到的内容都值得进入周报。这里需要LLM出场。我们可以设计一个提示词(Prompt),让LLM扮演“资深AI编辑”,对每个条目进行打分和分类。

一个典型的Prompt可能是:

你是一位专注于人工智能领域的资深技术编辑。请评估以下新闻/论文/博客的重要性,并给出理由。 评估维度: 1. 技术突破性(0-10分):是否提出了颠覆性的新方法、模型或理论? 2. 行业影响力(0-10分):是否会对业界产品、投资或就业市场产生显著影响? 3. 社区关注度(0-10分):是否在开发者/研究社区引发了广泛讨论? 4. 可访问性(0-10分):其代码、模型或服务是否已开源或可用? 请根据以上维度,对以下内容进行综合评分(0-40分),并判断其所属类别(如“大模型技术”、“多模态”、“AI基础设施”、“伦理与治理”、“产品发布”、“融资动态”等)。 内容标题:[标题] 内容摘要:[摘要] 来源:[来源]

LLM会返回一个结构化的JSON,包含分数和类别。我们可以设定一个阈值(比如总分高于20分),只保留高分条目进入下一阶段。这个过程也完成了初步的分类。

2.2.3 关键信息提取与摘要生成

对于通过筛选的条目,需要进一步加工。我们可以再次调用LLM,为每个条目生成一个更精炼的摘要,并提取关键信息点,例如:

  • 论文:核心创新点、性能提升(SOTA)、代码/模型地址。
  • 产品发布:主要功能、定价变化、目标用户。
  • 行业新闻:涉及公司、交易金额、潜在影响。

这个摘要将直接用于周报的撰写,因此要求准确、简洁、包含干货。

2.3 报告生成层:从信息到知识的结构化呈现

经过处理的信息是零散的“珍珠”,报告生成层负责将它们串成一条“项链”。

2.3.1 内容组织与大纲生成

首先,LLM需要根据所有条目的类别和重要性,生成本周报的目录大纲。例如:

# AI Weekly Digest (YYYY-MM-DD) ## 一、 大模型前沿 ### 1.1 模型架构新进展 ### 1.2 高效训练与推理 ## 二、 多模态与具身智能 ## 三、 AI基础设施与工具 ## 四、 行业动态与商业应用 ## 五、 开源项目推荐

这个大纲为后续的内容填充提供了骨架。

2.3.2 章节内容撰写

接着,LLM会以“编辑”的身份,根据大纲和每个分类下的条目列表,撰写完整的章节内容。这里不再是简单的条目罗列,而是需要LLM进行连贯的叙述,可能包括背景介绍、事件串联、简要评论等,使周报读起来像是由人撰写的。

2.3.3 格式渲染与输出

最后,将LLM生成的Markdown文本进行最终渲染。这可能包括:

  • 添加固定的页眉页脚(如项目说明、订阅方式)。
  • 确保所有链接格式正确。
  • 将Markdown转换为更美观的格式,如通过WeasyPrint生成PDF,或直接发布到静态网站(如GitHub Pages)。
  • 集成邮件发送功能(使用smtplib或邮件服务商API),将周报推送给订阅者。

2.4 任务调度与运维层:让智能体自主运行

一个真正的“智能体”需要能定期、无人值守地运行。这一层关注系统的可持续性。

2.4.1 调度系统

最简单的方式是使用服务器的Cron Job(Linux)或Task Scheduler(Windows),定时(如每周一凌晨2点)执行主程序脚本。更云原生的做法是使用GitHub Actions的schedule事件,这样无需自有服务器,且能与代码仓库集成,运行日志清晰可见。在GitHub Actions的.yml配置文件中,可以这样设置:

on: schedule: - cron: '0 2 * * 1' # 每周一UTC时间2点(北京时间10点)运行 workflow_dispatch: # 允许手动触发

2.4.2 状态管理与错误处理

智能体运行中可能遇到各种问题:网络超时、API额度用尽、网站改版导致爬虫失效、LLM调用失败等。健壮的系统需要:

  • 日志记录:详细记录每个阶段的运行状态、获取的条目数、处理结果、遇到的错误,便于后期排查。
  • 检查点(Checkpoint):在关键步骤后保存中间状态(如采集到的原始数据、处理后的条目列表)。如果后续步骤失败,可以从检查点恢复,避免重复工作(特别是昂贵的LLM调用)。
  • 失败重试与降级策略:对网络请求和API调用设置重试机制。如果某个数据源完全失效,系统应能跳过它并继续运行,同时在日志中告警,而不是整体崩溃。
  • 通知机制:当运行失败或生成的内容异常(如条目数过少)时,通过邮件、Slack或钉钉机器人通知维护者。

2.4.3 成本控制与优化

LLM API调用是主要成本。需要优化:

  • 批量处理:将多个条目的评估或摘要任务合并到一个Prompt中调用,减少请求次数。
  • 模型选型:对于重要性评估、分类等任务,可以使用更便宜、更快的模型(如GPT-3.5-Turbo);对于最终的报告撰写,再使用能力更强的模型(如GPT-4)。
  • 缓存策略:对于短期内重复出现或相似的新闻,可以使用缓存,避免重复调用LLM进行分析。

3. 关键技术点与工具选型解析

构建ai-news-weekly-agent这样的项目,技术选型直接决定了开发效率和最终效果。下面我们来拆解几个关键的技术组件及其常见的选型方案。

3.1 大语言模型(LLM)接入与提示工程

LLM是整个系统的“大脑”,其选型和Prompt设计是核心。

3.1.1 模型服务选型

  • 闭源API(易用、能力强)
    • OpenAI GPT系列:生态最成熟,API稳定,文档齐全。gpt-4ogpt-4-turbo在理解和生成能力上表现优异,但成本较高。gpt-3.5-turbo性价比高,适合处理大量文本分类和摘要任务。
    • Anthropic Claude系列:以长上下文和强指令跟随著称,适合处理需要整合大量信息的报告生成任务。
    • 国内大厂API:如百度文心、阿里通义、智谱GLM等,访问速度和合规性有优势。
  • 开源模型自部署(可控、成本固定)
    • 轻量级模型:如Qwen2.5-7B-Instruct,Llama-3.2-3B-Instruct,它们参数量小,可以在消费级显卡(甚至CPU)上运行,适合对实时性要求不高或希望完全控制数据的场景。可以使用vLLM,TGI(Text Generation Inference) 等框架进行高效部署。
    • 重量级模型:如Qwen2.5-72B-Instruct,Llama-3.1-70B,能力接近第一梯队闭源模型,但需要强大的GPU服务器,运维成本高。

实操心得:对于个人或小团队项目,初期强烈建议从OpenAI或Claude的API开始。这能让你快速验证想法和流程,把精力集中在业务逻辑而非模型部署上。当流程跑通且成本成为主要考量时,再考虑将部分任务(如文本分类、摘要)迁移到本地部署的轻量开源模型上,形成混合架构。

3.1.2 提示工程(Prompt Engineering)实践

Prompt是驱动LLM工作的“指令集”,设计好坏直接影响结果质量。

  • 角色扮演(Role Playing):如“你是一位资深的AI科技媒体编辑”,这能有效引导模型输出符合特定风格和深度的内容。
  • 结构化输出(Structured Output):明确要求模型以JSON、XML或特定Markdown格式返回结果,便于后续程序化处理。例如,在评估重要性时,直接要求返回{"score": 25, "category": "大模型技术", "reason": "..."}
  • 少样本学习(Few-shot Learning):在Prompt中提供1-3个高质量的例子(输入和期望的输出),能显著提升模型在特定任务上的表现。例如,给一个新闻标题和摘要,然后展示一个理想的重要性评估结果。
  • 链式思考(Chain-of-Thought):对于复杂任务,鼓励模型“一步一步思考”,可以提高推理的准确性和可靠性。

一个综合性的Prompt模板可能长这样:

你是一位专注于人工智能领域的资深技术编辑,负责为专业读者筛选和总结本周重要动态。 ## 你的任务 对给定的内容条目进行重要性评估和摘要。 ## 输出格式 你必须严格按照以下JSON格式输出,不要有任何其他文字: { “overall_score”: 一个0到40的整数, “category”: “分类名称”, “key_points”: [“要点1”, “要点2”, “要点3”], “concise_summary”: “一段不超过100字的中文摘要” } ## 评估标准 - 技术突破性 (0-10): ... - 行业影响力 (0-10): ... - ... ## 示例 输入: {“title”: “...”, “abstract”: “...”} 输出: {“overall_score”: 32, “category”: “...”, ...} ## 现在开始处理 输入: {“title”: “{{title}}”, “abstract”: “{{abstract}}”}

3.2 数据采集与处理的工程实现

3.2.1 异步并发采集

为了提高采集效率,必须使用异步IO。Python的asyncio库配合aiohttp是标准选择。可以构建一个异步的采集器池,同时并发抓取多个数据源。

import aiohttp import asyncio from bs4 import BeautifulSoup async def fetch_url(session, url): try: async with session.get(url, headers=headers, timeout=10) as response: html = await response.text() # 使用BeautifulSoup解析 soup = BeautifulSoup(html, 'html.parser') # ... 提取逻辑 ... return extracted_data except Exception as e: logging.error(f“Failed to fetch {url}: {e}”) return None async def main(urls): async with aiohttp.ClientSession() as session: tasks = [fetch_url(session, url) for url in urls] results = await asyncio.gather(*tasks, return_exceptions=True) # 处理结果

3.2.2 向量数据库用于智能去重

如前所述,基于语义的去重需要计算文本嵌入的相似度。虽然可以实时计算,但对于历史数据比对,使用向量数据库(Vector Database)更高效。你可以将过去几周处理过的条目向量存入数据库,当新条目到来时,进行相似度查询。

  • 轻量级选择ChromaDBFAISS。它们易于集成,特别是ChromaDB,API简单,支持持久化。
  • 生产级选择Qdrant,Weaviate,Milvus。它们功能更强大,支持分布式、更丰富的查询条件。

基本流程:1) 用嵌入模型将新条目文本转换为向量;2) 在向量库中搜索Top-K个最相似的向量;3) 如果相似度超过阈值,则视为重复或高度相关,进行合并处理。

3.3 系统架构与代码组织

一个清晰的项目结构有助于长期维护。

ai-news-weekly-agent/ ├── config.yaml # 配置文件:API密钥、数据源列表、阈值参数等 ├── main.py # 主程序入口,协调整个流程 ├── src/ │ ├── collectors/ # 采集器模块 │ │ ├── __init__.py │ │ ├── arxiv_collector.py │ │ ├── github_collector.py │ │ └── rss_collector.py │ ├── processors/ # 处理器模块 │ │ ├── __init__.py │ │ ├── deduplicator.py # 去重 │ │ ├── classifier.py # 分类与评分(调用LLM) │ │ └── summarizer.py # 摘要生成(调用LLM) │ ├── generators/ # 生成器模块 │ │ ├── __init__.py │ │ └── report_generator.py # 报告撰写(调用LLM) │ ├── utils/ │ │ ├── llm_client.py # 封装LLM API调用 │ │ ├── vector_db.py # 向量数据库操作 │ │ └── logger.py │ └── models.py # 数据模型定义(如NewsItem类) ├── outputs/ │ ├── raw_data/ # 原始采集数据 │ ├── processed/ # 处理后的数据 │ └── reports/ # 生成的周报 ├── tests/ # 单元测试 └── requirements.txt # 依赖列表

这种模块化设计使得每个功能职责单一,易于测试和替换。例如,要增加一个新的数据源,只需在collectors目录下添加一个新的类。

4. 从零搭建的实操步骤与核心配置

假设我们现在要从零开始实现一个简化版的ai-news-weekly-agent,以下是核心的实操步骤。我们将以Python为主要语言,使用OpenAI API和GitHub Actions。

4.1 环境准备与基础依赖

首先,创建一个新的项目目录并初始化虚拟环境。

mkdir ai-news-weekly-agent && cd ai-news-weekly-agent python -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate # Windows

创建requirements.txt文件,包含基础依赖:

# 核心依赖 openai>=1.0.0 aiohttp>=3.9.0 beautifulsoup4>=4.12.0 feedparser>=6.0.0 python-dotenv>=1.0.0 pyyaml>=6.0 chromadb>=0.4.0 # 向量数据库 sentence-transformers>=2.2.0 # 用于生成文本嵌入 # 报告生成与格式化 markdown>=3.5.0 pdfkit>=1.0.0 # 需要额外安装wkhtmltopdf # 调度与部署(可选) schedule>=1.2.0

安装依赖:pip install -r requirements.txt

接下来,创建配置文件.env用于存储敏感信息(切勿提交到Git):

OPENAI_API_KEY=sk-your-openai-key-here OPENAI_BASE_URL=https://api.openai.com/v1 # 如果使用其他兼容API,可修改 DATA_SOURCES_PATH=./config/data_sources.yaml VECTOR_DB_PATH=./data/chroma_db LOG_LEVEL=INFO

创建config/data_sources.yaml定义数据源:

sources: - type: “arxiv” category: “cs.AI” max_results: 50 - type: “rss” url: “https://news.ycombinator.com/rss" tags: [“hackernews”] - type: “github_trending” language: “python” since: “weekly”

4.2 实现核心数据模型与采集器

src/models.py中定义核心数据类:

from pydantic import BaseModel from datetime import datetime from typing import List, Optional class NewsItem(BaseModel): id: str # 唯一标识,可以是URL的hash title: str url: str source: str # 来源网站,如 “arxiv”, “hackernews” published_at: Optional[datetime] content: Optional[str] # 原始内容或摘要 embedding: Optional[List[float]] = None # 文本向量 category: Optional[str] = None score: Optional[int] = None processed_summary: Optional[str] = None

src/collectors/arxiv_collector.py中实现一个简单的ArXiv采集器:

import arxiv import asyncio from ..models import NewsItem from datetime import datetime class ArXivCollector: def __init__(self, category=“cs.AI”, max_results=50): self.category = category self.max_results = max_results self.client = arxiv.Client() async def fetch(self) -> List[NewsItem]: search = arxiv.Search( query=f“cat:{self.category}”, max_results=self.max_results, sort_by=arxiv.SortCriterion.SubmittedDate ) items = [] for result in self.client.results(search): # 构造唯一ID,例如使用entry_id的MD5 import hashlib item_id = hashlib.md5(result.entry_id.encode()).hexdigest() news_item = NewsItem( id=item_id, title=result.title, url=result.entry_id, source=“arxiv”, published_at=result.published, content=result.summary, # 使用摘要作为初始内容 ) items.append(news_item) return items

类似地,可以实现RSS采集器(使用feedparser)和GitHub Trending采集器(使用GitHub API或爬虫)。

4.3 构建处理流水线:去重、评分与摘要

src/processors/deduplicator.py中,实现基于向量相似度的去重:

import chromadb from sentence_transformers import SentenceTransformer from ..models import NewsItem class Deduplicator: def __init__(self, persist_path=“./data/chroma_db”): self.client = chromadb.PersistentClient(path=persist_path) # 创建一个集合(collection)来存储历史新闻 self.collection = self.client.get_or_create_collection(name=“news_items”) self.embedding_model = SentenceTransformer(‘all-MiniLM-L6-v2’) # 轻量级嵌入模型 def find_similar(self, news_item: NewsItem, top_k=3, threshold=0.85): # 为新闻项生成嵌入向量 text_to_embed = f“{news_item.title} {news_item.content[:500]}” # 取部分内容 embedding = self.embedding_model.encode(text_to_embed).tolist() news_item.embedding = embedding # 在向量数据库中查询相似项 results = self.collection.query( query_embeddings=[embedding], n_results=top_k ) # results包含ids, distances, metadatas等 similar_items = [] if results[‘distances’][0]: # 检查是否有结果 for dist, meta in zip(results[‘distances’][0], results[‘metadatas’][0]): if 1 - dist > threshold: # chromadb使用余弦距离,越小越相似 similar_items.append(meta) return similar_items def add_item(self, news_item: NewsItem): # 将新项目添加到向量数据库,以备未来查重 if news_item.embedding: self.collection.add( embeddings=[news_item.embedding], metadatas=[{“id”: news_item.id, “title”: news_item.title, “source”: news_item.source}], ids=[news_item.id] )

src/processors/classifier.py中,实现调用LLM进行评分和分类:

from openai import OpenAI import json from ..models import NewsItem import logging class NewsClassifier: def __init__(self, model=“gpt-3.5-turbo”): self.client = OpenAI() # 会自动从环境变量读取OPENAI_API_KEY self.model = model self.prompt_template = “””你是一位AI领域编辑...(此处填入之前设计好的Prompt)...””” def classify_and_score(self, news_item: NewsItem) -> NewsItem: prompt = self.prompt_template.format(title=news_item.title, abstract=news_item.content[:1000]) try: response = self.client.chat.completions.create( model=self.model, messages=[{“role”: “user”, “content”: prompt}], temperature=0.2, # 低温度保证输出稳定 response_format={“type”: “json_object”} # 要求返回JSON ) result = json.loads(response.choices[0].message.content) news_item.category = result.get(“category”) news_item.score = result.get(“overall_score”) # 可以保存其他信息到news_item的额外字段中 return news_item except Exception as e: logging.error(f“Classification failed for {news_item.id}: {e}”) return news_item # 返回原item,分数为None

Summarizer的实现类似,设计一个专注于生成简洁摘要的Prompt来调用LLM。

4.4 组装主流程与生成报告

src/generators/report_generator.py中,实现报告生成:

class ReportGenerator: def __init__(self, llm_client, model=“gpt-4o”): self.llm_client = llm_client self.model = model def generate_outline(self, categorized_items: dict) -> str: # categorized_items 是一个字典,key是类别,value是该类下的NewsItem列表 prompt = f“””基于以下分类的AI新闻条目,生成一份中文周报的目录大纲。大纲应清晰有逻辑,包含主要章节和可能的子章节。 分类数据:{json.dumps(categorized_items, default=str, indent=2)} 只输出大纲内容,用Markdown格式。””” # 调用LLM生成大纲... return outline_markdown def generate_section(self, section_title: str, items: List[NewsItem]) -> str: prompt = f“””你是一位AI科技专栏作者。请根据以下条目,撰写‘{section_title}’部分的周报内容。 要求:内容连贯,有引言和简要评论,不要简单罗列。使用中文。 条目信息:{json.dumps([item.dict() for item in items], default=str, indent=2)}””” # 调用LLM生成章节内容... return section_content def assemble_report(self, outline: str, sections: dict) -> str: # sections: {‘章节名’: ‘内容’} report = “# AI Weekly Digest\n\n” report += f“*本期周报生成于 {datetime.now().strftime(‘%Y-%m-%d %H:%M’)}*\n\n” report += outline + “\n\n” for sec_title, sec_content in sections.items(): report += f“## {sec_title}\n\n{sec_content}\n\n” report += “---\n*本报告由AI自动生成,仅供参考。*” return report

最后,在main.py中组装整个流水线:

import asyncio from src.collectors import ArXivCollector, RssCollector from src.processors import Deduplicator, NewsClassifier, Summarizer from src.generators import ReportGenerator from src.utils.llm_client import get_llm_client import logging async def main(): logging.basicConfig(level=logging.INFO) # 1. 采集 collectors = [ArXivCollector(), RssCollector(“https://example.com/feed")] all_items = [] for collector in collectors: items = await collector.fetch() all_items.extend(items) logging.info(f“Collected {len(all_items)} raw items.”) # 2. 去重 deduplicator = Deduplicator() unique_items = [] for item in all_items: similar = deduplicator.find_similar(item) if not similar: # 没有高度相似的,认为是新内容 unique_items.append(item) deduplicator.add_item(item) # 存入数据库 logging.info(f“After deduplication: {len(unique_items)} items.”) # 3. 分类与评分 classifier = NewsClassifier(model=“gpt-3.5-turbo”) scored_items = [] for item in unique_items: processed_item = classifier.classify_and_score(item) if processed_item.score and processed_item.score > 20: # 阈值过滤 scored_items.append(processed_item) logging.info(f“After scoring: {len(scored_items)} high-quality items.”) # 4. 按类别分组 from collections import defaultdict categorized = defaultdict(list) for item in scored_items: categorized[item.category].append(item) # 5. 生成报告 llm_client = get_llm_client() generator = ReportGenerator(llm_client, model=“gpt-4”) outline = generator.generate_outline(categorized) sections = {} for category, items in categorized.items(): sections[category] = generator.generate_section(category, items) final_report = generator.assemble_report(outline, sections) # 6. 保存输出 import os os.makedirs(‘./outputs/reports’, exist_ok=True) report_path = f‘./outputs/reports/weekly_{datetime.now().strftime(“%Y%m%d”)}.md’ with open(report_path, ‘w’, encoding=‘utf-8’) as f: f.write(final_report) logging.info(f“Report saved to {report_path}”) if __name__ == “__main__”: asyncio.run(main())

4.5 配置自动化部署与调度

为了让项目每周自动运行,我们使用GitHub Actions。

在项目根目录创建.github/workflows/weekly-report.yml

name: Generate AI Weekly Report on: schedule: - cron: ‘0 10 * * 1’ # 每周一UTC时间10点(北京时间周一18点)运行 workflow_dispatch: # 允许手动触发 jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: ‘3.11’ - name: Install dependencies run: | pip install -r requirements.txt # 如果需要wkhtmltopdf for PDF generation sudo apt-get update sudo apt-get install -y wkhtmltopdf - name: Run weekly agent env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} # 其他环境变量... run: python main.py - name: Commit and push if report changed run: | git config --local user.email “action@github.com” git config --local user.name “GitHub Action” git add ./outputs/reports/ git commit -m “chore: update weekly report [skip ci]” || echo “No changes to commit” git push

你需要将OPENAI_API_KEY添加到GitHub仓库的Settings -> Secrets and variables -> Actions中。

5. 常见问题、优化方向与避坑指南

在实际搭建和运行过程中,你一定会遇到各种问题。以下是我在类似项目中积累的一些经验和避坑点。

5.1 典型问题与排查

1. 采集失败或数据为空

  • 表现:某个采集器没有获取到任何数据。
  • 排查
    • 网络问题:检查目标网站是否可访问,是否被屏蔽。考虑在代码中添加重试机制和更友好的User-Agent。
    • 网站改版:网站结构变化导致CSS选择器或XPath失效。需要定期维护采集器代码。可以为关键采集器编写简单的单元测试,定期运行以检测是否失效。
    • API限制:检查是否触发了目标API的速率限制(Rate Limit)。需要在代码中实现请求间隔(如time.sleep)和使用API Key轮询。
  • 解决:增加详细的日志记录,记录每个请求的URL和响应状态。使用try...except包裹采集逻辑,捕获异常并记录,不影响其他采集器运行。

2. LLM调用超时或返回非预期格式

  • 表现:OpenAI API调用失败,或者返回的内容不是预期的JSON。
  • 排查
    • 网络或服务不稳定:API服务临时故障。
    • Prompt设计问题:Prompt指令不够清晰,导致模型“放飞自我”。特别是没有强制要求JSON输出时。
    • Token超限:输入文本过长,超过了模型上下文窗口。
  • 解决
    • 实现指数退避的重试逻辑。
    • 在Prompt中明确使用response_format={“type”: “json_object”}并要求模型输出指定键名的JSON。在代码中解析JSON前,加入json.loads()的异常捕获,并准备一个降级处理方案(如标记该条目为处理失败)。
    • 对过长的输入文本进行智能截断,保留开头、结尾和可能的关键中间部分。

3. 生成的内容质量不稳定

  • 表现:周报内容有时啰嗦,有时遗漏重点,风格不一致。
  • 排查
    • Temperature参数:在生成创造性内容(如报告撰写)时,temperature可以稍高(如0.7);在进行分类、摘要等确定性任务时,temperature应调低(如0.2)。
    • System Prompt缺失:没有给模型设定明确的角色和风格。
    • 输入信息质量差:如果给LLM的原始条目摘要本身就模糊不清,输出自然不佳。
  • 解决
    • 为不同的LLM调用任务(分类、摘要、撰写)设置不同的temperaturemax_tokens参数。
    • 精心设计System Prompt和User Prompt,使用少样本示例(Few-shot)来锚定输出风格和质量。
    • 在前期的摘要生成阶段把好关,确保输入给报告生成器的“素材”是高质量的。

4. 运行成本失控

  • 表现:API调用费用超出预期。
  • 排查
    • 数据源过多:每周抓取上千条新闻,每条都调用LLM处理。
    • 模型使用不当:所有任务都用最贵的gpt-4模型。
    • 重复处理:没有做好去重,同一新闻被多次处理。
  • 解决
    • 严格筛选数据源,只保留最高质量的。
    • 采用混合模型策略:分类、去重用便宜的gpt-3.5-turbo或本地小模型;最终报告润色用gpt-4
    • 强化去重模块,确保每条信息只被处理一次。实现一个缓存层,对近期已处理过的新闻标题/内容哈希值进行缓存。

5.2 性能与效果优化方向

当基础版本跑通后,可以考虑以下优化来提升系统的智能性和实用性:

1. 个性化推荐

  • 让系统学习用户的兴趣偏好。例如,用户可以标记对某些条目“感兴趣”或“不感兴趣”。系统可以记录这些条目的关键词、类别或嵌入向量,在后续的评分环节中引入“个性化分数”加权,让周报更贴合用户口味。

2. 多模态信息整合

  • 目前的处理主要基于文本。可以扩展采集器,抓取一些关键图表、模型性能对比图等。在报告中,可以引用这些图片的链接,甚至尝试用多模态模型(如GPT-4V)对图表进行简要描述,整合进摘要中。

3. 溯源与可解释性

  • 在生成的周报中,为每个观点或结论注明来源(超链接到原始文章)。这不仅增加可信度,也方便读者深入阅读。可以在NewsItem中保留原始URL,并在报告生成时,要求LLM在叙述中自然地附上引用标记。

4. 交互与反馈闭环

  • 将生成的周报发布到一个带有简单交互功能的页面(如静态博客)。读者可以对某条新闻点击“有用”或“无用”,或者提交评论。收集这些反馈数据,可以用于优化LLM的Prompt,或调整数据源的权重,形成一个持续改进的闭环。

5. 部署与监控升级

  • 将项目容器化(Docker),便于在不同环境部署。
  • 引入更完善的监控,如使用PrometheusGrafana监控API调用次数、耗时、费用消耗、各阶段处理条目数等关键指标,并设置告警。

5.3 新手避坑指南

  • 不要一开始就追求大而全:先从1-2个核心数据源(如Hacker News和ArXiv)和最简单的流程(采集->LLM摘要->输出列表)开始。快速跑通一个端到端的MVP(最小可行产品),验证想法是否可行。
  • API密钥安全第一:永远不要将API密钥硬编码在代码中或提交到公开仓库。始终使用环境变量或密钥管理服务。
  • 成本预估与控制:在运行前,粗略估算一下每次运行的成本。例如,处理100条新闻,每条调用2次LLM(分类+摘要),使用gpt-3.5-turbo,大约花费在0.1-0.2美元。可以先设置一个消费额度告警。
  • LLM调用要加“护栏”:LLM的输出是不可控的。一定要对输出进行格式验证和内容过滤(防止生成不当内容)。设置合理的超时和重试。
  • 日志是你的好朋友:在项目初期就建立完善的日志系统,记录每个步骤的输入输出。当出现问题时,详细的日志是唯一的排查线索。
  • 尊重数据源:遵守网站的robots.txt,设置合理的爬取间隔,不要用你的脚本对一个小网站进行高频请求。可以考虑使用公共API或RSS订阅,这是更友好的方式。

构建一个ai-news-weekly-agent是一次非常有益的实践,它串联起了爬虫、数据处理、LLM应用、提示工程、自动化部署等多个技能点。最终产出的不仅是一个工具,更是一个能够持续为你提供价值的“数字员工”。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/16 7:49:39

阴阳师百鬼夜行AI自动化脚本:智能式神碎片收集的革命性解决方案

阴阳师百鬼夜行AI自动化脚本:智能式神碎片收集的革命性解决方案 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 阴阳师百鬼夜行AI自动化脚本是一款基于先进计算机视觉…

作者头像 李华
网站建设 2026/5/16 7:49:38

FakeLocation:安卓应用级位置伪装技术详解与实践指南

FakeLocation:安卓应用级位置伪装技术详解与实践指南 【免费下载链接】FakeLocation Xposed module to mock locations per app. 项目地址: https://gitcode.com/gh_mirrors/fak/FakeLocation 你是否曾想过在不同的应用中展示不同的位置信息?比如…

作者头像 李华
网站建设 2026/5/16 7:49:38

ComfyUI-Manager终极指南:高效管理AI工作流扩展的完整解决方案

ComfyUI-Manager终极指南:高效管理AI工作流扩展的完整解决方案 【免费下载链接】ComfyUI-Manager ComfyUI-Manager is an extension designed to enhance the usability of ComfyUI. It offers management functions to install, remove, disable, and enable vario…

作者头像 李华
网站建设 2026/5/16 7:43:49

BeagleBone Black GPIO按键控制:Python实现与硬件连接详解

1. 项目概述:从物理按键到数字逻辑在嵌入式开发的世界里,让一块电路板“感知”物理世界的动作,比如按下一个小小的按键,往往是项目迈出的第一步。这看似简单的操作,背后却串联起了硬件连接、信号处理、软件逻辑等一系列…

作者头像 李华
网站建设 2026/5/16 7:38:05

免费GPT API代理网关:低成本AI应用开发与部署实战指南

1. 项目概述与核心价值最近在折腾AI应用开发,发现调用大模型API时,成本控制和稳定性是两个绕不开的痛点。特别是对于个人开发者、学生团队或者想快速验证想法的小项目,直接使用官方API,费用像流水一样,而且一旦遇到网络…

作者头像 李华