Ollama 网络搜索(Web search)
模型的参数里没有今天的新闻,也不知道上周发布的版本号。这类"时效性"问题,最省事的补法不是微调、不是自己维护爬虫,而是给它一个搜索接口,需要时自己去查。
Ollama 官方直接提供了两个现成接口:web_search 负责搜,web_fetch 负责读具体网页。两者都是云端 REST API,配好就能用,本地模型也能调用它们。
版本基线 v0.40.12,官方
docs.ollama.com/capabilities/web-search。
一、先拿到 API Key
这两个接口走 Ollama 云端,需要认证:
- 注册一个免费 Ollama 账号
- 到
ollama.com/settings/keys创建 API Key - 写进环境变量
OLLAMA_API_KEY
## 所有调用都会读取这个变量
export OLLAMA_API_KEY="your_api_key"
注意这是独立于本地模型运行的能力——你的模型跑在 localhost:11434,搜索请求发往 ollama.com。所以离线环境下这部分会失败,代码里要有降级路径。
二、web_search:一次查询,返回若干结果
POST https://ollama.com/api/web_search
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
query |
string | 是 | 搜索查询字符串 |
max_results |
integer | 否 | 返回结果数上限,默认 5,最大 10 |
curl https://ollama.com/api/web_search \
--header "Authorization: Bearer $OLLAMA_API_KEY" \
-d '{
"query": "what is ollama?"
}'
返回体是一个对象,results 数组里每条包含三项:
{
"results": [
{
"title": "Ollama",
"url": "https://ollama.com/",
"content": "Cloud models are now available..."
},
{
"title": "What is Ollama? Introduction to the AI model management tool",
"url": "https://www.hostinger.com/tutorials/what-is-ollama",
"content": "Ariffud M. 6min Read..."
}
]
}
content 是截取的相关片段,不是整页正文。这对控制上下文很友好——但如果你需要完整内容,得再调 web_fetch。
结果数不要贪多。默认 5 条通常够用,调到 10 条往往只是把噪声一起塞进上下文。
三、web_fetch:读某个具体的网页
POST https://ollama.com/api/web_fetch
只有 url 一个必填参数:
curl --request POST \
--url https://ollama.com/api/web_fetch \
--header "Authorization: Bearer $OLLAMA_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"url": "ollama.com"
}'
返回三样东西:
{
"title": "Ollama",
"content": "[Cloud models](https://ollama.com/blog/cloud-models) are now available in Ollama...",
"links": [
"http://ollama.com/",
"http://ollama.com/models",
"https://github.com/ollama/ollama"
]
}
content 是页面的主体内容,已经做过提取(去掉了导航、页脚这些噪声),但保留了 Markdown 标记——你会看到 [文字](链接) 这样的形式。links 是页面内提取出的链接列表,可以拿来做二级抓取。
url 写 ollama.com 这种不带协议的形式也能工作,服务端会补全。
四、SDK 里就是一行
Python:
## pip install ollama
import ollama
## 搜索
response = ollama.web_search("What is Ollama?")
print(response)
from ollama import web_fetch
## 抓取单页
result = web_fetch('https://ollama.com')
print(result)
## WebFetchResponse(title='Ollama', content='...', links=['https://ollama.com/', ...])
JavaScript:
import { Ollama } from "ollama";
const client = new Ollama();
// 搜索
const results = await client.webSearch("what is ollama?");
console.log(JSON.stringify(results, null, 2));
// 抓取单页
const fetchResult = await client.webFetch("https://ollama.com");
console.log(JSON.stringify(fetchResult, null, 2));
五、核心玩法:把搜索当工具挂给模型
上面这些调用都需要你自己发起。真正有价值的是把它们变成模型可自主调用的工具——模型判断需要联网,就自己搜;搜到 URL 后觉得摘要不够,再自己去抓全文。
Python SDK 的 web_search 和 web_fetch 本身就是函数,直接放进 tools 列表即可:
## 用一个小模型就够,4B 参数足够做工具选择
ollama pull qwen3:4b
from ollama import chat, web_fetch, web_search
## 两个函数直接作为工具
available_tools = {'web_search': web_search, 'web_fetch': web_fetch}
messages = [{'role': 'user', 'content': "what is ollama's new engine"}]
while True:
response = chat(
model='qwen3:4b',
messages=messages,
tools=[web_search, web_fetch],
think=True,
)
if response.message.thinking:
print('Thinking: ', response.message.thinking)
if response.message.content:
print('Content: ', response.message.content)
messages.append(response.message)
if response.message.tool_calls:
for tool_call in response.message.tool_calls:
function_to_call = available_tools.get(tool_call.function.name)
if function_to_call:
args = tool_call.function.arguments
result = function_to_call(**args)
# 关键:结果必须截断,否则一次搜索就能把上下文撑爆
messages.append({
'role': 'tool',
'content': str(result)[:2000 * 4],
'tool_name': tool_call.function.name,
})
else:
messages.append({
'role': 'tool',
'content': f'Tool {tool_call.function.name} not found',
'tool_name': tool_call.function.name,
})
else:
# 没有工具调用了,模型已经给出最终答案
break
跑起来会看到典型的搜索 Agent 轨迹:先思考"用户问的可能是引擎更新",然后调 web_search 搜 Ollama new engine,拿到结果后继续思考,最后输出带要点的答案。
*`str(result)[:2000 4]` 这个截断别去掉。** 一次搜索返回 5 条结果,每条几百字,轻松上千 token;再叠几轮,小模型的上下文立刻溢出。按需截断是搜索 Agent 能跑通的前提。
六、上下文长度必须调大
官方明确指出:搜索结果可能返回数千 token,建议把模型上下文长度提到至少约 32000 token,搜索 Agent 在完整上下文下效果最好。
Ollama 默认上下文长度通常比这小得多。设置方式有两种:
- 创建模型时通过 Modelfile 设
PARAMETER num_ctx 32768(详见 5.1 Ollama Modelfile 参考) - 请求时在
options里传num_ctx
如果不调,会遇到一个很迷惑的现象:搜索结果明明拿到了,模型的回答却像没看见。原因不是你代码错了,而是前面的消息被挤出了上下文窗口。
顺带一提,Ollama 云端模型默认跑在完整上下文长度上,这也是云端在长上下文场景更省心的原因。
七、接进现成工具:MCP
不想自己写 Agent 循环的话,官方提供了一个 Python MCP server,把它挂到支持 MCP 的客户端里,搜索能力立刻可用。
Cline:Manage MCP Servers → Configure MCP Servers,加入:
{
"mcpServers": {
"web_search_and_fetch": {
"type": "stdio",
"command": "uv",
"args": ["run", "path/to/web-search-mcp.py"],
"env": { "OLLAMA_API_KEY": "your_api_key_here" }
}
}
}
Codex:写进 ~/.codex/config.toml:
[mcp_servers.web_search]
command = "uv"
args = ["run", "path/to/web-search-mcp.py"]
env = { "OLLAMA_API_KEY" = "your_api_key_here" }
Goose 则通过它的 MCP 功能界面配置,字段同上。
这个 server 脚本在 ollama-python 仓库的 examples/web-search-mcp.py,克隆下来指向本地路径就行。
八、和 RAG 怎么选
两者都能"补充模型不知道的知识",分工其实很清楚:
| 网络搜索 | 自建 RAG(嵌入检索) | |
|---|---|---|
| 数据来源 | 公开互联网 | 你自己的文档库 |
| 时效性 | 实时 | 取决于你的库何时更新 |
| 隐私 | 内容出网,不适合内部资料 | 完全本地 |
| 依赖 | 需要 API Key + 联网 | 只需本地嵌入模型 |
| 适合 | 新闻、版本号、通用知识 | 内部规范、产品文档、客户资料 |
实际项目里经常同时用:内部知识查 RAG,外部实时信息查搜索,让模型根据问题自己选工具。这正好是上一节 3.8 Ollama 工具调用(Tool calling) 讲的多工具调度;嵌入检索的建法见 3.6 Ollama 嵌入向量(Embeddings)。
至此模型能力一章走完。想回到命令本身,看 4.1 Ollama CLI 参考;想调参数与模板,看 5.1 Ollama Modelfile 参考。