news 2026/9/17 18:52:08

使用 mistral.rs 的 HTTP API 实现 Chat Completions 网页搜索(web_search_options 完整实战指南)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 mistral.rs 的 HTTP API 实现 Chat Completions 网页搜索(web_search_options 完整实战指南)

使用 mistral.rs 的 HTTP API 实现 Chat Completions 网页搜索(web_search_options 完整实战指南)

【免费下载链接】mistral.rsFast, flexible LLM inference项目地址: https://gitcode.com/GitHub_Trending/mi/mistral.rs

本篇指南讲解如何在 mistral.rs 中以 OpenAI 兼容的 HTTP API 为 Chat Completions 请求启用内建网页搜索能力:只需在服务端以--agent模式启动一个支持搜索工具的服务器,然后在客户端请求体中传入web_search_options={},模型即可自主联网检索、抓取网页内容并基于实时信息作答。读完本文,你将掌握启动命令、完整的 Python 调用代码、web_search_options的全部可配置字段,以及搜索工具在服务端底层的真实执行机制。

概述:一条web_search_options引发的联网推理

mistral.rs 对 OpenAI 的web_search_options请求字段提供了服务端原生支持。该功能不需要你在客户端自行实现"搜索→工具调用→回传结果"的多轮循环,而是由服务端内置的 Agent 工具循环自动完成:模型按需调用预置的网页搜索工具与网页内容提取工具,检索结果被重新注入上下文后继续生成,最终直接返回一段引用了实时信息的最终回答。

对应到当前仓库,该能力由三部分协同构成:

  • mistralrs-server-core/src/chat_completion.rs:解析并归一化请求中的web_search_options,与tools一起转换为服务端内部工具配置;
  • mistralrs-core/src/search/mod.rs:定义搜索/提取工具的提示词描述、参数 Schema 与真实执行逻辑;
  • mistralrs-cli/src/args/mod.rs:提供--agent--enable-search--search-embedding-model等命令行开关。

第一步:以 Agent 模式启动搜索服务器

原文档给出的启动命令是:

mistralrs serve --agent -p 1234 -m Qwen/Qwen3-4B

参数拆解如下:

参数作用
serve启动 OpenAI 兼容的 HTTP 服务器
--agent构建本地 Agent:同时启用网页搜索、Python 代码执行与 Shell 执行,并运行 Agent 工具循环(--agentic是其别名)
-p 1234服务监听端口,客户端将访问http://localhost:1234/v1/
-m Qwen/Qwen3-4B指定 HuggingFace 模型仓库标识,此处使用 Qwen3-4B

需要说明的是:--agent是一个"全家桶"开关。从 mistralrs-cli/src/commands/serve.rs 的源码可以看到,传入--agent后服务端会自动把enable_search置为true。因此如果你只想启用网页搜索、不希望附带代码执行等能力,可以显式使用更精确的组合:

# 仅启用网页搜索(需搭配 embedding 重排序模型) mistralrs serve --enable-search -p 1234 -m Qwen/Qwen3-4B

其中:

  • --enable-search:启用与 OpenAIweb_search_options兼容的搜索能力,会加载一个搜索 embedding 重排序模型(默认是 EmbeddingGemma);
  • --search-embedding-model:指定要加载的内建搜索 embedding 模型,该参数要求同时传入--enable-search--agent,否则 CLI 会直接报错(见 mistralrs-cli/src/commands/serve.rs)。

从服务端构建器的源码(mistralrs-server-core/src/mistralrs_for_server_builder.rs)看,enable_search负责加载搜索重排序模型,search_embedding_model用于覆盖默认的 EmbeddingGemma,而search_callback则允许以编程方式完全替换内置的搜索实现——这些都是高级自定义入口,默认情况下无需改动。

第二步:运行示例脚本

服务启动后,在仓库根目录执行:

python examples/server/web_search.py

脚本的完整源码位于 examples/server/web_search.py。下面逐段解析其工作方式。

构造 OpenAI 兼容客户端

from openai import OpenAI client = OpenAI(api_key="foobar", base_url="http://localhost:1234/v1/")
  • base_url指向 mistral.rs 服务器的/v1/端点;
  • api_key只是占位符(mistral.rs 本地服务不做鉴权),可以填写任意字符串。

发起带网页搜索的请求

messages = [ { "role": "user", "content": "Can you show me some code using mistral.rs for running Llama 3.2 Vision?", } ] completion = client.chat.completions.create( model="default", messages=messages, tool_choice="auto", max_tokens=1024, web_search_options={}, )

这里的关键参数是web_search_options={}

  • {}表示启用网页搜索且全部选项走默认值;
  • tool_choice="auto"允许模型自主决定是否调用搜索工具;
  • max_tokens=1024限制单次生成的最大 token 数;
  • 服务端在请求归一化阶段会把web_search_optionstools统一转换为内部工具配置(见 mistralrs-server-core/src/chat_completion.rs),随后交给 Agent 工具循环执行。

读取结果

