从零搭建Agent与LLM技术日报:信息聚合与筛选系统实战

发布时间:2026/10/17 8:09:05
从零搭建Agent与LLM技术日报:信息聚合与筛选系统实战 1. 从一份日报说起Agent 与 LLM 技术雷达的搭建思路每天早上花十五分钟翻一遍 Agent 和 LLM 领域的新动态这个习惯我坚持了快两年。最开始是手动刷各种信息源后来信息量爆炸手动根本看不过来就开始琢磨怎么把这件事自动化。今天这篇内容就是把我搭建“技术精选日报”这套流程的完整思路和实操细节拆开来讲——它本质上是一个信息聚合与筛选系统核心目标是从海量噪音里捞出真正值得看的几条信号。这套东西能做什么简单说它每天定时抓取我预设的若干信息源经过一轮关键词过滤和相关性打分把最值得关注的条目挑出来按主题归类生成一份结构化的日报。适合谁参考如果你也在做技术跟踪、竞品调研、或者单纯想保持对某个领域的敏感度这套思路可以直接抄作业。哪怕你不想写代码里面关于“信息源怎么选”“筛选标准怎么定”的部分手动操作同样适用。我把它定位成一个个人技术雷达而不是什么大而全的资讯平台。这个定位很关键因为它决定了后面所有的设计取舍——不求覆盖全只求不漏掉真正重要的东西。2. 整体架构设计为什么是“抓取-过滤-打分-生成”四段式2.1 核心流程拆解与选型考量整套流程我拆成了四段抓取、过滤、打分、生成。为什么是这四段而不是别的分法因为每一段解决的是一个独立的问题段与段之间通过明确的数据结构衔接任何一段出问题都不会污染其他段。抓取段负责把原始内容拿回来统一成{title, url, source, timestamp, raw_content}这样的结构。过滤段做粗筛把明显不相关的条目扔掉比如标题里连“Agent”“LLM”“大模型”这些词都没有的直接淘汰。打分段是核心给每条内容算一个相关性分数决定它能不能进日报。生成段负责排版把选中的条目按主题分组输出成可读的 Markdown。我试过把这四段揉在一起写结果就是改一个过滤规则要动整个脚本调试起来非常痛苦。拆开之后每段可以独立测试、独立替换。比如后来我把打分逻辑从“关键词命中数”换成了“关键词加权来源权重”只改了打分段一个文件其他部分完全没动。提示分段的核心原则是“每段只做一件事输入输出格式固定”。这样即使你后面想换掉整个抓取方式只要输出结构不变下游完全无感。2.2 信息源的选择逻辑与权重分配信息源这块我踩过不少坑。一开始贪多什么源都往里加结果日报里全是重复内容和低质量灌水。后来我定了一个原则每个信息源必须能回答“它比别的源多提供了什么”。我目前用的源大致分三类。第一类是一手发布源比如官方博客、技术团队的更新日志这类源权威性最高权重给到 1.0。第二类是社区讨论源比如技术论坛的热帖、问答社区的高赞回答这类源时效性强、视角多元但噪音也大权重给 0.6。第三类是聚合筛选源就是别人已经筛过一轮的 newsletter 或者周报权重 0.7因为它们已经做了一轮过滤但可能带有别人的偏好。权重不是拍脑袋定的我的方法是连续跟踪两周统计每个源产出的条目最终进入日报的比例。比例高的源说明它的内容和我关注的方向匹配度高权重就往上调比例低的要么降权要么直接砍掉。这个统计过程我写了个小脚本自动跑每周出一份源质量报告。2.3 数据流转与存储的轻量方案存储这块我没上数据库直接用 JSON 文件按天存。每天一个文件文件名就是日期里面是一个数组每个元素是一条处理过的条目。为什么不用数据库因为我的数据量级很小一天撑死几百条JSON 完全够用而且方便我直接用文本编辑器打开看调试成本极低。数据流转是这样的抓取段把原始数据写到raw/YYYY-MM-DD.json过滤和打分段读这个文件处理后写到processed/YYYY-MM-DD.json生成段读 processed 文件输出daily/YYYY-MM-DD.md。每一段都可以单独重跑比如我觉得今天打分有问题改完规则直接重跑打分和生成两段就行不用重新抓取。这个设计还有一个好处历史数据可回溯。我想看看三个月前某条内容当时的打分是多少直接翻对应的 processed 文件就行。如果用了数据库反而要多写查询代码。3. 核心细节解析过滤规则与打分算法的实操要点3.1 关键词体系的搭建与维护关键词体系是整个筛选逻辑的地基。我最开始只用了几个核心词比如“Agent”“LLM”“大模型”结果漏掉了很多相关但没用这些词表述的内容。后来我建了一个三层关键词结构。第一层是核心词就是绝对相关的词命中就直接进入候选池。第二层是扩展词比如“多智能体”“工具调用”“推理链”“上下文窗口”这类命中一个加一定分数但不直接决定入选。第三层是排除词比如“招聘”“课程广告”“融资快讯”这类命中直接扣分甚至淘汰。关键词不是一成不变的。我每周会看一遍被淘汰的条目如果发现某条其实应该入选但被漏掉了就分析它为什么没被命中然后补充关键词。反过来如果某类内容频繁入选但我其实不想看就把它加到排除词里。这个维护过程大概每周花十分钟但效果非常明显。注意关键词匹配要做大小写不敏感处理同时要考虑中英文混排的情况。比如“Agent”和“agent”要视为同一个词“大模型”和“LLM”要根据你的实际关注方向决定是否等价。3.2 相关性打分的计算公式与参数调优打分公式我迭代了好几版目前用的是这个score base_score * source_weight keyword_bonus - exclude_penalty其中base_score默认是 1.0source_weight就是前面说的源权重keyword_bonus是命中扩展词的累加值每个扩展词加 0.2exclude_penalty是命中排除词的扣分每个扣 0.5。这个公式看起来简单但参数调起来有讲究。keyword_bonus的步长我试过 0.1、0.2、0.5最后发现 0.2 最合适——太小了区分度不够太大了几个词就能把一条低质量内容顶上去。exclude_penalty我设成 0.5是因为我不想一棍子打死有些内容虽然带了排除词但可能确实有价值扣分但不直接淘汰给它一个“将功补过”的机会。阈值我定在 1.5。低于这个分数的条目不进日报。这个阈值也是调出来的定 1.0 的时候日报太长定 2.0 的时候又漏内容1.5 是我实测下来比较平衡的点。3.3 去重与相似内容的合并策略去重这块我吃过亏。最开始只按 URL 去重结果同一件事被不同源报道日报里出现三四条读起来很烦。后来我加了一层标题相似度去重。具体做法是把标题转成小写去掉标点和停用词然后算两个标题的 Jaccard 相似度。相似度超过 0.7 的视为同一事件只保留分数最高的那条同时在日报里标注“另有 N 条相关报道”。Jaccard 相似度的计算很简单就是两个集合的交集大小除以并集大小。比如标题 A 的词集合是 {agent, 记忆, 机制}标题 B 是 {agent, 记忆, 模块}交集是 {agent, 记忆}并集是 {agent, 记忆, 机制, 模块}相似度就是 2/4 0.5不到 0.7不合并。如果 B 是 {agent, 记忆, 机制}那相似度就是 3/3 1.0合并。这个阈值 0.7 也是试出来的。太低会误合并不同事件太高又起不到去重效果。0.7 在我的数据上表现最好。4. 实操过程从零搭建一套可运行的日报系统4.1 环境准备与依赖安装我用的是 Python版本 3.10 以上。依赖不多核心就几个pip install requests beautifulsoup4 feedparser python-dateutilrequests用来发 HTTP 请求beautifulsoup4用来解析 HTMLfeedparser用来解析 RSSpython-dateutil用来处理时间。如果你要抓的源主要是 RSS那feedparser基本就够了如果是网页就需要requestsbeautifulsoup4组合。我不建议一上来就上 Scrapy 这种重框架除非你要抓的源特别多、特别复杂。对于个人日报这种场景轻量脚本完全够用而且调试起来快得多。4.2 抓取模块的实现与容错处理抓取模块的核心逻辑是遍历源列表对每个源发请求拿到内容后统一成标准结构。这里有几个实操细节值得说。第一一定要设超时。我默认设 10 秒超过就放弃这个源记录一条错误日志继续抓下一个。不设超时的话某个源响应慢会把整个脚本卡死。第二要处理编码问题。有些源返回的编码和声明的不一致直接解码会乱码。我的做法是先按response.encoding解如果出现乱码特征比如大量问号再用response.apparent_encoding重试。第三要加请求头。不加的话很多源会直接拒绝。我一般加一个常见的 User-Agent模拟正常浏览器访问。import requests from bs4 import BeautifulSoup def fetch_source(url, timeout10): headers { User-Agent: Mozilla/5.0 (compatible; TechRadar/1.0) } try: resp requests.get(url, headersheaders, timeouttimeout) resp.raise_for_status() if resp.encoding and resp.encoding.lower() ! utf-8: resp.encoding resp.apparent_encoding return resp.text except Exception as e: print(f抓取失败: {url}, 原因: {e}) return None这段代码我用了很久稳定性不错。关键就是那个try-except任何异常都吞掉并记录不让单个源的失败影响整体。4.3 过滤与打分模块的代码实现过滤和打分我放在一个函数里做因为两者逻辑紧密相关。输入是原始条目列表输出是打过分的条目列表。CORE_KEYWORDS [agent, llm, 大模型, 多智能体] EXTEND_KEYWORDS [工具调用, 推理链, 上下文窗口, 记忆机制, 规划] EXCLUDE_KEYWORDS [招聘, 课程, 广告, 融资快讯] SOURCE_WEIGHTS { official_blog: 1.0, community: 0.6, newsletter: 0.7, } def score_item(item): text (item[title] item.get(raw_content, )).lower() if not any(kw in text for kw in CORE_KEYWORDS): return None base 1.0 source_weight SOURCE_WEIGHTS.get(item[source_type], 0.5) keyword_bonus sum(0.2 for kw in EXTEND_KEYWORDS if kw in text) exclude_penalty sum(0.5 for kw in EXCLUDE_KEYWORDS if kw in text) score base * source_weight keyword_bonus - exclude_penalty item[score] round(score, 2) return item if score 1.5 else None这段代码的逻辑很直白先检查核心词没有就直接扔掉有的话算分分数不够也扔掉。round(score, 2)是为了让分数好看一点方便调试时对比。4.4 日报生成与排版输出生成模块负责把选中的条目按主题分组输出成 Markdown。分组逻辑我用的还是关键词——如果标题里包含“记忆”“上下文”就归到“记忆与上下文”组包含“工具”“调用”就归到“工具与调用”组以此类推。没有命中任何分组关键词的归到“其他”。GROUPS { 记忆与上下文: [记忆, 上下文, memory, context], 工具与调用: [工具, 调用, tool, function], 规划与推理: [规划, 推理, planning, reasoning], } def generate_daily(items, date_str): groups {name: [] for name in GROUPS} groups[其他] [] for item in sorted(items, keylambda x: -x[score]): placed False for group_name, keywords in GROUPS.items(): if any(kw in item[title].lower() for kw in keywords): groups[group_name].append(item) placed True break if not placed: groups[其他].append(item) lines [f# Agent / LLM 技术精选日报 · {date_str}\n] for group_name, group_items in groups.items(): if not group_items: continue lines.append(f## {group_name}\n) for item in group_items: lines.append(f- [{item[title]}]({item[url]}) score: {item[score]}) lines.append() return \n.join(lines)输出格式我刻意保持简洁每条就是标题加链接加分数。分数放在那里是为了让我自己知道这条为什么入选也方便我后续调参时回溯。5. 常见问题与排查技巧实录5.1 抓取失败与反爬应对抓取失败是最常见的问题。我遇到过的原因大概有这么几类网络超时、返回 403、返回内容为空、返回内容不是预期的 HTML。网络超时前面说了设 timeout 就行。403 一般是请求头的问题加上 User-Agent 基本能解决大部分。返回内容为空可能是源本身挂了也可能是被限流了我的做法是记录日志连续三天都失败的源就暂时禁用过一周再试。还有一种情况是返回的内容是 JavaScript 渲染出来的直接抓 HTML 拿不到数据。这种源我一般直接放弃因为为了一个源上无头浏览器成本太高不值得。我的原则是如果一个源需要我花超过半小时去适配就砍掉它。5.2 打分偏差的调试方法打分偏差表现为两种该进的没进不该进的进了。我的调试方法是每天人工抽查。具体做法是每天日报生成后我花五分钟快速扫一遍如果发现某条明显该进但没进就去 processed 文件里找它看它的分数是多少为什么没到阈值。常见原因是关键词没命中那就补关键词或者是源权重太低那就调权重。反过来如果发现某条不该进但进了就看它为什么分数高。常见原因是命中了太多扩展词但内容其实很水这时候要么把某些扩展词降权要么把它加到排除词里。这个抽查过程听起来麻烦但每天就五分钟坚持两周之后你的规则就会变得非常准。5.3 日报内容同质化的破解思路同质化是日报做久了必然遇到的问题——每天都是类似的内容读起来没有新鲜感。我的破解思路是主动引入多样性。具体做法有两个。一是定期轮换信息源比如每个月换掉一个表现最差的源换一个新的进来试试。二是给不同主题设配额比如“记忆与上下文”最多三条“工具与调用”最多三条避免某个热门主题刷屏。还有一个技巧是故意保留一些低分但视角独特的内容。比如某条内容分数只有 1.6刚过阈值但它的角度很新颖我就会手动把它提到日报前面。这种人工干预不多但能有效打破算法的惯性。5.4 常见问题速查表问题现象可能原因排查方法解决方案抓取返回空源挂了或被限流手动访问源地址记录日志连续失败则禁用抓取返回 403缺少请求头检查 headers添加 User-Agent内容乱码编码不一致检查 response.encoding用 apparent_encoding 重试该进日报的没进关键词未命中或分数不够查 processed 文件中的分数补关键词或调权重不该进的进了扩展词命中过多查分数构成降扩展词权重或加排除词日报同质化信息源单一或主题集中看最近一周的日报轮换源、设主题配额去重不彻底相似度阈值太高看重复条目的相似度降低阈值到 0.6 试试脚本跑一半卡住某个源响应慢看日志最后一条设 timeout加异常捕获这张表是我踩坑踩出来的基本上覆盖了 90% 的日常问题。遇到新问题我会往表里加一行慢慢就成了一本自己的运维手册。6. 一些实操心得与后续扩展方向这套系统我跑了快两年最大的体会是规则要简单维护要勤快。我见过有人把打分逻辑写得极其复杂几十个参数结果调参调到崩溃。我的做法是保持公式简单靠每天五分钟的抽查来微调反而更稳定。另一个心得是不要追求全自动。我一开始想做到完全无人值守后来发现完全自动的日报质量总差那么一点。现在我保留了一个人工干预的环节——日报生成后我会快速扫一遍手动调整几条的排序或分组。这个环节花不了几分钟但日报的可读性提升非常明显。后续扩展的话我打算加一个趋势追踪功能统计某个关键词在过去一周、一个月内的出现频率如果频率突然上升就在日报里加一个“趋势提醒”板块。这个功能不需要多复杂就是简单的计数和对比但能帮我更早发现热点。还有一个想法是个性化推荐根据我过去点击和阅读的行为自动调整源权重和关键词权重。这个稍微复杂一点需要记录我的交互数据但逻辑上不难就是给每个源和每个关键词维护一个动态权重我点得多的就加权不点的就降权。最后分享一个小技巧如果你不想写代码这套逻辑用表格软件也能实现大半。把抓取到的内容贴进表格用公式做关键词匹配和打分用筛选功能做过滤用排序功能做优先级排列。效果肯定不如脚本但胜在零门槛适合先跑通流程再考虑自动化。我个人在实际操作中的体会是这套东西的价值不在于技术多复杂而在于它逼着你把“我到底关注什么”这个问题想清楚。关键词体系、源权重、分组逻辑每一个都是在回答这个问题。想清楚了系统自然就好用了。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询