AI Agent智能搜索与信息萃取:Yandex+Ollama实现网页内容结构化压缩
2026/5/9 4:27:39 网站建设 项目流程

1. 项目概述:一个为AI Agent量身定制的“智能搜索与信息萃取”工具箱

最近在折腾AI Agent(智能体)项目,发现一个挺普遍又头疼的问题:想让Agent去网上查点资料,要么搜索结果太零碎,只有标题和摘要,信息量不够;要么就是一股脑把整个网页的HTML都塞给Agent,动辄几千上万个Token,不仅处理慢、成本高,还让Agent在大量无关的导航栏、广告、脚本代码里“迷路”,抓不住重点。

如果你也遇到过类似情况,那今天分享的这个开源项目qwexs/yandex-search-webscraper-skill可能正是你需要的。它本质上是一对为OpenClaw框架设计的Agent技能(Skill),但设计思路非常通用,完全可以独立运行或集成到其他AI工作流中。核心就两件事:第一,用Yandex Search API进行精准的网页搜索;第二,用一个本地运行的轻量级大模型(Ollama),把抓取到的网页“智能压缩”成结构化的关键信息,大幅节省上下文Token。简单说,它让AI Agent拥有了一个既会“精准搜索”又会“提炼要点”的智能助理。

2. 核心设计思路:为什么“搜索+智能萃取”是黄金组合?

在深入代码之前,我们先聊聊背后的设计哲学。很多开发者给Agent加网络能力,容易走两个极端:要么只给个搜索API返回的简短摘要(Snippet),信息深度不足;要么直接用fetch把整个网页丢进去,信息噪音太大。这个项目的聪明之处在于,它采用了一个分阶段、渐进式的信息获取策略。

2.1 传统方案的痛点分析

假设你的Agent需要了解“AMD Zen 6架构的最新传闻”。传统做法可能是:

  1. 仅使用搜索摘要:从搜索引擎拿到5条结果,每条只有50-100个单词的摘要。Agent只知道“某网站提到了Zen 6”,但具体爆料了哪些核心参数、发布时间、工艺节点等细节一概不知,无法进行深度分析和推理。
  2. 全量抓取网页:把排名前3的网页整个HTML(可能包含CSS、JS、多栏布局)都下载下来,通过web_fetch之类的工具塞给Agent。一个中等长度的新闻或论坛页面,经过HTML净化后,文本内容也可能达到5000到30000个Token。这不仅消耗了Agent宝贵的上下文窗口(想想GPT-4 Turbo的128K窗口也很珍贵),更关键的是,大量无关文本(如相关文章推荐、用户评论、页脚版权信息)会严重干扰Agent对核心内容的判断。

2.2 本项目的“瘦身”与“结构化”之道

