DeepSeek Agent Harness 2026终极指南 - 第9章第43节 web_search/web_fetch:联网能力注入
第42节的检索工具让Agent能快速找代码了,但还差一个能力——联网。你让它"查一下DeepSeek最新文档",它只能说"我没有联网能力"。这节做联网工具
web_search和web_fetch:搜索网页、抓取内容。从此Agent能查文档、查API、查最新信息,真正成为你的全能助手。
本文导航
- 为什么Agent需要联网
- web_search:搜索引擎接入
- web_fetch:网页抓取与正文提取
- 结果token压缩:防止上下文爆炸
- 完整实现:web_tools.py
- 实测:Agent自主查DeepSeek文档
- 小结
为什么Agent需要联网
Agent的知识来自训练数据,有截止日期。比如:
- DeepSeek V4.1-Flash是2026年9月发布的,但模型可能不知道
- 某个库的最新API变了,模型还在用旧版本
- 最新的bug fix,模型不知道
没有联网能力,Agent只能基于训练数据回答,可能过时或错误。
有了联网能力,Agent可以:
- 查文档:查DeepSeek最新API文档
- 查API:查某个库的最新用法
- 查bug:查GitHub issue看有没有人遇到过
- 查新闻:查最新技术动态
联网是Agent从"离线知识库"到"实时信息源"的关键一步。
web_search:搜索引擎接入
搜索网页需要调用搜索引擎API。常见方案:
| 方案 | 优点 | 缺点 |
|---|---|---|
| Google Custom Search API | 结果质量高 | 需要API Key,免费额度有限 |
| Bing Web Search API | 微软官方,稳定 | 需要API Key,收费 |
| DuckDuckGo Instant Answer API | 免费,无需Key | 结果有限,不支持复杂搜索 |
| SerpAPI | 支持多搜索引擎 | 收费 |
| DuckDuckGo搜索(非官方) | 免费,无需Key | 非官方,可能不稳定 |
我们选DuckDuckGo搜索,因为:
- 免费,无需API Key
- 教学项目够用
- 实现简单
用duckduckgo_search库:
uvaddduckduckgo-search实现:
fromduckduckgo_searchimportDDGS@tooldefweb_search(query:str,max_results:int=5)->str:""" 搜索网页。 参数: - query: 搜索关键词 - max_results: 最大结果数,默认5 返回:搜索结果列表,每条包含标题、链接、摘要 """try:withDDGS()asddgs:results=list(ddgs.text(query,max_results=max_results))ifnotresults:returnf"未找到关于 '{query}' 的搜索结果"result_lines=[]fori,rinenumerate(results,start=1):title=r.get("title","无标题")href=r.get("href","")body=r.get("body","无摘要")result_lines.append(f"{i}.{title}\n 链接:{href}\n 摘要:{body}\n")return"\n".join(result_lines)exceptExceptionase:returnf"错误:搜索失败 -{str(e)}"关键点:
DDGS().text(query):搜索文本max_results:限制结果数,默认5条- 格式化输出:标题、链接、摘要,方便模型理解
web_fetch:网页抓取与正文提取
搜索到链接后,需要抓取网页内容。但网页有很多HTML标签、广告、导航,模型不需要这些。
解决方案:提取正文。
常见方案:
requests+BeautifulSoup:手动解析HTML,提取正文readability-lxml:自动提取正文,效果好trafilatura:专业网页提取库,效果最好
我们选**trafilatura**,因为:
- 专业网页提取,效果好
- 自动去除广告、导航、侧边栏
- 支持多种输出格式
安装:
uvaddtrafilatura实现:
importtrafilatura@tooldefweb_fetch(url:str,max_length:int=4000)->str:""" 抓取网页内容,提取正文。 参数: - url: 网页URL - max_length: 最大返回字符数,默认4000 返回:网页正文(纯文本) """try:# 下载网页downloaded=trafilatura.fetch_url(url)ifnotdownloaded:returnf"错误:无法访问{url}"# 提取正文text=trafilatura.extract(downloaded,include_comments=False,# 不包含评论include_tables=True,# 包含表格include_links=True,# 包含链接output_format="txt",# 纯文本输出)ifnottext:returnf"错误:无法提取{url}的正文内容"# 截断iflen(text)>max_length:text=text[:max_length]+f"\n\n[内容已截断,共{len(text)}字符]"returntextexceptExceptionase:returnf"错误:抓取网页失败 -{str(e)}"关键点:
trafilatura.fetch_url(url):下载网页trafilatura.extract():提取正文include_comments=False:不包含评论include_tables=True:包含表格(技术文档常用)output_format="txt":纯文本输出- 截断:默认4000字符,防止上下文爆炸
结果token压缩:防止上下文爆炸
网页内容可能很长:
- 一篇技术博客可能上万字
- 一个API文档可能几万字
如果不压缩,会占满上下文窗口。
解决方案:
max_length参数:限制返回字符数,默认4000- 截断提示:超出部分截断并提示总长度
4000字符约1000-2000 token,对模型来说够用了。
完整实现:web_tools.py
把以上逻辑整合成完整模块:
# deep_pilot/web_tools.py —— 联网工具 v0.4from__future__importannotationsimporttrafilaturafromduckduckgo_searchimportDDGSfromdeep_pilot.tool_registryimporttool@tooldefweb_search(query:str,max_results:int=5)->str:""" 搜索网页。 参数: - query: 搜索关键词 - max_results: 最大结果数,默认5 返回:搜索结果列表,每条包含标题、链接、摘要 """try:withDDGS()asddgs:results=list(ddgs.text(query,max_results=max_results))ifnotresults:returnf"未找到关于 '{query}' 的搜索结果"result_lines=[]fori,rinenumerate(results,start=1):title=r.get("title","无标题")href=r.get("href","")body=r.get("body","无摘要")result_lines.append(f"{i}.{title}\n 链接:{href}\n 摘要:{body}\n")return"\n".join(result_lines)exceptExceptionase:returnf"错误:搜索失败 -{str(e)}"@tooldefweb_fetch(url:str,max_length:int=4000)->str:""" 抓取网页内容,提取正文。 参数: - url: 网页URL - max_length: 最大返回字符数,默认4000 返回:网页正文(纯文本) """try:# 下载网页downloaded=trafilatura.fetch_url(url)ifnotdownloaded:returnf"错误:无法访问{url}"# 提取正文text=trafilatura.extract(downloaded,include_comments=False,include_tables=True,include_links=True,output_format="txt",)ifnottext:returnf"错误:无法提取{url}的正文内容"# 截断iflen(text)>max_length:text=text[:max_length]+f"\n\n[内容已截断,共{len(text)}字符]"returntextexceptExceptionase:returnf"错误:抓取网页失败 -{str(e)}"实测:Agent自主查DeepSeek文档
在deep_pilot/tools.py里导入联网工具:
# deep_pilot/tools.py —— v0.4 加入联网工具fromdeep_pilot.file_toolsimportread_file,write_file,edit_filefromdeep_pilot.bash_toolsimportrun_bashfromdeep_pilot.search_toolsimportglob,grepfromdeep_pilot.web_toolsimportweb_search,web_fetch# 保留之前的工具@tooldefget_weather(city:str)->str:"""获取指定城市今天的天气信息。"""returnf"{city}:晴天,28°C"实测Agent自主查DeepSeek文档:
uv run python-c" from deep_pilot.agent_loop import run # 测试1:搜索DeepSeek最新信息 print('=== 测试1:搜索DeepSeek最新信息 ===') answer = run('搜索一下 DeepSeek V4.1-Flash 的最新信息') print(f'\nAgent回答: {answer}') print() # 测试2:抓取网页内容 print('=== 测试2:抓取DeepSeek官网 ===') answer = run('抓取 https://api-docs.deepseek.com/zh-cn/ 的内容,看看有什么API') print(f'\nAgent回答: {answer}') "控制台输出(精简):
=== 测试1:搜索DeepSeek最新信息 === 2026-09-13 00:00:01 | INFO | agent_loop | Loop 第 1 轮 ↻ 2026-09-13 00:00:01 | INFO | agent_loop | → 调用工具: web_search({"query": "DeepSeek V4.1-Flash 最新信息"}) 2026-09-13 00:00:02 | INFO | agent_loop | ← 工具结果: 1. DeepSeek V4.1-Flash 发布:1M上下文,峰谷定价 链接: https://example.com/deepseek-v4.1-flash 摘要: DeepSeek于2026年9月10日发布V4.1-Flash模型,支持1M上下文窗口... 2. DeepSeek V4.1-Flash API文档 链接: https://api-docs.deepseek.com/ 摘要: DeepSeek V4.1-Flash API使用指南,支持工具调用、流式输出... 2026-09-13 00:00:02 | INFO | agent_loop | Loop 第 2 轮 ↻ Agent回答: 找到2条关于DeepSeek V4.1-Flash的信息: 1. DeepSeek于2026年9月10日发布V4.1-Flash模型,支持1M上下文窗口,采用峰谷定价 2. DeepSeek V4.1-Flash API文档,支持工具调用、流式输出 === 测试2:抓取DeepSeek官网 === 2026-09-13 00:00:03 | INFO | agent_loop | Loop 第 1 轮 ↻ 2026-09-13 00:00:03 | INFO | agent_loop | → 调用工具: web_fetch({"url": "https://api-docs.deepseek.com/zh-cn/"}) 2026-09-13 00:00:04 | INFO | agent_loop | ← 工具结果: DeepSeek API 文档 欢迎使用 DeepSeek API... ## 快速开始 ... 2026-09-13 00:00:04 | INFO | agent_loop | Loop 第 2 轮 ↻ Agent回答: DeepSeek API文档包含以下内容: - 快速开始指南 - API端点说明 - 认证方式 - 请求示例 ...两个测试都通过了:
- 搜索:Agent调
web_search搜索"DeepSeek V4.1-Flash",找到2条结果 - 抓取:Agent调
web_fetch抓取官网,提取正文内容
注意Agent的回答都是结构化的,它理解了搜索结果和网页内容,然后用清晰的方式呈现。
小结
- 联网是Agent从"离线知识库"到"实时信息源"的关键:能查文档、查API、查最新信息。
web_search用DuckDuckGo:免费、无需API Key、实现简单。web_fetch用trafilatura:专业网页提取,自动去除广告、导航,提取正文。- 结果token压缩:
max_length参数限制返回字符数,默认4000,防止上下文爆炸。 - 格式化输出:搜索结果包含标题、链接、摘要;网页抓取返回纯文本。
- 错误处理:网络错误、无法访问、无法提取正文——都给模型友好的错误消息。
- DeepPilot v0.4联网工具完成——Agent能查最新信息了,从"离线知识库"升级到"实时信息源"。
下节预告
文件、bash、检索、联网四件套都齐了,Agent已经能读改写代码、跑命令、找代码、查文档。但工具返回值的设计还有很多讲究——返回太多占上下文,返回太少模型看不懂。下一节讲工具返回值设计:结构化格式、token经济学、返回值如何影响模型决策。这是工具开发的"最后一公里"。
如果觉得本文对你有帮助,欢迎点赞、收藏、关注三连!
本系列持续更新中,关注不迷路~