# print(completion.usage) print(completion.choices[0].message.content) if completion.choices[0].message.tool_calls is not None: # Should never happen. tool_called = completion.choices[0].message.tool_calls[0].function print(tool_called)
  • 正常路径下,模型完成联网检索后会把最终答案写入choices[0].message.content,直接打印即可;
  • 示例中tool_calls的分支仅为防御性代码:由于web_search_options模式下搜索由服务端内部完成,客户端最终收到的应当是纯文本回答,因此理论上不应出现未消费的工具调用;如确实出现,说明发生了异常情况,可借此排查;
  • 被注释掉的completion.usage行可取消注释,用于观察本次请求的 token 用量统计。

第三步:web_search_options的完整参数说明

虽然示例只传了{},但该字段支持丰富的配置项,其数据结构定义于 mistralrs-core/src/request.rs。下表整理自该结构体:

字段类型说明
search_context_sizeSearchContextSize控制注入上下文的搜索结果规模
user_locationWebSearchUserLocation用户地理位置信息,影响搜索结果的本地化
filtersWebSearchFilters域名过滤:allowed_domains(仅允许)与blocked_domains(排除),值为域名字符串列表
external_web_accessbool是否允许外部网络访问
return_token_budgetWebSearchReturnTokenBudget搜索结果回传的 token 预算,枚举值为default/unlimited
search_content_typesVec<WebSearchContentType>搜索内容类型,枚举值为text/image
image_settingsWebSearchImageSettings图片搜索设置:max_results(最大结果数)与caption(是否生成说明)
search_descriptionString覆盖搜索工具默认的提示词描述
extract_descriptionString覆盖网页提取工具默认的提示词描述

地理位置示例

user_location采用type: "approximate"的序列化格式(见 mistralrs-core/src/request.rs),支持cityregioncountrytimezone四个可选维度。一个带本地化搜索的完整请求示例如下:

completion = client.chat.completions.create( model="default", messages=messages, tool_choice="auto", max_tokens=1024, web_search_options={ "user_location": { "type": "approximate", "approximate": { "city": "Shanghai", "country": "CN", "region": "CN-31", "timezone": "Asia/Shanghai", }, }, "return_token_budget": "default", "filters": { "allowed_domains": ["arxiv.org", "github.com"], }, }, )

服务端在构造搜索工具时,会把上述地理位置拼接到搜索工具的描述文本中(如The user's location is: Shanghai, CN-31, CN, Asia/Shanghai.),从而引导模型给出本地化更强的查询词——该逻辑见 mistralrs-core/src/search/mod.rs。

底层原理:搜索工具与执行流程

启用web_search_options后,服务端会注册两个内建工具(工具名定义于 mistralrs-core/src/search/mod.rs):

工具名输入参数职责
mistralrs_search_the_webquery(字符串)根据查询词执行网页搜索,返回标题、摘要、URL 与正文内容
mistralrs_website_content_extractorurl(字符串)提取指定 URL 的网页正文内容

二者的工具描述、参数 JSON Schema 由get_search_tools动态生成(见 mistralrs-core/src/search/mod.rs),并且均声明为strict: true的 Function 工具。

搜索执行的真实路径

mistralrs_search_the_web为例(mistralrs-core/src/search/mod.rs),一次搜索的完整链路是:

  1. URL 直取:若模型传入的"查询词"本身是http://https://开头的 URL,则直接抓取该页面并把正文作为唯一结果返回(因为 DuckDuckGo 对裸 URL 的搜索返回为空);
  2. 搜索引擎查询:否则请求https://html.duckduckgo.com/html/?q=<编码后的查询词>,使用形如mistralrs/<版本号> (<OS>; <ARCH>; <FAMILY>)的 User-Agent;
  3. 解析结果页:用scraper解析 DuckDuckGo HTML 结果,通过.result.result__title.result__snippet.result__url四个 CSS 选择器提取标题、摘要与链接,过滤掉任一字段为空的结果,最多保留MAX_SEARCH_RESULTS = 10条;
  4. 并发抓取正文:对每条结果并发发起页面抓取,并用html2text把 HTML 转换为纯文本后填充content字段;
  5. 返回结构化结果:最终把SearchResulttitle/description/url/content)列表回传给模型,模型据此继续生成带引用的回答。

mistralrs_website_content_extractor则更简单直接:抓取给定 URL,将 HTML 转为纯文本返回;抓取失败时返回ERROR: failed to extract content占位文本(见 mistralrs-core/src/search/mod.rs)。

两个工具共用的网络参数位于文件顶部的常量:连接超时 5 秒(SEARCH_CONNECT_TIMEOUT)、请求超时 10 秒(SEARCH_REQUEST_TIMEOUT)、最大结果数 10(MAX_SEARCH_RESULTS),见 mistralrs-core/src/search/mod.rs。

工具描述即"提示词"

