docs/exa-search.mdXem bản gốc Bản dịch đầy đủ theo đúng cấu trúc tài liệu; code, liên kết và định danh kỹ thuật được giữ nguyên.
Tìm kiếm Exa
ExaSearch cung cấp cho agent các công cụ nghiên cứu web được hỗ trợ bởi
Exa API tìm kiếm: tìm kiếm trả về kết quả phù hợp nhất
đoạn trích từ mỗi lần truy cập (có tóm tắt văn bản tổng hợp tùy chọn), toàn trang
truy xuất để tìm hiểu sâu về một URL cụ thể và chọn tham gia tìm kiếm sâu
tổng hợp một câu trả lời được trích dẫn trong một cuộc gọi. Sự riêng biệt ExaAgent khả năng
ủy quyền nghiên cứu dài hạn cho API Exa Agent dưới dạng lệnh gọi công cụ bị trì hoãn.
Mặc dù Pydantic AI Harness có trên các bản phát hành 0.x nhưng API có thể thay đổi giữa các bản phát hành nhỏ; khi đó, cảnh báo ngừng sử dụng và hướng dẫn di chuyển ghi chú phát hành sẽ cho bạn (hoặc người đại diện của bạn) biết chính xác cách nâng cấp. Xem chính sách phiên bản.
vấn đề
Các công cụ tìm kiếm chỉ trả về tiêu đề và đoạn trích buộc phải thực hiện vòng thứ hai tìm nạp trước khi agent có thể đánh giá một nguồn, trong khi các công cụ tìm kiếm trả về văn bản toàn trang tràn ngập bối cảnh với các trang mà agent sẽ loại bỏ. Đấu dây một API tìm kiếm cùng với trình tìm nạp trang, lập ngân sách cho những gì mỗi công cụ trả về và thúc đẩy agent nghiên cứu một cách có phương pháp là bản soạn sẵn cho mọi nghiên cứu agent tái phát minh.
ExaSearch bó hệ thống ống nước thành một
khả năng: công cụ nghiên cứu, mỗi công cụ
ngân sách đầu ra và hướng dẫn nghiên cứu ngắn gọn trong lời nhắc hệ thống.
Cách sử dụng
Cài đặt exa thêm và thiết lập EXA_API_KEY biến môi trường (tạo
một chìa khóa tại https://dashboard.exa.ai):
uv add "pydantic-ai-harness[exa]"
Sau đó vượt qua ExaSearch đến một Agent thông qua capabilities tham số:
from pydantic_ai import Agent
from pydantic_ai_harness import ExaSearch
agent = Agent('anthropic:claude-sonnet-4-6', capabilities=[ExaSearch()])
result = agent.run_sync('What changed in the latest stable Python release?')
print(result.output)
Công cụ
ExaSearch đóng góp những công cụ này cho agent:
| Công cụ | Mục đích |
|---|---|
web_search | Tìm kiếm trên web và trở về đầu num_results các trang, mỗi trang có tiêu đề, URL và các đoạn trích phù hợp nhất. |
get_page | Truy xuất toàn bộ văn bản của một URL cụ thể -- một URL đầy hứa hẹn web_search lần truy cập hoặc URL mà người dùng đã cung cấp. |
deep_search | Chạy tìm kiếm sâu nhiều bước của Exa và trả về câu trả lời tổng hợp, được trích dẫn. Chọn tham gia qua include_deep_search=True. |
exa_agent | Ủy thác nhiệm vụ nghiên cứu cho việc chạy agent Exa không đồng bộ. Được cung cấp bởi riêng biệt ExaAgent khả năng. |
web_search trả về các đoạn trích ngắn (Exa nổi bật) thay vì toàn trang
văn bản, tuân theo hướng dẫn riêng của Exa dành cho tổng đài viên,
vì vậy việc khảo sát một số nguồn vẫn rẻ; agent đọc một trang đã chọn với
get_page.
get_page văn bản được giới hạn ở max_text_chars ký tự, giữ đầu
(dẫn đầu của một trang mang nội dung). Một ký tự của khoảng không phía trên nắp
được yêu cầu từ Exa, vì vậy khi một trang vượt quá giới hạn, đầu ra sẽ kết thúc bằng
[... page text truncated at N characters] điểm đánh dấu; ở mức trần API của
10.000 ký tự không tồn tại khoảng trống nên điểm đánh dấu không thể xuất hiện ở đó. các
số kết quả được giới hạn theo cùng một cách: num_results được yêu cầu từ Exa và
áp dụng lại cho câu trả lời.
URL hoặc câu hỏi không trả về nội dung, giới hạn tỷ lệ hoặc API tạm thời hoặc
Lỗi mạng xuất hiện trong mô hình dưới dạng
ModelRetry chứ không phải là một
lỗi cứng: quá trình chạy tiếp tục và mô hình có thể sửa URL, diễn đạt lại hoặc
thử lại. Lỗi xác thực (401/403) là lỗi cấu hình và
tuyên truyền.
Tìm kiếm sâu
deep_search gọi tìm kiếm Exa với type='deep' và một đầu ra văn bản thuần túy
lược đồ: Exa mở rộng câu hỏi thành nhiều truy vấn, tìm kiếm và trả về
một câu trả lời dựa trên các trích dẫn -- tất cả đều có trong một lệnh gọi công cụ, với trích dẫn
các nguồn được liệt kê dưới câu trả lời. Mỗi cuộc gọi đầu tư nhiều thời gian và độ sâu tìm kiếm hơn
hơn web_search (Chế độ cấp độ nghiên cứu của Exa) và mô hình quyết định thời điểm thực hiện
gọi các công cụ, do đó công cụ này bị tắt theo mặc định -- bật nó một cách rõ ràng:
from pydantic_ai_harness import ExaSearch
ExaSearch(include_deep_search=True)
Khi được bật, hướng dẫn của khả năng sẽ yêu cầu mô hình coi nó như một
leo thang từ web_search, không phải là sự thay thế Câu trả lời tổng hợp là
được trả về đầy đủ (nó được tạo bởi Exa và vốn đã bị giới hạn); max_text_chars
chỉ áp dụng cho get_page.
Tóm tắt văn bản
Đặt text_summary có mọi thứ web_search gọi cũng yêu cầu Exa's
lược đồ đầu ra văn bản thuần túy, do đó phản hồi mang một bản tóm tắt ngắn được tổng hợp
từ các kết quả cho các truy vấn kiểu câu hỏi. Vượt qua True cho một không bị hạn chế
tóm tắt hoặc một chuỗi mô tả định dạng mong muốn (được gửi dưới dạng
description):
from pydantic_ai_harness import ExaSearch
ExaSearch(text_summary='One concise sentence with the requested facts.')
Hình dạng trả về của công cụ không thay đổi và tương thích ngược: danh sách kết quả
được trả về như trước và khi Exa trả về một bản tóm tắt, nó được thêm vào trước dưới dạng
Summary: dòng.
Trích dẫn có cấu trúc
Mỗi công cụ đều trả về một
ToolReturn:
return_value mang văn bản có thể đọc được mà mô hình nhìn thấy (không thay đổi từ
phiên bản trước đó, bao gồm cả Sources: khối) và metadata mang theo
các nguồn có cấu trúc ExaSource hồ sơ ({'url': ..., 'title': ...})
dưới 'sources' chìa khóa. Siêu dữ liệu không bao giờ được gửi đến mô hình; cái
ứng dụng đọc nó từ ToolReturnPart trong lịch sử tin nhắn, vì vậy
hiển thị trích dẫn không cần phân tích văn bản:
from pydantic_ai.messages import ModelRequest, ToolReturnPart
for message in result.all_messages():
if isinstance(message, ModelRequest):
for part in message.parts:
if isinstance(part, ToolReturnPart) and part.metadata is not None:
for source in part.metadata.get('sources', []):
print(source['url'], source['title'])
exa_agent kết quả còn mang ID chạy Exa trong siêu dữ liệu trong
RUN_ID_METADATA_KEY.
Hướng dẫn
ExaSearch đóng góp hướng dẫn nghiên cứu ngắn vào lời nhắc của hệ thống: tìm kiếm
rộng với web_search đầu tiên, hãy đọc đầy đủ những trang hứa hẹn nhất với
get_page trước khi đưa ra kết luận, hãy ưu tiên các nguồn chính và trích dẫn
URL dựa vào. Với include_deep_search=True, hướng dẫn cũng bao gồm khi
leo thang đến deep_search. Đặt guidance để thay thế văn bản mặc định, hoặc
để '' để đóng góp không có hướng dẫn nào cả.
Cấu hình
Mỗi lĩnh vực của ExaSearch với mặc định của nó:
from pydantic_ai_harness import ExaSearch
ExaSearch(
num_results=5, # results per web_search call (1 to 100)
max_text_chars=10_000, # get_page text cap, in characters (1 to 10,000)
text_summary=False, # web_search also returns a synthesized text summary
include_deep_search=False, # also expose the deep_search tool
include_domains=[], # only search these domains (allowlist)
exclude_domains=[], # never search these domains (denylist)
guidance=None, # None = default instructions, '' = none, str = custom
client=None, # ExaClient -- None builds exa_py.AsyncExa from EXA_API_KEY
)
include_domains và exclude_domains áp dụng cho web_search và deep_search,
và loại trừ lẫn nhau -- đặt một, không phải cả hai. Giới hạn ngoài phạm vi và
thiết lập cả danh sách tên miền nâng cao khi xây dựng.
agent exa chạy
Exa API agent thực hiện các nhiệm vụ nghiên cứu mở
không đồng bộ: một lần chạy được tạo, di chuyển qua queued -> runningvà
đạt đến trạng thái đầu cuối (completed, failedhoặc cancelled) sau đến
một giờ. Sự riêng biệt ExaAgent khả năng ánh xạ vòng đời vào Pydantic
Cuộc gọi công cụ bị trì hoãn của AI: nó
exa_agent công cụ tạo lần chạy và trì hoãn, mang ID chạy Exa trong
siêu dữ liệu của cuộc gọi bị trì hoãn.
from pydantic_ai import Agent
from pydantic_ai_harness import ExaAgent
agent = Agent('anthropic:claude-sonnet-4-6', capabilities=[ExaAgent()])
Theo mặc định (execution='inline') khả năng giải quyết sự trì hoãn của chính nó
các cuộc gọi trong agent được điều hành bằng cách thăm dò quá trình chạy Exa để hoàn thành, vì vậy công cụ
hoạt động giống như một công cụ thông thường (nếu chậm). Với execution='external' các cuộc gọi
bong bóng lên như DeferredToolRequests đầu ra cho ứng dụng máy chủ giải quyết
ngoài băng tần -- kể cả từ một quy trình khác, vì ID chạy Exa
tồn tại trong siêu dữ liệu yêu cầu bên dưới RUN_ID_METADATA_KEY. của agent
output_type phải bao gồm DeferredToolRequests, nếu không thì lượt chạy sẽ tăng
thay vì trả lại các yêu cầu bị trì hoãn:
from pydantic_ai import Agent
from pydantic_ai.tools import DeferredToolRequests
from pydantic_ai_harness import ExaAgent
agent = Agent(
'anthropic:claude-sonnet-4-6',
output_type=[str, DeferredToolRequests],
capabilities=[ExaAgent(execution='external')],
)
Kết xuất một lần chạy đã hoàn thành với agent_run_result người trợ giúp, đi ngang qua
output_schema khả năng được xây dựng với độ phân giải bên ngoài
áp dụng cùng một xác nhận và tạo ra hình dạng kết quả công cụ giống như nội tuyến
thực thi, sau đó cung cấp kết quả và lịch sử tin nhắn ban đầu vào
agent tiếp tục quá trình chạy bị trì hoãn:
from pydantic_ai.tools import DeferredToolResults
from pydantic_ai_harness.exa import RUN_ID_METADATA_KEY, agent_run_result
async def resolve(requests, runs, output_schema=None): # e.g. in a worker process
results = DeferredToolResults()
for call in requests.calls:
run_id = requests.metadata[call.tool_call_id][RUN_ID_METADATA_KEY]
run = await runs.poll_until_finished(run_id)
results.calls[call.tool_call_id] = agent_run_result(run, output_schema=output_schema)
return results
async def resume(agent, messages, results):
return await agent.run(message_history=messages, deferred_tool_results=results)
Mỗi lĩnh vực của ExaAgent với mặc định của nó:
from pydantic_ai_harness import ExaAgent
ExaAgent(
effort=None, # 'low' | 'medium' | 'high' | 'xhigh' | 'auto' -- None = API default
execution='inline', # 'inline' polls to completion; 'external' bubbles DeferredToolRequests
output_schema=None, # BaseModel class or dict schema for structured output
system_prompt=None, # forwarded to the Exa agent run
poll_interval=1000, # ms between polls when resolving inline
timeout_ms=3_600_000, # ms to wait for a run when resolving inline
guidance=None, # None = default instructions, '' = none, str = custom
runs=None, # ExaAgentRuns -- None builds AsyncExa().agent.runs from EXA_API_KEY
)
Một output_schema lớp mô hình được xác nhận dựa trên
đầu ra có cấu trúc của lần chạy đã hoàn thành (bề mặt không khớp vì ModelRetry),
trong khi lược đồ dict được chuyển tiếp mà không cần xác thực phía máy khách và là
biểu mẫu đặc tả agent. Lỗi terminal (failed, cancelled) được trả về
mô hình hóa như một thông điệp có cấu trúc thay vì được nêu ra, vì vậy agent có thể quyết định cách thức
để tiếp tục. Mỗi kết quả bao gồm ID chạy mà mô hình có thể gửi lại dưới dạng
previous_run_id để đặt câu hỏi tiếp theo trong bối cảnh của lần chạy trước.
Nhiều trường hợp
Hai phiên bản có cùng khả năng đăng ký cùng một tên công cụ, đó là một
lỗi. Để chạy một số phiên bản được cấu hình khác nhau trong một agent (ví dụ:
ví dụ một trang web mở ExaSearch và một được ghim vào các miền cụ thể), hãy gói
các trường hợp bổ sung trong lõi PrefixTools khả năng, tiền tố công cụ của họ
tên:
from pydantic_ai import Agent
from pydantic_ai.capabilities import PrefixTools
from pydantic_ai_harness import ExaSearch
agent = Agent(
'anthropic:claude-sonnet-4-6',
capabilities=[
ExaSearch(), # web_search, get_page
PrefixTools(
wrapped=ExaSearch(include_domains=['crunchbase.com'], guidance=''),
prefix='cb',
), # cb_web_search, cb_get_page
],
)
Đặt guidance='' trên phiên bản được bao bọc (hoặc thay thế nó bằng văn bản cho biết
mô hình khi nào nên sử dụng các công cụ có tiền tố), vì mỗi trường hợp khác
đóng góp hướng dẫn nghiên cứu mặc định tương tự.
Điều này cũng có tác dụng với ExaAgent: nó xác định các cuộc gọi bị trì hoãn bằng siêu dữ liệu
nó được viết khi trì hoãn, không phải theo tên công cụ, vì vậy tiền tố exa_agent vẫn còn
giải quyết nội tuyến và nhiều ExaAgent các trường hợp không bao giờ đòi hỏi của nhau
cuộc gọi.
Khách hàng tùy chỉnh
Máy khách mặc định là exa_py.AsyncExa, được cấu hình từ EXA_API_KEY
biến môi trường; khi biến bị thiếu, việc xây dựng không thành công với
gợi ý thiết lập. Vượt qua bất kỳ đối tượng nào thỏa mãn ExaClient giao thức -- tập hợp con của
AsyncExa lệnh gọi bộ công cụ -- để định cấu hình xác thực hoặc URL cơ sở
một cách rõ ràng hoặc để thay thế hàng giả trong các thử nghiệm:
from exa_py import AsyncExa
from pydantic_ai_harness import ExaSearch
ExaSearch(client=AsyncExa(api_key='...'))
ExaSearch so với WebSearch cốt lõi
Lõi AI Pydantic cung cấp một thiết bị thích ứng với nhà cung cấp
WebSearch
khả năng: trên các kiểu máy có công cụ tìm kiếm gốc, nó sử dụng công cụ tìm kiếm của chính nhà cung cấp
tìm kiếm, thực thi phía máy chủ; ở nơi khác nó rơi trở lại DuckDuckGo cục bộ
công cụ. Hãy tiếp cận nó khi bạn muốn tìm kiếm theo mô hình.
Tiếp cận với ExaSearch khi bạn muốn hành vi tìm kiếm giống nhau trên mọi mô hình:
một nhà cung cấp, các đoạn trích với mỗi lần truy cập, truy xuất trang rõ ràng, bộ lọc tên miền,
và chọn tham gia tìm kiếm sâu.
Một lưu ý khi kết hợp chúng: trên mô hình Anthropic, tìm kiếm gốc của nhà cung cấp
công cụ cũng được đặt tên web_search trên dây, vì vậy
capabilities=[WebSearch(), ExaSearch()] đặt hai công cụ có cùng tên vào
yêu cầu. Sử dụng một khả năng tìm kiếm cho mỗi agent trên các mô hình tìm kiếm gốc hoặc
buộc dự phòng cục bộ với WebSearch(native=False) (công cụ DuckDuckGo của nó là
đặt tên duckduckgo_search, không va chạm).
ExaSearch vs máy chủ MCP của Exa
Exa cũng vận chuyển một máy chủ MCP được lưu trữ chính thức tại https://mcp.exa.ai/mcp
(exa-labs/exa-mcp-server). Bởi
mặc định nó lộ ra web_search_exa và web_fetch_exa; danh mục đầy đủ bổ sung
web_search_advanced_exa và một bộ do agent điều hành (agent_create_run,
agent_wait_for_run, agent_get_run_output, agent_cancel_run).
ExaSearch là đường dẫn được sắp xếp, được nhập: đầu ra bị chặn, thử lại khi trống
hợp đồng, hướng dẫn nghiên cứu đi kèm và mối liên hệ với khách hàng tạo nên nó
có thể kiểm tra ngoại tuyến. Máy chủ MCP là cách bạn có được danh mục đầy đủ của Exa mà không cần tốn nhiều công sức
mã bao bọc, thông qua khả năng MCP của lõi Pydantic AI. Hoạt động agent của họ là
tạo-rồi-thăm dò ý kiến (agent_create_run trả về ID ngay lập tức;
agent_wait_for_run thăm dò nó), ở đâu deep_search trả lại câu trả lời trong một
cuộc gọi duy nhất. Cả hai sáng tác thành một capabilities danh sách và không có MCP nào
tên công cụ va chạm với web_search, get_pagehoặc deep_search:
from pydantic_ai import Agent
from pydantic_ai.capabilities import MCP
from pydantic_ai_harness import ExaSearch
agent = Agent('anthropic:claude-sonnet-4-6', capabilities=[ExaSearch(), MCP('https://mcp.exa.ai/mcp')])
Thông số agent (YAML/JSON)
ExaSearch hoạt động với Pydantic AI
thông số agent, vì vậy bạn có thể khai báo nó trong config
tập tin thay vì Python:
# agent.yaml
model: anthropic:claude-sonnet-4-6
capabilities:
- ExaSearch:
num_results: 3
include_deep_search: true
- ExaAgent:
effort: low
from pydantic_ai import Agent
from pydantic_ai_harness import ExaAgent, ExaSearch
agent = Agent.from_file('agent.yaml', custom_capability_types=[ExaSearch, ExaAgent])
Vượt qua custom_capability_types để trình tải thông số kỹ thuật biết cách khởi tạo
khả năng. các client và runs các trường không được tuần tự hóa theo thông số kỹ thuật;
các phiên bản được tải thông số kỹ thuật luôn xây dựng ứng dụng khách mặc định từ EXA_API_KEY. trong
thông số kỹ thuật, output_schema có dạng chính tả lược đồ JSON; Mô hình Pydantic
các lớp chỉ khả dụng khi xây dựng khả năng trong Python.
Đọc thêm
Tham chiếu API
::: pydantic_ai_harness.exa.ExaSearch
::: pydantic_ai_harness.exa.ExaAgent
::: pydantic_ai_harness.exa.agent_run_result
::: pydantic_ai_harness.exa.ExaSource