search_provider 设置为 "exa",Venice 就会在零数据保留的条件下通过 Exa 执行搜索。你使用 Venice API 密钥进行身份验证,搜索费用由 Venice 计费,无需 Exa 账户。
所有提供商返回的结果格式都相同,因此 Exa 可以直接接入你基于 Venice 默认 Brave 搜索构建的任何应用,切换提供商只需修改一个字段。本指南介绍如何调用该端点、如何将 Exa 搜索作为工具提供给 Venice 模型、如何自行用 Exa 结果为提示词提供依据,以及何时应改为调用 Exa 自己的 API。
前提条件
- 一个 Venice API 密钥
- Python 3.10 或更高版本,或 Node.js 22 或更高版本
- 对于智能体示例,需要一个支持函数调用的 Venice 模型。示例使用
z-ai-glm-5-3-flash。
设置
安装 OpenAI SDK,Python 还需安装requests。Node.js 已内置 fetch:
使用 Exa 搜索
向/augment/search 发送查询,并将 search_provider 设置为 "exa":
limit 默认为 10,可接受 1 到 20 之间的值;query 可接受 1 到 400 个字符。超出这些范围的值会返回 400,而不会被自动截断到范围内。请将 date 视为可选字段,因为许多页面不会公布日期。
为 Venice 模型提供 Exa 搜索
要让模型自行决定何时搜索以及搜索什么,请在聊天请求的tools 数组中描述一个 web_search 函数,并在模型每次调用它时由你自己执行搜索。下面的程序将上面的请求封装为一个搜索辅助函数,以 tool 消息的形式将结果返回给模型,并不断循环,直到模型以文本形式作答:
- 截断模型编写的查询。 端点会直接拒绝超过 400 个字符的查询,而不是将其缩短,而模型有时会写出很长的查询。
- 将错误作为工具结果返回。 失败的搜索会变成一条以
Error:开头的工具消息,这样模型可以尝试其他查询或解释失败原因,而不是让循环崩溃。 - 先追加助手消息,再追加其工具结果。 每条
tool消息都必须跟在请求它的助手回合之后。直接追加消息对象本身还能保留reasoning_content(GLM 5.3 Flash 等推理模型会返回该字段),从而让模型在多轮之间保持推理过程。
content 是页面文本,最多约 10,000 个字符,因此模型通常仅凭搜索结果就能作答。当需要完整页面时,可以再添加一个调用 /augment/scrape 的工具,它会以 Markdown 形式返回页面。
先搜索再生成
函数调用让模型决定何时搜索以及搜索什么。当你的代码已经知道要搜索什么时,可以跳过工具循环:运行一次 Exa 搜索,为结果编号,然后让 Venice 基于这些结果作答。这种方式适用于任何 Venice 文本模型,而且由于你保留了输入提示词的来源列表,答案中的每条引用都能对应回一个 URL。 使用上一个示例中的搜索辅助函数、客户端和模型:"exa" 即可在 Exa 上运行。
直接使用 Exa API
Venice 的搜索端点接受一个查询和结果数量。Exa 自己的 API 提供更多控制选项:新闻、研究论文、公司、人物和财务报告等类别,域名和日期筛选,面向查询的高亮片段和完整页面文本,以及深度多步搜索。要使用这些功能,请使用从 Exa 控制台获取的 API 密钥直接调用 Exa。这些请求从你的应用直接发送到 Exa,受 Exa 而非 Venice 的条款约束,并计入你的 Exa 账户。Exa 在企业版套餐中提供零数据保留。 Exa SDK(exa-py 和 2.24.0 或更高版本的 exa-js)包含 Chat Completions 格式的工具,可以直接放入上面的循环中。将工具列表替换为 Exa 的工具:
messages += exa.openai.handle_tool_calls(message),在 Node.js 中使用 messages.push(...(await exa.openai.handleToolCalls(message)))。它会执行每个 Exa 调用并返回对应的 tool 消息,失败会以 Error: 结果报告。请保留页面文本长度上限,因为 exa-js 在不设上限时会返回整个页面。category、include_domains 和 start_published_date 等关键字参数会透传给 Exa 的搜索。有关所有选项,请参阅 Exa 的工具调用指南。
推荐模型
模型 ID 会轮换。可以在运行时通过
GET /models/traits 获取当前的函数调用默认模型,或浏览文本模型查找其他支持函数调用的模型。
隐私
使用search_provider: "exa" 时,你的应用只与 Venice 通信,Venice 在零数据保留的条件下通过 Exa 执行每次搜索。Venice 不存储提示词或响应内容,而推理层如何处理数据则由模型的隐私级别决定。私密模型运行在零数据保留的基础设施上。
容易被忽视的一点是:模型会根据对话内容编写搜索查询,因此提示词中的细节可能会出现在发送给 Exa 的查询中。如果提示词可能包含个人或机密信息,请在系统提示词中告诉模型不要将这些细节放入搜索,或者使用先搜索模式,让你自己的代码编写每一条查询。
如果你直接调用 Exa API,这些请求将改为受 Exa 条款约束并发送至 Exa。
费用
每次搜索费用为 $0.01,即每 1,000 次 $10,与 Brave 或 Google 搜索相同。Venice 会将其与聊天请求使用的 token 一起计入你的 Venice 账户,因此不会有单独的 Exa 账单。因错误而失败的搜索不收费,但返回空结果的搜索仍会收费。搜索结果会在下一轮作为输入返回给模型,由于其中包含页面文本,一次五条结果的搜索通常会增加 5,000 到 10,000 个输入 token。以下几个习惯可以同时降低这两项开销:- 当少量来源就足够时,降低
limit。无论limit为多少,搜索费用都相同,但结果越少,下一轮的输入 token 就越少。 - 保持较低的
max_rounds。每多一轮都可能增加搜索次数和 token 用量。 - 当你的代码知道要搜索什么时,使用先搜索模式。它只运行一次搜索和一次聊天请求。
故障排除
搜索端点返回 400
搜索端点返回 400
query 必须为 1 到 400 个字符,limit 必须为 1 到 20,search_provider 必须为 brave、google 或 exa。超出这些范围的值会被拒绝,而不会被自动截断到范围内。在工具循环中,被拒绝的搜索会以 Error: 工具结果的形式传给模型,而不会抛出异常。402 Payment Required
402 Payment Required
你的 Venice 余额不足以支付该请求。使用 API 密钥发出的请求会返回
INSUFFICIENT_BALANCE,请为你的 Venice 余额充值。使用 x402 钱包认证发出的请求会在响应中返回充值说明。工具回合后 Venice 返回 400
工具回合后 Venice 返回 400
包括 Claude 和 GPT 模型在内的部分模型,在工具调用之后没有紧跟带有对应
tool_call_id 的 tool 消息时,会返回 400。GLM 模型仍会接受这样的对话,因此该问题可能在你切换模型时才首次出现。上面的循环会在发起调用的助手消息之后立即响应每个调用,如果你添加工具,请保持这种结构。模型未搜索就直接作答
模型未搜索就直接作答
请检查模型是否支持函数调用,并在系统提示词中说明何时应进行搜索。模型如果认为可以凭记忆作答,往往会跳过工具,除非你明确要求它针对最新或具体的事实进行搜索。
资源
Web Search API
参数、搜索提供商和响应架构
带引用回答
在 Venice 上实现完整的搜索、抓取和引用流程
函数调用
工具调用在 Venice 上的工作方式
Exa 文档
Exa 自己的 API、SDK 和搜索选项