值得注意的一个设计细节是:搜索/提取工具的英文描述本身就是精心编写的提示词。例如搜索工具描述中明确要求模型"如果用户需要最新信息就调用此工具""调用后必须基于输出完成回答""输入应是查询词而非 URL",并给出了期望的 JSON 输出结构(sourcesoutput数组)。这些描述(SEARCH_DESCRIPTIONEXTRACT_DESCRIPTION)会被注入模型可见的工具定义中,直接影响模型的调用决策质量。

与普通 Tool Calling 的区别及 API 兼容性

如果你已经熟悉 examples/server/tool_calling.py 展示的"客户端侧工具调用"模式,可以这样对比理解:

  • 普通 tool calling(客户端循环):客户端在tools中自行声明函数 Schema,模型返回tool_calls后由客户端执行函数、再把结果以role: "tool"的消息回传,需要客户端维护多轮对话;
  • web_search_options(服务端 Agent 循环):搜索工具由服务端注册,检索与回传全部在服务端完成,客户端只需传web_search_options={},最终直接拿到文本回答。

此外需要特别留意 API 差异:在 Chat Completions 接口中应使用web_search_options字段;而tools[].type="web_search"这种工具声明形式只被 Responses API 支持,如果在 Chat Completions 中使用会触发明确的报错提示:"tools[].type="web_search"is only supported by the Responses API; useweb_search_optionswith Chat Completions"(见 mistralrs-server-core/src/openai.rs)。这一点在 mistralrs-server-core/src/openai.rs 的单元测试中也有对应断言。

实践要点与注意事项

  • 网络可达性:搜索功能依赖对html.duckduckgo.com及目标网站的实时访问,服务器所在环境需要具备出网能力;
  • 默认值即可用web_search_options={}是最低成本的启用方式,全部选项取默认值;按需再叠加user_locationfiltersreturn_token_budget等精细化配置;
  • 域名过滤filters.allowed_domains/blocked_domains用于限定搜索与提取的域名范围,适合对检索来源有合规要求的场景;注意域名列表存在数量上限校验(见 mistralrs-server-core/src/openai.rs);
  • 模型选择--agent/--enable-search会加载搜索 embedding 重排序模型,首次启动需要下载对应权重;主模型建议选择工具调用能力较强的型号(如 Qwen3 系列),以获得更稳定的搜索决策;
  • 结果上限:单次搜索最多返回 10 条结果,且每条正文内容会在后续处理中按 token 预算截断(SearchResult::cap_content_len,见 mistralrs-core/src/search/mod.rs),因此大文档页面只会保留前缀内容。

延伸阅读

  • 服务端 Agent 循环与多工具调度:examples/server/agentic_tool_rounds.py、examples/server/tool_dispatch.py
  • 客户端侧手工工具调用范式:examples/server/tool_calling.py
  • 搜索/提取工具的 Rust 实现:mistralrs-core/src/search/mod.rs
  • web_search_options数据结构定义:mistralrs-core/src/request.rs
  • CLI 参数(--agent/--enable-search/--search-embedding-model):mistralrs-cli/src/args/mod.rs

【免费下载链接】mistral.rsFast, flexible LLM inference项目地址: https://gitcode.com/GitHub_Trending/mi/mistral.rs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

STM32 Bootloader与串口IAP实现:从原理到代码,轻松搞定固件升级

很多人刚接触单片机开发时&#xff0c;对 bootloader 总是有一种“高深莫测”的感觉。后来我自己做产品&#xff0c;才真正意识到它其实就是一段“先于主程序运行的小程序”&#xff0c;并没有想象中复杂。尤其是当你需要给已经出货的设备做固件升级时&#xff0c;IAP&#xff…

作者头像 李华
网站建设 2026/9/17 18:45:21

S7-1500 PLC硬件配置、电源预算与硬件诊断实战

简介&#xff1a;这份《S7-1500 PLC应用技术》第2章课件&#xff0c;面向自动化、电气控制专业学生及初学S7-1500的工程人员&#xff0c;用于梳理该系列PLC硬件体系与选型要点。内容分六部分&#xff1a;SIMATIC产品定位、CPU模块、电源模块、信号模块、通信模块与CPU操作模式。…

作者头像 李华
网站建设 2026/9/17 18:41:18

VS2015安装包损坏修复全指南:校验、离线重建与工具链提取

1. 这不是“重装就完事”的问题&#xff1a;VS2015安装包损坏/丢失的真实战场你点开那个下载了三小时的 vs2015community.exe&#xff0c;双击后弹出“无法验证安装包完整性”、“找不到 bootstrapper.exe”、“setup.exe 已损坏”——不是你的网速慢&#xff0c;也不是磁盘满了…

作者头像 李华
网站建设 2026/9/17 18:40:56

UML用例模型实战:用例图、规格说明与需求评审避坑

用例模型是UML里最容易被低估的一块内容。用例图谁都能画几个小人加圆圈&#xff0c;但真正能拿去评审、能撑起后续设计与测试的用例模型&#xff0c;十份里挑不出一份。用例图解决的是"系统边界在哪、谁跟系统打交道、系统对外承诺做什么"这三个问题&#xff0c;用例…

作者头像 李华