news 2026/10/20 6:07:10

给Agent接一个搜索工具:DeepSeek搜索接口上手

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
给Agent接一个搜索工具:DeepSeek搜索接口上手

给Agent接一个搜索工具:DeepSeek搜索接口上手

原文:DeepSeek API Docs - 《网页搜索与抓取》(https://api-docs.deepseek.com/zh-cn/guides/search/)

前言

写 Agent 到第二个礼拜,几乎都会撞上同一堵墙:模型的知识停在训练截止那天,问它今天的事就开始编。解决办法无非两条——把私有资料塞进向量库做 RAG,或者给它一个能查公网的工具。

RAG 解决"我知道的",搜索解决"我不知道的"。真实项目里后者往往更急:用户问的是新闻、价格、版本号、文档最新写法,这些全在模型参数之外。

DeepSeek 在 10 月 17 日的 API 更新里放开了自研搜索能力,形态很干脆:两个 HTTP 接口,Search 负责按 query 搜,Fetch 负责把单个网页抓成 Markdown。不是 SDK 封装,就是原始 JSON API,Bearer 鉴权,和对话接口同一套 key。这篇笔记按官方指南把两个接口的请求、返回、计费和坑过一遍,最后接进一个最小的工具调用循环里。

一、两个接口,各管一段

接口地址作用
SearchPOST https://api.deepseek.com/v1/tools/search按 query 返回结构化搜索结果
FetchPOST https://api.deepseek.com/v1/tools/fetch抓单个网页,正文转 Markdown

两者都是只读请求,用同一套 Bearer 鉴权。计费按请求次数走,不按 token 也不按返回条数:Search 和 Fetch 都是每 1000 次成功请求 5 元。限速上,每个账号 Search 5 QPS、Fetch 5 QPS,两条通道独立计算,互不占额度。

这里有个容易被忽略的定义——什么叫"成功"。官方写得很清楚:只有返回 HTTP 200 且产生结果的请求才计费,Search 的 results 必须非空,Fetch 必须真的拿到网页正文;请求失败、搜索无结果、超时都不计费。

二、Search 的请求字段

# 最小可用调用:一次搜索,拿回 5 条带正文的结果importrequests response=requests.post("https://api.deepseek.com/v1/tools/search",headers={"Authorization":"Bearer <DeepSeek API Key>"},json={"query":"DeepSeek V4 模型 发布","count":5,"need_content":True,},)response.raise_for_status()forresultinresponse.json()["results"]:print(result["title"],result["url"])print(result["summary"])

四个参数值得逐个说:

  • query 是唯一必填项,1~128 个 Unicode 字符,不能全为空白;
  • count 默认 10,范围 1~50,只控制返回条数,不影响单次价格;
  • ori_question 是可选的"用户原始问题",1~128 字符,传了能让搜索服务更好理解意图,传 null 视同没传;
  • localization 传 IP 地址,用于优先返回本地化结果;
  • need_content 默认 false,此时 content 字段恒为空字符串——想要正文必须显式打开。

请求体里的未知字段会被直接忽略,这点挺宽容,但也意味着参数名打错了不会报错,只会静默失效。调试时值对不上,先核对字段名拼写。

三、query 里能写搜索语法

query 里的操作符会原样透传给搜索服务,可以组合使用:

操作符示例含义
site:DeepSeek site:github.com限定站点,多个用空格分隔并以 OR 连接
-site:DeepSeek -site:example.com排除站点
-DeepSeek -广告排除含该关键词的网页
-“…”DeepSeek -“release notes”排除含该短语的网页
“…”DeepSeek “精确短语”精确匹配短语
lang:DeepSeek lang:zh,en限定语言
after: / before:DeepSeek after:2025-01-01限定发布时间区间

对 Agent 来说,lang 和 after 这两个最实用。做技术问答时把 lang 卡到 zh,en,能挡掉大量机翻垃圾站;做时效性问题时加 after,比在提示词里反复叮嘱"只要最新的"有效得多。

四、返回值里哪几个字段真的有用

每条结果包含 rerank_score、title、url、snippet、summary、content、site_name、site_icon、date、authority 十个字段。全部塞给模型是浪费,我一般只留四个:

  • summary,长摘要,600~800 字符,官方定位就是"适用于给模型阅读";
  • rerank_score,0~3 分,综合相关性、权威性、时效性,大于等于 1.5 视为优质结果;
  • authority,0~4 的网页权威性,-1 表示未知,大于等于 3 是极权威结果;
  • date,UTC 的 RFC 3339 格式,未知时为 null。

snippet 是 100~200 字符的短摘要,更适合前端展示,没必要和 summary 一起塞进上下文。下面是按分数过滤并压成模型可读文本的写法:

# 只保留优质且权威的结果,并把字段压成模型友好的形状defcompact(results,min_score=1.5,min_authority=3):kept=[]forrinresults:ifr["rerank_score"]<min_score:continue# authority 为 -1 表示未知,这类结果不因权威性被丢弃ifr["authority"]!=-1andr["authority"]<min_authority:continuekept.append({"title":r["title"],"url":r["url"],"date":r["date"],"text":r["summary"],})returnkept

这段过滤逻辑是我自己加的,不是官方推荐值。实际调的时候会发现阈值和 query 类型强相关:查官方文档类问题,authority 卡到 3 很干净;查社区讨论(issue、论坛帖),authority 普遍偏低,硬卡 3 会把有用结果全砍掉,这时候应该只留 rerank_score 一个条件。

五、Fetch:把网页变成 Markdown

Search 拿到的 summary 是别人嚼过的,要做引用、要抓代码块,还是得读原文。Fetch 就干这件事:传一个 url,返回 title 和 content,content 是转好的 Markdown 正文。

url 长度不超过 8192,必须是含 host 的 HTTP/HTTPS URL,且不能携带用户名或密码。官方明确写了:Fetch 的结果受目标站点可用性和访问策略影响。

错误码比 Search 更需要区分对待:

状态码含义该不该重试
403Fetch 请求被安全策略拒绝不重试
404未能获取可用网页内容(URL 不可用、被站点拦、内容类型不支持、没有可提取正文)不重试
408 / 429 / 5xx超时、超 QPS、服务端错误退避后重试
402余额不足充值后再试

这条"4xx 不重试"的规则看起来废话,实际写循环时最容易忘。我第一版 Agent 就是无差别重试,遇上一个返回 403 的站点,把工具调用预算全烧在了同一个 URL 上。

六、接进工具调用循环

两个接口都是纯 HTTP,直接包成工具就行。下面用 OpenAI 兼容格式的接口示意,DeepSeek 的对话接口本身就是 OpenAI 兼容的:

# 示意写法:把 search 和 fetch 注册成两个工具,跑一个最小循环importjson TOOLS=[{"type":"function","function":{"name":"web_search","description":"搜索公网网页,返回标题、链接、日期和摘要。需要时效信息时使用。","parameters":{"type":"object","properties":{"query":{"type":"string","description":"搜索词,可带 site:/lang:/after: 语法"},"count":{"type":"integer","description":"返回条数,1-50"},},"required":["query"],},},},{"type":"function","function":{"name":"fetch_page","description":"抓取单个网页并返回 Markdown 正文。摘要不足以回答时使用。","parameters":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"],},},},]defrun_tool(name,args):ifname=="web_search":r=requests.post("https://api.deepseek.com/v1/tools/search",headers={"Authorization":f"Bearer{API_KEY}"},json={"query":args["query"],"count":args.get("count",5),"ori_question":args.get("ori_question"),"need_content":False},)r.raise_for_status()returnjson.dumps(compact(r.json()["results"]),ensure_ascii=False)ifname=="fetch_page":r=requests.post("https://api.deepseek.com/v1/tools/fetch",headers={"Authorization":f"Bearer{API_KEY}"},json={"url":args["url"]},)ifr.status_codein(403,404):return"抓取失败:该页面不可用,换一个来源"r.raise_for_status()page=r.json()returnpage["content"][:8000]# 截断,避免单页吃满上下文returnf"未知工具:{name}"

调用链是这样的:模型返回 tool_calls,外层按 name 分发到 run_tool,把结果包成 role=tool 的消息追加回 messages,再请求一次,直到模型不再调工具。

两个细节值得单独拎出来。第一,need_content 设成 false,正文留给 Fetch 单独抓——Search 阶段没人知道哪条值得读,预先拉 10 条正文既多花钱又多烧 token。第二,Fetch 的返回必须截断,一个长文档页面转成 Markdown 轻轻松松几万字符,不截断的话第二步就爆上下文了。

七、几个工程上的判断

成本会显性化。官方在计费段落里补了一句:目前用户在 DeepSeek Harness、Claude Code、Codex 里使用 DeepSeek API 时,已经通过服务端工具调用访问到 Search/Fetch,这部分暂不计费,将于北京时间 2026 年 11 月 1 日 00:00 起按次收取。也就是说,之前"白嫖"的那部分检索成本很快会变成账单上的一行,跑批量任务的脚本该提前算一下。

QPS 是账号粒度,不是 key 粒度。5 QPS 看着够用,但如果你同时开了几个 Agent 实例、每个都在并发搜,很容易撞 429。限速还跟模型并发限制相互独立,别以为模型那边没限就万事大吉。Fetch 另外还有目标域名级别的 QPS 限制。

搜索和 RAG 不是二选一。内部文档、权限隔离的语料、稳定的产品手册,走 RAG 更稳更便宜;开放域、时效性、长尾冷门问题,走 Search。常见的组合是 RAG 先召回,命中分数不够时兜底调一次搜索,把结果和本地片段一起交给模型。

提示词里要写清楚"什么时候不许搜"。工具一旦挂上,模型会倾向于每轮都搜一遍。给一句明确的边界,比如"仅当问题涉及发布日期、版本号、近期事件时调用搜索",能省下不少无意义的请求。

八、小结

DeepSeek 这次放出的两个接口,本质是把"检索"从模型能力里拆出来,做成一个可计费、可限速、可编排的基础设施。对 Agent 开发者来说,它的价值不在"多了个搜索源",而在于返回结构足够结构化——rerank_score 和 authority 两个分数,让你可以在工具层做过滤,而不是把判断全丢给模型。

真要上手,建议的路径是:先用 Search 跑通一次带 site: 和 after: 的查询,确认返回结构;再加 compact 过滤,看结果质量变化;最后才接进工具循环,并且第一步就把错误码分支和正文截断写进去。这三步走完,一个能查资料的 Agent 就成型了。

具体参数与限额以官方文档为准,接口行为后续可能调整,未验证最新版本。

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

Compose原生AI组件库:从架构设计到流式输出性能优化实战

1. 一个Compose原生AI组件库到底意味着什么移动端做AI功能集成&#xff0c;过去两年我踩过的坑比写过的业务代码还多。大多数团队的做法是&#xff1a;后端把模型能力封装成HTTP接口&#xff0c;客户端拿到JSON自己拼UI&#xff0c;或者干脆塞一个WebView把网页版对话界面嵌进来…

作者头像 李华
网站建设 2026/10/20 6:06:45

流量分析题实战:Wireshark抓包过滤与Base64解码全流程

拿到流量分析题&#xff0c;很多零基础的同学第一反应是“这玩意儿到底从哪儿下手”。特别是蓝桥杯这类竞赛里面&#xff0c;Wireshark抓包加Base64解码组合出现的频率不低&#xff0c;题目本身不难&#xff0c;但考的是你能不能快速定位可疑流量、把藏在数据里的编码串挖出来还…

作者头像 李华
网站建设 2026/10/20 6:06:18

Unity AssetBundle安卓实战:从打包分组到热更新全链路避坑指南

1. 为什么打包成APK之后资源加载全乱套了如果你做过Unity移动端项目&#xff0c;大概率经历过这个场景&#xff1a;在编辑器里跑得好好的场景&#xff0c;打包成APK装到安卓手机上&#xff0c;要么贴图变成一片粉红&#xff0c;要么模型直接消失&#xff0c;要么音效播不出来。…

作者头像 李华
网站建设 2026/10/20 6:06:12

基于Python与CNN的牙齿健康识别:毕设实战全流程

开场&#xff1a;牙齿健康识别这个毕设选题&#xff0c;到底值不值得做每年毕业季都能看到大量"深度学习"方向的计算机毕设&#xff0c;但很多题目做出来就是个玩具&#xff1a;MNIST手写数字识别改成你的名字、猫狗分类换个数据集&#xff0c;论文水完就忘。说实话&…

作者头像 李华
网站建设 2026/10/20 6:05:35

2026年10月方案推荐,室内导航导览系统哪家好经验分享

摘要进入2026年,医院、车站、商场、场馆等大型建筑的室内导航导览需求持续升温,一套好用的室内导航导览系统,既能帮助访客快速找到目的地,也能减轻现场人工服务的压力。不过面对数量众多的方案供应商,不少项目负责人在选型时常常无从下手:定位精度怎么看?地图数据怎么维护?系…

作者头像 李华
网站建设 2026/10/20 6:04:57

彻底讲透HashMap:从哈希原理到源码与性能优化

给新手讲清楚HashMap&#xff0c;Java入门阶段的很多事情一下子就能通。这个数据结构核心就一句话&#xff1a;通过key找到value。登录系统里拿用户ID查用户信息、订单统计里按日期聚合金额、缓存场景里用请求URL换响应结果&#xff0c;背后全是同一套逻辑——给一个key&#x…

作者头像 李华