exa.ai-websearch-api
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseExa API Setup Guide
Exa API 设置指南
Exa | Web Search API, AI Search Engine, & Website Crawler
Exa | 网页搜索API、AI搜索引擎与网站爬虫
Your Configuration
你的配置
| Setting | Value |
|---|---|
| Coding Tool | Other |
| Framework | cURL |
| Use Case | Coding agent, Agetnic AI, Open Claw |
| Search Type | Auto - Balanced relevance and speed (~1 second) |
| Content | Full text |
| 设置项 | 值 |
|---|---|
| 编码工具 | 其他 |
| 框架 | cURL |
| 使用场景 | 编码Agent、Agentic AI、Open Claw |
| 搜索类型 | Auto - 平衡相关性与速度(约1秒) |
| 内容 | 全文 |
Keywords
关键词
ai search engine,serp api,best ai search engine,search api,deep research api,web search api,web search ai,ai search api,deepresearch api,web crawling api,website crawler,metaphor,exa,api,search,ai,llms
ai search engine,serp api,best ai search engine,search api,deep research api,web search api,web search ai,ai search api,deepresearch api,web crawling api,website crawler,metaphor,exa,api,search,ai,llms
API Key Setup
API密钥设置
Environment Variable
环境变量
bash
export EXA_API_KEY="YOUR_API_KEY"bash
export EXA_API_KEY="YOUR_API_KEY".env File
.env 文件
env
EXA_API_KEY=YOUR_API_KEYenv
EXA_API_KEY=YOUR_API_KEY🔌 Exa MCP Server
🔌 Exa MCP 服务器
Give your AI coding assistant real-time web search with Exa MCP.
Remote MCP URL:
https://mcp.exa.ai/mcp?exaApiKey=YOUR_API_KEYAvailable tools: , , , , ,
web_search_exaget_code_context_exacompany_research_exacrawling_exalinkedin_search_exadeep_researcher_startHTTP config (Cursor, Claude Code, Codex):
json
{
"mcpServers": {
"exa": {
"type": "http",
"url": "https://mcp.exa.ai/mcp?exaApiKey=YOUR_API_KEY",
"headers": {}
}
}
}Local install (Claude Desktop):
json
{
"mcpServers": {
"exa": {
"command": "npx",
"args": ["-y", "exa-mcp-server"],
"env": { "EXA_API_KEY": "YOUR_API_KEY" }
}
}
}📖 Full docs: docs.exa.ai/reference/exa-mcp
为你的AI编码助手通过Exa MCP提供实时网页搜索能力。
远程MCP地址:
https://mcp.exa.ai/mcp?exaApiKey=YOUR_API_KEY可用工具: , , , , ,
web_search_exaget_code_context_exacompany_research_exacrawling_exalinkedin_search_exadeep_researcher_startHTTP配置(Cursor、Claude Code、Codex):
json
{
"mcpServers": {
"exa": {
"type": "http",
"url": "https://mcp.exa.ai/mcp?exaApiKey=YOUR_API_KEY",
"headers": {}
}
}
}本地安装(Claude Desktop):
json
{
"mcpServers": {
"exa": {
"command": "npx",
"args": ["-y", "exa-mcp-server"],
"env": { "EXA_API_KEY": "YOUR_API_KEY" }
}
}
}Quick Start (cURL)
快速开始(cURL)
cURL
cURL
bash
curl -X POST 'https://api.exa.ai/search' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "React hooks best practices 2024",
"type": "auto",
"num_results": 10,
"contents": {
"text": {
"max_characters": 20000
}
}
}'bash
curl -X POST 'https://api.exa.ai/search' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "React hooks best practices 2024",
"type": "auto",
"num_results": 10,
"contents": {
"text": {
"max_characters": 20000
}
}
}'Function Calling / Tool Use
函数调用 / 工具使用
Function calling (also known as tool use) allows your AI agent to dynamically decide when to search the web based on the conversation context. Instead of searching on every request, the LLM intelligently determines when real-time information would improve its response—making your agent more efficient and accurate.
Why use function calling with Exa?
- Your agent can ground responses in current, factual information
- Reduces hallucinations by fetching real sources when needed
- Enables multi-step reasoning where the agent searches, analyzes, and responds
📚 Full documentation: https://docs.exa.ai/reference/openai-tool-calling
函数调用(也称为工具使用)允许你的AI Agent根据对话上下文动态决定何时进行网页搜索。无需每次请求都搜索,LLM会智能判断何时需要实时信息来提升响应质量——让你的Agent更高效、准确。
为什么要结合Exa使用函数调用?
- 你的Agent可以基于当前真实信息生成响应
- 在需要时获取真实来源,减少幻觉
- 支持多步骤推理,Agent可以先搜索、分析,再给出响应
OpenAI Function Calling
OpenAI 函数调用
python
import json
from openai import OpenAI
from exa_py import Exa
openai = OpenAI()
exa = Exa()
tools = [{
"type": "function",
"function": {
"name": "exa_search",
"description": "Search the web for current information.",
"parameters": {
"type": "object",
"properties": {"query": {"type": "string", "description": "Search query"}},
"required": ["query"]
}
}
}]
def exa_search(query: str) -> str:
results = exa.search(query=query, type="auto", num_results=10, contents={"text": {"max_characters": 20000}})
return "\n".join([f"{r.title}: {r.url}" for r in results.results])
messages = [{"role": "user", "content": "What's the latest in AI safety?"}]
response = openai.chat.completions.create(model="gpt-4o", messages=messages, tools=tools)
if response.choices[0].message.tool_calls:
tool_call = response.choices[0].message.tool_calls[0]
search_results = exa_search(json.loads(tool_call.function.arguments)["query"])
messages.append(response.choices[0].message)
messages.append({"role": "tool", "tool_call_id": tool_call.id, "content": search_results})
final = openai.chat.completions.create(model="gpt-4o", messages=messages)
print(final.choices[0].message.content)python
import json
from openai import OpenAI
from exa_py import Exa
openai = OpenAI()
exa = Exa()
tools = [{
"type": "function",
"function": {
"name": "exa_search",
"description": "Search the web for current information.",
"parameters": {
"type": "object",
"properties": {"query": {"type": "string", "description": "Search query"}},
"required": ["query"]
}
}
}]
def exa_search(query: str) -> str:
results = exa.search(query=query, type="auto", num_results=10, contents={"text": {"max_characters": 20000}})
return "\n".join([f"{r.title}: {r.url}" for r in results.results])
messages = [{"role": "user", "content": "What's the latest in AI safety?"}]
response = openai.chat.completions.create(model="gpt-4o", messages=messages, tools=tools)
if response.choices[0].message.tool_calls:
tool_call = response.choices[0].message.tool_calls[0]
search_results = exa_search(json.loads(tool_call.function.arguments)["query"])
messages.append(response.choices[0].message)
messages.append({"role": "tool", "tool_call_id": tool_call.id, "content": search_results})
final = openai.chat.completions.create(model="gpt-4o", messages=messages)
print(final.choices[0].message.content)Anthropic Tool Use
Anthropic 工具使用
python
import anthropic
from exa_py import Exa
client = anthropic.Anthropic()
exa = Exa()
tools = [{
"name": "exa_search",
"description": "Search the web for current information.",
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string", "description": "Search query"}},
"required": ["query"]
}
}]
def exa_search(query: str) -> str:
results = exa.search(query=query, type="auto", num_results=10, contents={"text": {"max_characters": 20000}})
return "\n".join([f"{r.title}: {r.url}" for r in results.results])
messages = [{"role": "user", "content": "Latest quantum computing developments?"}]
response = client.messages.create(model="claude-sonnet-4-20250514", max_tokens=4096, tools=tools, messages=messages)
if response.stop_reason == "tool_use":
tool_use = next(b for b in response.content if b.type == "tool_use")
tool_result = exa_search(tool_use.input["query"])
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": [{"type": "tool_result", "tool_use_id": tool_use.id, "content": tool_result}]})
final = client.messages.create(model="claude-sonnet-4-20250514", max_tokens=4096, tools=tools, messages=messages)
print(final.content[0].text)python
import anthropic
from exa_py import Exa
client = anthropic.Anthropic()
exa = Exa()
tools = [{
"name": "exa_search",
"description": "Search the web for current information.",
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string", "description": "Search query"}},
"required": ["query"]
}
}]
def exa_search(query: str) -> str:
results = exa.search(query=query, type="auto", num_results=10, contents={"text": {"max_characters": 20000}})
return "\n".join([f"{r.title}: {r.url}" for r in results.results])
messages = [{"role": "user", "content": "Latest quantum computing developments?"}]
response = client.messages.create(model="claude-sonnet-4-20250514", max_tokens=4096, tools=tools, messages=messages)
if response.stop_reason == "tool_use":
tool_use = next(b for b in response.content if b.type == "tool_use")
tool_result = exa_search(tool_use.input["query"])
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": [{"type": "tool_result", "tool_use_id": tool_use.id, "content": tool_result}]})
final = client.messages.create(model="claude-sonnet-4-20250514", max_tokens=4096, tools=tools, messages=messages)
print(final.content[0].text)Search Type Reference
搜索类型参考
| Type | Best For | Speed | Depth |
|---|---|---|---|
| Real-time apps, autocomplete, quick lookups | Fastest | Basic |
| Most queries - balanced relevance & speed | Medium | Smart |
Tip: works well for most queries. It provides balanced relevance and speed.
type="auto"| 类型 | 适用场景 | 速度 | 深度 |
|---|---|---|---|
| 实时应用、自动补全、快速查询 | 最快 | 基础 |
| 大多数查询 - 平衡相关性与速度 | 中等 | 智能 |
提示: 适用于大多数查询,它能提供相关性与速度的平衡。
type="auto"Content Configuration
内容配置
Choose ONE content type per request (not both):
| Type | Config | Best For |
|---|---|---|
| Text | | Full content extraction, RAG |
| Highlights | | Snippets, summaries, lower cost |
⚠️ Token usage warning: Using (full page text) can significantly increase token count, leading to slower and more expensive LLM calls. To mitigate:
text: true- Add limit:
max_characters"text": {"max_characters": 10000} - Use instead if you don't need contiguous text
highlights
When to use text vs highlights:
- Text - When you need untruncated, contiguous content (e.g., code snippets, full articles, documentation)
- Highlights - When you need key excerpts and don't need the full context (e.g., summaries, Q&A, general research)
每次请求仅能选择一种内容类型(不可同时选两种):
| 类型 | 配置 | 适用场景 |
|---|---|---|
| 文本 | | 完整内容提取、RAG |
| 高亮片段 | | 片段摘要、总结、低成本 |
⚠️ Token使用警告: 使用(完整页面文本)会显著增加Token数量,导致LLM调用更慢、成本更高。可通过以下方式缓解:
text: true- 添加限制:
max_characters"text": {"max_characters": 10000} - 若不需要连续文本,可改用
highlights
何时使用文本 vs 高亮片段:
- 文本 - 当你需要完整、连续的内容时(例如代码片段、完整文章、文档)
- 高亮片段 - 当你只需要关键摘录,不需要完整上下文时(例如摘要、问答、通用研究)
Domain Filtering (Optional)
域名过滤(可选)
Usually not needed - Exa's neural search finds relevant results without domain restrictions.
When to use:
- Targeting specific authoritative sources
- Excluding low-quality domains from results
Example:
json
{
"includeDomains": ["arxiv.org", "github.com"],
"excludeDomains": ["pinterest.com"]
}Note: and cannot be used together.
includeDomainsexcludeDomains通常不需要 - Exa的神经搜索无需域名限制即可找到相关结果。
何时使用:
- 针对特定权威来源
- 从结果中排除低质量域名
示例:
json
{
"includeDomains": ["arxiv.org", "github.com"],
"excludeDomains": ["pinterest.com"]
}注意: 和 不能同时使用。
includeDomainsexcludeDomainsCoding Agent
编码Agent
Use to search for null content.
category: "null"json
{
"query": "React hooks best practices 2024",
"category": null,
"num_results": 10,
"contents": {
"text": {
"max_characters": 20000
}
}
}Tips:
- Use for balanced results
type: "auto" - Great for documentation lookup, API references, code examples
使用来搜索无分类内容。
category: "null"json
{
"query": "React hooks best practices 2024",
"category": null,
"num_results": 10,
"contents": {
"text": {
"max_characters": 20000
}
}
}提示:
- 使用获取平衡结果
type: "auto" - 非常适合文档查询、API参考、代码示例
SDK Examples
SDK示例
Category Examples
分类示例
Use category filters to search dedicated indexes. Each category returns only that content type.
Note: Categories can be restrictive. If you're not getting enough results, try searching without a category first, then add one if needed.
使用分类过滤器搜索特定类型的内容索引。每个分类仅返回对应类型的内容。
注意: 分类过滤器有一定局限性。如果没有得到足够结果,建议先不使用分类过滤器,之后再根据需要添加。
People Search (category: "people"
)
category: "people"人物搜索 (category: "people"
)
category: "people"Find people by role, expertise, or what they work on
bash
curl -X POST 'https://api.exa.ai/search' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "software engineer distributed systems",
"category": "people",
"type": "auto",
"num_results": 10
}'Tips:
- Use SINGULAR form
- Describe what they work on
- No date/text filters supported
根据角色、专业领域或工作内容查找人物
bash
curl -X POST 'https://api.exa.ai/search' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "software engineer distributed systems",
"category": "people",
"type": "auto",
"num_results": 10
}'提示:
- 使用单数形式
- 描述其工作内容
- 不支持日期/文本过滤器
Company Search (category: "company"
)
category: "company"公司搜索 (category: "company"
)
category: "company"Find companies by industry, criteria, or attributes
bash
curl -X POST 'https://api.exa.ai/search' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "AI startup healthcare",
"category": "company",
"type": "auto",
"num_results": 10
}'Tips:
- Use SINGULAR form
- Simple entity queries
- Returns company objects, not articles
根据行业、标准或属性查找公司
bash
curl -X POST 'https://api.exa.ai/search' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "AI startup healthcare",
"category": "company",
"type": "auto",
"num_results": 10
}'提示:
- 使用单数形式
- 简单的实体查询
- 返回公司对象,而非文章
News Search (category: "news"
)
category: "news"新闻搜索 (category: "news"
)
category: "news"News articles
bash
curl -X POST 'https://api.exa.ai/search' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "OpenAI announcements",
"category": "news",
"type": "auto",
"num_results": 10,
"contents": {
"text": {
"max_characters": 20000
}
}
}'Tips:
- Use livecrawl: "preferred" for breaking news
- Avoid date filters unless required
新闻文章
bash
curl -X POST 'https://api.exa.ai/search' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "OpenAI announcements",
"category": "news",
"type": "auto",
"num_results": 10,
"contents": {
"text": {
"max_characters": 20000
}
}
}'提示:
- 对于突发新闻,使用livecrawl: "preferred"
- 除非必要,避免使用日期过滤器
Research Papers (category: "research paper"
)
category: "research paper"研究论文搜索 (category: "research paper"
)
category: "research paper"Academic papers
bash
curl -X POST 'https://api.exa.ai/search' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "transformer architecture improvements",
"category": "research paper",
"type": "auto",
"num_results": 10,
"contents": {
"text": {
"max_characters": 20000
}
}
}'Tips:
- Use type: "auto" for most queries
- Includes arxiv.org, paperswithcode.com, and other academic sources
学术论文
bash
curl -X POST 'https://api.exa.ai/search' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "transformer architecture improvements",
"category": "research paper",
"type": "auto",
"num_results": 10,
"contents": {
"text": {
"max_characters": 20000
}
}
}'提示:
- 大多数查询使用type: "auto"
- 包含arxiv.org、paperswithcode.com及其他学术来源
Tweet Search (category: "tweet"
)
category: "tweet"推文搜索 (category: "tweet"
)
category: "tweet"Twitter/X posts
bash
curl -X POST 'https://api.exa.ai/search' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "AI safety discussion",
"category": "tweet",
"type": "auto",
"num_results": 10,
"contents": {
"text": {
"max_characters": 20000
}
}
}'Tips:
- Good for real-time discussions
- Captures public sentiment
Twitter/X帖子
bash
curl -X POST 'https://api.exa.ai/search' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "AI safety discussion",
"category": "tweet",
"type": "auto",
"num_results": 10,
"contents": {
"text": {
"max_characters": 20000
}
}
}'提示:
- 适合实时讨论
- 捕捉公众情绪
Content Freshness (maxAgeHours)
内容新鲜度(maxAgeHours)
maxAgeHours| Value | Behavior | Best For |
|---|---|---|
| 24 | Use cache if less than 24 hours old, otherwise livecrawl | Daily-fresh content |
| 1 | Use cache if less than 1 hour old, otherwise livecrawl | Near real-time data |
| 0 | Always livecrawl (ignore cache entirely) | Real-time data where cached content is unusable |
| -1 | Never livecrawl (cache only) | Maximum speed, historical/static content |
| (omit) | Default behavior (livecrawl as fallback if no cache exists) | Recommended — balanced speed and freshness |
When LiveCrawl Isn't Necessary:
Cached data is sufficient for many queries, especially for historical topics or educational content. These subjects rarely change, so reliable cached results can provide accurate information quickly.
See maxAgeHours docs for more details.
maxAgeHours| 值 | 行为 | 适用场景 |
|---|---|---|
| 24 | 若缓存不足24小时则使用缓存,否则实时爬取 | 每日更新的内容 |
| 1 | 若缓存不足1小时则使用缓存,否则实时爬取 | 近实时数据 |
| 0 | 始终实时爬取(完全忽略缓存) | 缓存内容不可用的实时数据场景 |
| -1 | 从不实时爬取(仅使用缓存) | 追求最大速度的历史/静态内容 |
| (省略) | 默认行为(若无缓存则实时爬取作为 fallback) | 推荐 —— 平衡速度与新鲜度 |
何时无需实时爬取:
缓存数据适用于许多查询场景,尤其是历史主题或教育内容。这些内容很少变化,可靠的缓存结果可以快速提供准确信息。
更多细节请查看maxAgeHours文档。
Other Endpoints
其他端点
Troubleshooting
故障排除
Results not relevant?
- Try - most balanced option
type: "auto" - Refine query - use singular form, be specific
- Check category matches your use case
Results too slow?
- Use
type: "fast" - Reduce
num_results - Skip contents if you only need URLs
No results?
- Remove filters (date, domain restrictions)
- Simplify query
- Try - has fallback mechanisms
type: "auto"
结果不相关?
- 尝试——最平衡的选项
type: "auto" - 优化查询——使用单数形式,更具体
- 检查分类是否匹配你的使用场景
结果速度太慢?
- 使用
type: "fast" - 减少数量
num_results - 若仅需URL,可跳过内容获取
无结果返回?
- 移除过滤器(日期、域名限制)
- 简化查询
- 尝试——它有 fallback 机制
type: "auto"
Resources
资源
- Docs: https://exa.ai/docs
- Dashboard: https://dashboard.exa.ai
- API Status: https://status.exa.ai