Skip to content

Commit 3f14e8b

Browse files
authored
Expand Python agent framework integrations (#235)
* feat(python): expand agent framework adapters * fix(python): address agent adapter review feedback
1 parent 841c8b2 commit 3f14e8b

30 files changed

Lines changed: 1687 additions & 288 deletions

docs/cn/zh-CN/js-sdk.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ const { text } = await generateText({
154154
});
155155
```
156156

157-
[Python SDK](python-sdk.md) 还提供 LangChainOpenAI Agents SDK 适配器。
157+
[Python SDK](python-sdk.md) 还提供 LangChain/LangGraph、OpenAI Agents SDK、CrewAI、AutoGen、LlamaIndex 和 Pydantic AI 适配器。
158158

159159
## 错误处理
160160

docs/cn/zh-CN/python-sdk.md

Lines changed: 74 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -263,60 +263,104 @@ if handled and not is_error:
263263

264264
### 框架集成
265265

266-
把 QVeris 的 discover/inspect/call 工作流暴露为主流 Agent 框架的工具。适配器惰性导入各自框架,因此基础 `qveris` 包不依赖它们。
266+
把 QVeris 的 discover/inspect/call 工作流暴露为主流 Agent 框架的原生工具。适配器惰性导入各自框架,因此基础 `qveris` 包不依赖它们。
267267

268-
**LangChain**
268+
| 框架 | 原生工具类型 | Adapter 安装 | 完整 Agent 还需要 |
269+
|------|--------------|--------------|-------------------|
270+
| LangChain / LangGraph | `StructuredTool` | `pip install "qveris[langchain]"`(Adapter 支持 Python 3.9+) | 下方当前版 `create_agent` 示例需要 Python 3.10+、`langchain>=1.0` 和模型 provider 包。 |
271+
| OpenAI Agents SDK | `FunctionTool` | `pip install "qveris[openai-agents]"`(Python 3.10+) | 将工具传给 `Agent`,最后 `await client.close()`|
272+
| CrewAI | `BaseTool` | `pip install "qveris[crewai]"`(Python 3.10+) | Adapter 负责同步/异步桥接,最后调用 `aclose(client)`|
273+
| AutoGen | `autogen_core.tools.FunctionTool` | `pip install "qveris[autogen]"`(Python 3.10+) | 另装 `autogen-agentchat` 和模型扩展,如 `autogen-ext[openai]`|
274+
| LlamaIndex | `llama_index.core.tools.FunctionTool` | `pip install "qveris[llamaindex]"`(Python 3.10+) | 另装 `FunctionAgent` 使用的模型集成包;使用异步 Agent 或 `await tool.acall(...)`|
275+
| Pydantic AI | `pydantic_ai.Tool` | `pip install "qveris[pydantic-ai]"`(Python 3.10+) | Extra 为精简安装;另装模型 provider extra,如 `pydantic-ai-slim[openai]`|
276+
277+
每次调用 `get_qveris_tools(client, session_id=...)` 都会按顺序返回 `qveris_discover``qveris_inspect``qveris_call` 三个工具。工具结果(包括 QVeris 错误结果)统一为 JSON 字符串,Agent 可以读取并自行调整参数或改选能力。`discover` 免费并返回 `search_id`,后续应把它传给 `inspect``call`。完整 Agent 运行既需要 `QVERIS_API_KEY`,也需要所选模型 provider 的 API key。
278+
279+
**LangChain 与 LangGraph**
280+
281+
使用 LangChain 当前的 `create_agent` API。它运行在 LangGraph 上;自定义 LangGraph 工作流也可以把同一组工具放入 `ToolNode`
269282

270283
```bash
271-
pip install 'qveris[langchain]'
284+
pip install "qveris[langchain]" "langchain>=1.0" langchain-openai
272285
```
273286

274287
```python
288+
import asyncio
289+
290+
from langchain.agents import create_agent
275291
from qveris import QverisClient, QverisConfig
276292
from qveris.integrations.langchain import get_qveris_tools
277293

278-
client = QverisClient(QverisConfig(base_url="https://qveris.cn/api/v1"))
279-
tools = get_qveris_tools(client) # 3 个异步工具:qveris_discover / qveris_inspect / qveris_call
280-
# 把 `tools` 绑定到 LangChain 或 LangGraph agent,用完 `await client.close()`
281-
```
294+
async def main():
295+
client = QverisClient(QverisConfig(base_url="https://qveris.cn/api/v1"))
296+
try:
297+
agent = create_agent("openai:gpt-4o-mini", tools=get_qveris_tools(client))
298+
result = await agent.ainvoke({"messages": [{"role": "user", "content": "查找股票报价工具并查询 AAPL。"}]})
299+
print(result)
300+
finally:
301+
await client.close()
282302

283-
工具是异步的(用 `ainvoke` / 异步 agent executor)。
303+
asyncio.run(main())
304+
```
284305

285306
**OpenAI Agents SDK**
286307

287-
```bash
288-
pip install 'qveris[openai-agents]'
289-
```
290-
291308
```python
309+
import asyncio
310+
292311
from agents import Agent, Runner
293312
from qveris import QverisClient, QverisConfig
294313
from qveris.integrations.openai_agents import get_qveris_tools
295314

296-
client = QverisClient(QverisConfig(base_url="https://qveris.cn/api/v1"))
297-
agent = Agent(name="Assistant", tools=get_qveris_tools(client))
298-
result = await Runner.run(agent, "Find a stock quote capability and quote AAPL.")
299-
await client.close()
315+
async def main():
316+
client = QverisClient(QverisConfig(base_url="https://qveris.cn/api/v1"))
317+
try:
318+
agent = Agent(name="Assistant", tools=get_qveris_tools(client))
319+
result = await Runner.run(agent, "查找股票报价能力并查询 AAPL。")
320+
print(result.final_output)
321+
finally:
322+
await client.close()
323+
324+
asyncio.run(main())
300325
```
301326

302327
**CrewAI**
303328

304-
```bash
305-
pip install 'qveris[crewai]'
306-
```
307-
308329
```python
309330
from crewai import Agent
310331
from qveris import QverisClient, QverisConfig
311-
from qveris.integrations.crewai import get_qveris_tools, aclose
332+
from qveris.integrations.crewai import aclose, get_qveris_tools
312333

313334
client = QverisClient(QverisConfig(base_url="https://qveris.cn/api/v1"))
314-
agent = Agent(role="Researcher", goal="...", backstory="...", tools=get_qveris_tools(client))
315-
# 同步运行你的 crew(crew.kickoff()),然后:
335+
agent = Agent(role="Researcher", goal="选择正确能力", backstory="工具专家", tools=get_qveris_tools(client))
336+
# Crew(...).kickoff()
316337
aclose(client)
317338
```
318339

319-
CrewAI 同步执行工具;适配器在一个专用事件循环上桥接到异步 client。由于 client 的连接绑定在该循环上,请用 `aclose(client)` 关闭(而非 `await client.close()`)。TypeScript SDK 提供 Vercel AI SDK 适配器。
340+
CrewAI 的 client 连接运行在 Adapter 的专用事件循环中,因此要使用 `aclose(client)`,不能使用 `await client.close()`
341+
342+
**AutoGen、LlamaIndex 与 Pydantic AI**
343+
344+
```python
345+
# 以下片段假设已配置 QverisClient 以及框架所需的 model_client / llm;
346+
# 只需选择与你的 Agent 框架对应的 Adapter。
347+
# AutoGen AssistantAgent
348+
from autogen_agentchat.agents import AssistantAgent
349+
from qveris.integrations.autogen import get_qveris_tools
350+
agent = AssistantAgent("assistant", model_client=model_client, tools=get_qveris_tools(client))
351+
352+
# LlamaIndex FunctionAgent
353+
from llama_index.core.agent.workflow import FunctionAgent
354+
from qveris.integrations.llamaindex import get_qveris_tools
355+
agent = FunctionAgent(tools=get_qveris_tools(client), llm=llm)
356+
357+
# Pydantic AI Agent
358+
from pydantic_ai import Agent
359+
from qveris.integrations.pydantic_ai import get_qveris_tools
360+
agent = Agent("openai:gpt-4o-mini", tools=get_qveris_tools(client))
361+
```
362+
363+
完整的 provider 配置与资源关闭方式见下方可运行示例。TypeScript SDK 提供 Vercel AI SDK 适配器。
320364

321365
### 自定义 LLM provider
322366

@@ -359,9 +403,15 @@ agent = Agent(llm_provider=MyProvider())
359403
| `explainable_routing.py` | 基于 `why_recommended` / `expected_cost` 的成本感知能力选型 |
360404
| `budget_guard.py` |`Agent(budget_credits=...)` 设置会话级积分预算 |
361405
| `agent_loop_integration.py` | LLM agent 循环集成 |
406+
| `interactive_chat.py` | 交互式流式终端聊天 |
407+
| `stock_debate.py` | 多 Agent 股票研究辩论 |
362408
| `langchain_integration.py` | 把 QVeris 能力作为 LangChain 工具(`qveris[langchain]`|
363409
| `openai_agents_integration.py` | 把 QVeris 能力作为 OpenAI Agents SDK 工具(`qveris[openai-agents]`|
364410
| `crewai_integration.py` | 把 QVeris 能力作为 CrewAI 工具(`qveris[crewai]`|
411+
| `autogen_integration.py` | 把 QVeris 能力作为 AutoGen 工具(`qveris[autogen]`|
412+
| `llamaindex_integration.py` | 把 QVeris 能力作为 LlamaIndex 工具(`qveris[llamaindex]`|
413+
| `pydantic_ai_integration.py` | 把 QVeris 能力作为 Pydantic AI 工具(`qveris[pydantic-ai]`|
414+
| `otel_tracing.py` | 为 discover/call 生成 OpenTelemetry span(`qveris[otel]`|
365415

366416
设置 `QVERIS_API_KEY` 后,能力示例会运行 `discover`/`inspect`;仅当设置 `RUN_QVERIS_CALLS=1` 时才执行 `call`。运行前请确保已设置 `QVERIS_BASE_URL=https://qveris.cn/api/v1`
367417

docs/en-US/js-sdk.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ const { text } = await generateText({
156156
});
157157
```
158158

159-
The [Python SDK](python-sdk.md) ships LangChain and OpenAI Agents SDK adapters as well.
159+
The [Python SDK](python-sdk.md) ships adapters for LangChain/LangGraph, OpenAI Agents SDK, CrewAI, AutoGen, LlamaIndex, and Pydantic AI as well.
160160

161161
## Error handling
162162

docs/en-US/python-sdk.md

Lines changed: 77 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -260,60 +260,107 @@ if handled and not is_error:
260260

261261
### Framework integrations
262262

263-
Expose the QVeris discover/inspect/call workflow as tools for popular agent frameworks. Adapters import their framework lazily, so the base `qveris` package never depends on them.
263+
Expose the QVeris discover/inspect/call workflow as native tools for popular agent frameworks. Adapters import their framework lazily, so the base `qveris` package never depends on them.
264264

265-
**LangChain**
265+
| Framework | Native tool type | Adapter install | Complete agent setup |
266+
|-----------|------------------|-----------------|----------------------|
267+
| LangChain / LangGraph | `StructuredTool` | `pip install "qveris[langchain]"` (adapter: Python 3.9+) | The current `create_agent` example requires Python 3.10+, `langchain>=1.0`, and a model-provider package. |
268+
| OpenAI Agents SDK | `FunctionTool` | `pip install "qveris[openai-agents]"` (Python 3.10+) | Pass the tools to `Agent`; close with `await client.close()`. |
269+
| CrewAI | `BaseTool` | `pip install "qveris[crewai]"` (Python 3.10+) | Tools are sync/async bridged; close with `aclose(client)`. |
270+
| AutoGen | `autogen_core.tools.FunctionTool` | `pip install "qveris[autogen]"` (Python 3.10+) | Also install `autogen-agentchat` and a model extension such as `autogen-ext[openai]`. |
271+
| LlamaIndex | `llama_index.core.tools.FunctionTool` | `pip install "qveris[llamaindex]"` (Python 3.10+) | Also install the model integration used by `FunctionAgent`; use an async agent or `await tool.acall(...)`. |
272+
| Pydantic AI | `pydantic_ai.Tool` | `pip install "qveris[pydantic-ai]"` (Python 3.10+) | The extra is slim; add a provider extra such as `pydantic-ai-slim[openai]`. |
273+
274+
Every `get_qveris_tools(client, session_id=...)` call returns exactly three tools: `qveris_discover`, `qveris_inspect`, and `qveris_call`. Results, including QVeris error payloads, are JSON strings so the agent can inspect them and recover. `discover` is free and returns a `search_id`; pass that ID to `inspect` and `call`. A complete agent run needs `QVERIS_API_KEY` plus the API key required by its model provider.
275+
276+
**LangChain and LangGraph**
277+
278+
Use LangChain's current `create_agent` API. It runs on LangGraph; custom LangGraph workflows can put the same tools in a `ToolNode`.
266279

267280
```bash
268-
pip install 'qveris[langchain]'
281+
pip install "qveris[langchain]" "langchain>=1.0" langchain-openai
269282
```
270283

271284
```python
285+
import asyncio
286+
287+
from langchain.agents import create_agent
272288
from qveris import QverisClient
273289
from qveris.integrations.langchain import get_qveris_tools
274290

275-
client = QverisClient()
276-
tools = get_qveris_tools(client) # 3 async tools: qveris_discover / qveris_inspect / qveris_call
277-
# bind `tools` to a LangChain or LangGraph agent, then `await client.close()` when done
278-
```
291+
async def main():
292+
client = QverisClient()
293+
try:
294+
agent = create_agent("openai:gpt-4o-mini", tools=get_qveris_tools(client))
295+
result = await agent.ainvoke({"messages": [{"role": "user", "content": "Find a stock quote tool and quote AAPL."}]})
296+
print(result)
297+
finally:
298+
await client.close()
279299

280-
The tools are async (use `ainvoke` / an async agent executor).
300+
asyncio.run(main())
301+
```
281302

282303
**OpenAI Agents SDK**
283304

284-
```bash
285-
pip install 'qveris[openai-agents]'
286-
```
287-
288305
```python
306+
import asyncio
307+
289308
from agents import Agent, Runner
290309
from qveris import QverisClient
291310
from qveris.integrations.openai_agents import get_qveris_tools
292311

293-
client = QverisClient()
294-
agent = Agent(name="Assistant", tools=get_qveris_tools(client))
295-
result = await Runner.run(agent, "Find a stock quote capability and quote AAPL.")
296-
await client.close()
312+
async def main():
313+
client = QverisClient()
314+
try:
315+
agent = Agent(name="Assistant", tools=get_qveris_tools(client))
316+
result = await Runner.run(agent, "Find a stock quote capability and quote AAPL.")
317+
print(result.final_output)
318+
finally:
319+
await client.close()
320+
321+
asyncio.run(main())
297322
```
298323

299324
**CrewAI**
300325

301-
```bash
302-
pip install 'qveris[crewai]'
303-
```
304-
305326
```python
306327
from crewai import Agent
307328
from qveris import QverisClient
308-
from qveris.integrations.crewai import get_qveris_tools, aclose
329+
from qveris.integrations.crewai import aclose, get_qveris_tools
309330

310331
client = QverisClient()
311-
agent = Agent(role="Researcher", goal="...", backstory="...", tools=get_qveris_tools(client))
312-
# run your crew synchronously (crew.kickoff()), then:
332+
agent = Agent(role="Researcher", goal="Use the right capability", backstory="Tool specialist", tools=get_qveris_tools(client))
333+
# Crew(...).kickoff()
313334
aclose(client)
314335
```
315336

316-
CrewAI runs tools synchronously; these bridge to the async client on one dedicated event loop. Close the client with `aclose(client)` (not `await client.close()`), since its connections are bound to that loop. The TypeScript SDK ships a Vercel AI SDK adapter.
337+
CrewAI's client connections run on the adapter's dedicated event loop, so use `aclose(client)` rather than `await client.close()`.
338+
339+
**AutoGen, LlamaIndex, and Pydantic AI**
340+
341+
```python
342+
# The following snippets assume a configured QverisClient plus the framework's
343+
# model_client / llm. Choose the adapter that matches your agent framework.
344+
# AutoGen AssistantAgent
345+
from autogen_agentchat.agents import AssistantAgent
346+
from qveris.integrations.autogen import get_qveris_tools
347+
348+
agent = AssistantAgent("assistant", model_client=model_client, tools=get_qveris_tools(client))
349+
350+
# LlamaIndex FunctionAgent
351+
from llama_index.core.agent.workflow import FunctionAgent
352+
from qveris.integrations.llamaindex import get_qveris_tools
353+
354+
agent = FunctionAgent(tools=get_qveris_tools(client), llm=llm)
355+
356+
# Pydantic AI Agent
357+
from pydantic_ai import Agent
358+
from qveris.integrations.pydantic_ai import get_qveris_tools
359+
360+
agent = Agent("openai:gpt-4o-mini", tools=get_qveris_tools(client))
361+
```
362+
363+
See the runnable examples below for provider setup and complete client cleanup. The TypeScript SDK ships a Vercel AI SDK adapter.
317364

318365
### Custom LLM providers
319366

@@ -356,9 +403,15 @@ Runnable examples live under [`packages/python-sdk/examples/`](https://github.co
356403
| `explainable_routing.py` | Cost-aware capability selection with `why_recommended` / `expected_cost` |
357404
| `budget_guard.py` | Per-session credit budget with `Agent(budget_credits=...)` |
358405
| `agent_loop_integration.py` | LLM agent loop integration |
406+
| `interactive_chat.py` | Interactive streaming terminal chat |
407+
| `stock_debate.py` | Multi-agent stock research debate |
359408
| `langchain_integration.py` | QVeris capabilities as LangChain tools (`qveris[langchain]`) |
360409
| `openai_agents_integration.py` | QVeris capabilities as OpenAI Agents SDK tools (`qveris[openai-agents]`) |
361410
| `crewai_integration.py` | QVeris capabilities as CrewAI tools (`qveris[crewai]`) |
411+
| `autogen_integration.py` | QVeris capabilities as AutoGen tools (`qveris[autogen]`) |
412+
| `llamaindex_integration.py` | QVeris capabilities as LlamaIndex tools (`qveris[llamaindex]`) |
413+
| `pydantic_ai_integration.py` | QVeris capabilities as Pydantic AI tools (`qveris[pydantic-ai]`) |
414+
| `otel_tracing.py` | OpenTelemetry spans for discover/call (`qveris[otel]`) |
362415

363416
Capability examples run `discover`/`inspect` when `QVERIS_API_KEY` is set, and only execute `call` when `RUN_QVERIS_CALLS=1`.
364417

docs/zh-CN/js-sdk.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ const { text } = await generateText({
154154
});
155155
```
156156

157-
[Python SDK](python-sdk.md) 还提供 LangChainOpenAI Agents SDK 适配器。
157+
[Python SDK](python-sdk.md) 还提供 LangChain/LangGraph、OpenAI Agents SDK、CrewAI、AutoGen、LlamaIndex 和 Pydantic AI 适配器。
158158

159159
## 错误处理
160160

0 commit comments

Comments
 (0)