这个项目提出的方案是“搜索定位 + 智能萃取”

  1. 第一阶段:精准搜索(Yandex Search):利用Yandex Search API(它对俄语及东欧内容有优势,且对中文等支持也不错)快速定位与查询最相关的10个网页,获取URL和摘要。这一步成本极低,速度很快。
  2. 第二阶段:智能萃取(Web Scraper):对于其中最重要的几条结果(比如前3条),并不获取全文,而是启动本地的web-scraper技能。这个技能会做两件关键事:
    • 语义化内容定位:它不是简单粗暴地删除<script><style>标签,而是用一套启发式规则(寻找<article>,<main>,.post-content,#content等语义化标签)去定位网页的核心内容区块。这步操作直接过滤掉了至少70%的页面噪音。
    • 大模型信息结构化提取:将定位到的核心内容区块文本,发送给本地运行的Ollama模型(richardyoung/schematron-3b)。这个模型被专门提示(Prompt)去从文本中提取结构化的JSON信息,通常包括:title(标题)、description(描述)、main_content(主要内容)、links(文内链接)、images(图片信息)、metadata(元数据)等。

这样一番操作下来,原本需要5000+ Token的网页,被压缩成了一个300-800 Token、高度结构化、只包含干货的JSON对象。Agent接收到的信息密度极高,处理速度和准确性自然就上去了。官方给出的数据是10到40倍的Token节省,在实际使用中,对于内容型页面(新闻、博客、文档),节省20倍以上是常态。

注意:这里的选择非常务实。使用本地Ollama模型进行提取,而不是调用昂贵的云端大模型API(如GPT-4),使得大量、频繁的网页内容提取变得经济可行,且没有网络延迟和隐私泄露风险。schematron-3b这个3B参数量的模型,在信息提取这类结构化任务上表现足够好,且对硬件要求极低。

3. 环境准备与项目初始化

理论讲完了,我们来看看怎么把它用起来。整个项目基于Bun运行时,并依赖本地Ollama服务。

3.1 基础环境搭建

首先,确保你的系统已经安装好以下两个核心依赖:

  1. 安装 Bun:如果你还没用上Bun这个新兴的JavaScript运行时,现在是个好机会。它比Node.js启动更快,内置了打包、测试等工具链。去 官网 按照指引安装即可,通常就是一行终端命令。
  2. 安装并配置 Ollama:前往 Ollama官网 下载安装。安装完成后,你需要拉取项目指定的信息提取模型:
    ollama pull richardyoung/schematron-3b:Q4_K_M
    这个命令会下载一个约2GB左右的模型文件。Q4_K_M是一种量化格式,在保持较高精度的同时显著减少了模型体积和内存占用,非常适合本地部署。下载完成后,记得启动Ollama服务(通常安装后会自动运行)。

3.2 获取项目代码与依赖安装

接下来,获取项目代码并安装依赖:

# 克隆仓库 git clone https://github.com/qwexs/yandex-search-webscraper-skill.git cd yandex-search-webscraper-skill # 安装项目依赖(使用Bun) bun install

项目结构很清晰,主要就是两个目录:

  • yandex-search/:包含与Yandex搜索API交互的所有脚本。
  • web-scraper/:包含智能网页抓取与内容提取的核心逻辑。

3.3 Yandex Search API 密钥配置

yandex-search技能需要API密钥才能工作。你需要一个Yandex Cloud账号。

  1. 复制配置文件模板

    cd yandex-search cp config.example.json config.json
  2. 获取API Key和Folder ID:这是最需要耐心的一步。按照项目README的指引,你需要使用Yandex Cloud CLI (yc)。如果你不熟悉,其核心步骤是:

    • 安装并配置ycCLI,完成身份认证。
    • 创建一个专门的服务账号(Service Account),例如叫search-bot
    • 给这个服务账号授予在你某个云文件夹(Folder)下的search-api.webSearch.user角色权限。
    • 最后为该服务账号创建一个API Key。

    浓缩后的关键命令序列大致如下(请根据你的实际文件夹ID调整):

    # 创建服务账号 yc iam service-account create --name search-bot # 获取你的文件夹ID,假设为 b1g... yc config get folder-id # 授予权限(将 <folder-id> 替换为你的ID) yc resource-manager folder add-access-binding <folder-id> \ --role search-api.webSearch.user \ --service-account-name search-bot # 创建API Key,输出结果中的`key_id`和`secret`就是你要的 yc iam api-key create --service-account-name search-bot
  3. 填写配置:将上一步得到的secret(即API Key)和你的folder-id填入yandex-search/config.json文件。

    { "apiKey": "你的API密钥(即secret)", "folderId": "你的云文件夹ID" }

实操心得:Yandex Cloud的控制台对英语用户可能不太友好,但CLI工具yc的文档很完善。如果卡在权限配置上,请务必仔细阅读Yandex Cloud关于IAM(身份和访问管理)的文档,确保服务账号、文件夹、角色三者关系正确。这是整个配置过程中唯一的“坎儿”。

4. 核心技能详解与实战操作

环境配好了,我们来逐个拆解这两个技能怎么用,以及它们内部是如何工作的。

4.1 Web Scraper:智能信息萃取器

这个技能是项目的“智慧大脑”。它不负责搜索,只负责把一个给定的URL,变成一份结构清晰的“内容简报”。

基本使用

# 进入web-scraper目录执行,或使用项目根目录的相对路径 bun web-scraper/scripts/scrape.js --url https://nvworld.ru/

执行后,终端会输出一个JSON对象。这个JSON就是经过Ollama模型处理后的结构化信息。例如,对于一个新闻网站,你可能会得到:

{ "title": "МИР NVIDIA — продукция NVIDIA, RivaTuner, железо, игры", "description": "关于NVIDIA产品、游戏和硬件的新闻社区", "main_content": "Согласно новому слуху, архитектура AMD Zen 6...(根据最新传闻,AMD Zen 6架构将采用...)", "links": [ {"text": "详细阅读", "href": "/article/123"}, {"text": "官方论坛", "href": "https://forum.nvworld.ru"} ], "images": [ {"src": "/images/zen6-chip.jpg", "alt": "AMD Zen 6芯片示意图"} ], "metadata": { "author": "编辑部", "publish_date": "2023-10-27" } }

高级参数解析

  • --prompt <text>:你可以自定义发送给Ollama模型的提取指令。默认的Prompt已经过优化,能很好地提取标题、正文、链接等。但如果你只想提取文章中的日期和人物名字,可以尝试自定义Prompt,例如:--prompt “从以下HTML中提取发布日期和涉及的主要公司名称,以JSON格式输出:{date: string, companies: array}”。这给了你很大的灵活性。
  • --compact:输出压缩后的JSON,没有换行和缩进,节省屏幕空间。
  • --no-retry:默认情况下,如果提取失败(如网络超时、模型错误),脚本会重试一次。此标志禁用重试。

内部工作流程揭秘

  1. fetch-html.js:这是幕后英雄。它首先用fetch获取网页原始HTML。然后,它做了一个字符集自动检测(特别是对windows-1251等编码的俄语网站很重要),确保文本正确解码。最关键的一步是语义化内容定位:它不是一个简单的HTML清理器,而是尝试通过一系列CSS选择器(如article,main,[role=\"main\"],.post-content,.article-body,#mw-content-text(维基百科专用)等)来寻找包裹核心内容的DOM元素。找到后,只提取该元素内的文本,极大提升了后续处理的质量。
  2. extract.js:将上一步得到的纯净文本,连同预设的(或用户自定义的)系统提示词(System Prompt),一起发送给本地Ollama服务的schematron-3b模型。这个模型被训练/提示来理解和执行“从文本中提取结构化信息”的任务。最后,它负责解析模型的返回,并将其封装成格式良好的JSON。

注意事项:智能提取的准确性依赖于模型能力和网页结构。对于结构非常规或大量使用JavaScript渲染的动态网页(如单页应用SPA),fetch-html.js可能无法获取到有效内容,因为它的fetch只能拿到初始HTML。这种情况下,你可能需要更高级的无头浏览器(如Puppeteer)方案,但那就违背了本工具“轻量、快速”的初衷。

4.2 Yandex Search:智能区域化搜索

这个技能是项目的“侦察兵”。它封装了Yandex Search API,并增加了一些实用功能。

基础搜索

# 基础搜索,返回10条文本格式结果 bun yandex-search/search.js "AMD Zen 6" # 限制结果数量,并以JSON格式输出,便于程序处理 bun yandex-search/search.js "AMD Zen 6 архитектура" --limit=5 --format=json # 指定搜索区域(如土耳其) bun yandex-search/search.js "AMD Zen 6" --region=tr --format=markdown

智能搜索(smart-search): 这是更推荐的方式,它多了一个自动区域检测的功能。

bun yandex-search/smart-search.js "AMD Zen 6 архитектура"

smart-search.js会分析你的查询词:如果包含西里尔字母(俄语等),它自动使用ru(俄罗斯)区域;如果是拉丁字母,则使用com(国际)区域。这能显著提升相关语言内容的搜索结果质量。

搜索与萃取的联动作业(核心功能): 这才是整套工具的威力所在。通过一个--scrape标志,将搜索和萃取无缝连接。

# 搜索“AMD Zen 6”,并智能提取前3条结果的完整内容 bun yandex-search/smart-search.js "AMD Zen 6" --scrape --scrape-top=3

这个命令的执行流程如下:

  1. 调用smart-search.js,它内部会调用search.js
  2. search.js使用你的API密钥向Yandex发起搜索请求,获取到URL列表和摘要。
  3. smart-search.js检测到--scrape标志,于是对排名前--scrape-top(此处为3)的每个结果URL,启动一个web-scraper/scripts/scrape.js进程。
  4. 每个scrape.js进程独立工作,获取并提炼该网页内容。
  5. 最后,smart-search.js将原始的搜索结果与提炼后的详细内容(scraped_content字段)合并,输出最终结果。

最终你得到的每条结果,不仅包含来自Yandex的标题、链接和摘要,还包含了一个由本地模型生成的、高度浓缩的scraped_contentJSON对象。你的AI Agent可以直接消费这个结构化数据,无需再面对海量原始HTML。

5. 集成到AI Agent工作流:以OpenClaw为例

虽然这两个技能可以独立运行,但它们的初衷是作为OpenClaw Agent的“技能”(Skill)。这里简要说明一下集成思路,这对于想构建自主AI Agent的开发者很有参考价值。

在OpenClaw框架中,一个Skill通常是一个可以执行特定任务的模块。你需要将这两个技能“注册”到你的Agent配置中。

  1. 技能声明:在你的Agent配置文件(例如agent.yaml)中,添加这两个技能,并定义它们所需的参数(如API密钥路径、Ollama服务地址)。
  2. 任务规划:当Agent判断需要搜索网络信息时(例如用户问“AMD Zen 6有什么新消息?”),它的规划器(Planner)可以决定调用yandex-search技能。
  3. 技能链调用:在调用yandex-search时,通过参数(如{"query": "AMD Zen 6", "scrape": true, "scrape_top": 3})触发联动。OpenClaw的执⾏器(Executor)会先运行搜索,然后根据返回的URL列表,自动、并发地调用web-scraper技能。
  4. 结果整合:所有结果(搜索摘要+提炼内容)被汇总,放回Agent的上下文(Context)中。Agent的LLM核心(如GPT-4)现在就能基于这些高质量、高密度的信息进行推理、总结或回答,而不会被无关信息干扰。

这种设计使得Agent的能力扩展变得非常清晰和模块化。你可以轻松地为Agent添加其他技能,如数据库查询、计算、邮件发送等,构建出功能强大的自主智能体。

6. 常见问题、优化与排查指南

在实际部署和使用中,你可能会遇到一些问题。以下是一些常见情况的排查方法和优化建议。

6.1 搜索相关问题

问题现象可能原因解决方案
搜索返回403Invalid API Key错误1. API密钥错误或过期。
2. 服务账号没有正确的权限。
3.folderId配置错误。
1. 检查config.json中的apiKey是否填写正确(是secret,不是key_id)。
2. 在Yandex Cloud控制台,确认服务账号已被授予目标文件夹的search-api.webSearch.user角色。
3. 确认folderId与授权时的文件夹ID一致。
搜索结果数量少或质量差1. 查询词不准确。
2. 区域(region)设置不当。
1. 尝试使用更具体、包含关键技术的查询词。
2. 对于俄语内容,使用--region=ru或让smart-search自动检测。对于全球性技术话题,使用--region=com
smart-search区域检测错误查询词混合了多种语言字符。手动指定--region参数,覆盖自动检测。

6.2 网页抓取与提取问题

问题现象可能原因解决方案
scrape.js返回空或极短的main_content1. 网页是动态加载(SPA)。
2. 网站有反爬机制。
3. 语义化内容定位失败。
1. 这是本工具的局限。对于复杂JS渲染页,考虑使用Puppeteer等无头浏览器方案先获取完整HTML,再交给本工具提取。
2. 检查网络,尝试添加--no-retry看具体错误。
3. 可以尝试修改fetch-html.js中的CSS选择器列表,添加目标网站特有的内容容器类名。
Ollama模型提取错误或格式不对1. Ollama服务未运行。
2. 模型未加载。
3. 自定义Prompt格式有误。
1. 运行ollama serve确保服务在后台运行。
2. 运行ollama list确认richardyoung/schematron-3b:Q4_K_M模型存在。
3. 使用默认Prompt测试,如果正常,再检查你的自定义Prompt是否符合模型预期的指令格式。
提取过程非常慢1. 模型首次加载需要时间。
2. 网页内容过长。
3. 硬件性能不足。
1. 第一次调用后,模型会常驻内存,后续调用会快很多。
2.fetch-html.js已经做了内容截断,但如果原始页面核心内容仍很长,模型处理需要时间。考虑是否必要。
3. 3B模型对CPU要求不高,但GPU会快很多。确保Ollama能使用GPU(如果可用)。
处理中文网站乱码字符集检测失败。fetch-html.js内置了常见字符集检测,但对某些中文网站可能失效。可以尝试手动修改该文件,在解码环节强制指定charset: ‘utf-8’进行测试。

6.3 性能与优化建议

  1. 并发控制:当使用--scrape-top=5时,脚本会顺序抓取5个页面。你可以考虑修改smart-search.js,使用Promise.allBun.spawn进行有限度的并发抓取,以缩短总耗时。
  2. 缓存策略:对于频繁查询的相同URL,可以添加一个简单的文件缓存或内存缓存(如使用node-cache),避免重复调用Ollama模型,显著提升响应速度。
  3. 模型替代schematron-3b是一个不错的平衡选择。如果你有更强的显卡(如8GB以上显存),可以尝试更大的模型(如7B、13B参数),可能获得更准确、更稳定的提取结果。只需修改web-scraper中调用Ollama的模型名称即可。
  4. 错误处理与重试:默认的重试机制(--no-retry禁用)对于偶发的网络波动很有效。但对于持续失败的URL,应考虑加入更完善的错误日志和跳过机制,避免单个失败任务阻塞整个流程。

这个项目提供了一个极其优雅的思路和一套可立即运行的实现,将昂贵的、耗时的网页信息消费,变成了一个高效的、结构化的过程。它不仅仅是一个工具,更是一种为AI Agent设计外部信息获取能力的范式。你可以直接使用它,也可以借鉴其“搜索定位 -> 智能萃取”的分层思想,用不同的搜索引擎(如Google Programmable Search)和不同的提取模型(如云端API)来构建属于你自己的Agent信息流水线。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询