Running Agents - 运行 Agent
概述
通过调用 Agent.run() 或 Agent.arun() 来运行 Agent。
执行流程
- Agent 构建要发送给模型的上下文(系统消息、用户消息、聊天历史、用户记忆、会话状态等)
- Agent 将上下文发送给模型
- 模型返回消息或工具调用
- 如果模型进行工具调用,Agent 执行工具并将结果返回给模型
- 模型处理更新后的上下文,重复此循环直到生成最终消息(无工具调用)
- Agent 将最终响应返回给调用者
1. 基本执行
知识点说明
Agent.run() 返回 RunOutput 对象,当 stream=True 时返回 RunOutputEvent 对象的流。这是生产环境中最常用的运行方式。
代码示例 1: 基础 run() 方法
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.utils.pprint import pprint_run_response
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[DuckDuckGoTools()],
instructions="Search for information and provide summaries.",
markdown=True,
)
# 运行 agent 并将响应作为变量返回
response: RunOutput = agent.run("What is machine learning?")
# 以 markdown 格式打印响应
pprint_run_response(response, markdown=True)
代码示例 2: 访问 RunOutput 的所有属性
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
from agno.tools.duckduckgo import DuckDuckGoTools
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[DuckDuckGoTools()],
instructions="Search for information.",
)
response: RunOutput = agent.run("What is Python?")
# 访问所有可用属性
print(f"=== RunOutput 属性 ===")
print(f"run_id: {response.run_id}") # 运行的唯一 ID
print(f"agent_id: {response.agent_id}") # Agent 的 ID
print(f"agent_name: {response.agent_name}") # Agent 的名称
print(f"session_id: {response.session_id}") # 会话 ID
print(f"user_id: {response.user_id}") # 用户 ID
print(f"content: {response.content}") # 响应内容
print(f"content_type: {response.content_type}") # 内容类型
print(f"reasoning_content: {response.reasoning_content}") # 推理内容
print(f"messages count: {len(response.messages)}") # 消息数量
print(f"metrics: {response.metrics}") # 运行指标
print(f"model: {response.model}") # 使用的模型
代码示例 3: 异步运行 arun()
python
import asyncio
from agno.agent import Agent
from agno.models.deepseek import DeepSeek
from agno.tools.duckduckgo import DuckDuckGoTools
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[DuckDuckGoTools()],
instructions="Search for information.",
)
async def main():
# 使用 arun() 异步运行
response = await agent.arun("What is async programming?")
print(f"Content: {response.content}")
print(f"Run ID: {response.run_id}")
# 运行异步函数
asyncio.run(main())
代码示例 4: 带错误处理的运行
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
try:
response: RunOutput = agent.run("What is AI?")
print(f"Success! Response: {response.content}")
except Exception as e:
print(f"Error occurred: {type(e).__name__}: {e}")
代码示例 5: 多次运行同一个 Agent
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
from agno.tools.duckduckgo import DuckDuckGoTools
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[DuckDuckGoTools()],
instructions="Search for information.",
)
# 第一次运行
response1: RunOutput = agent.run("What is Python?")
print(f"Run 1 - ID: {response1.run_id}, Content: {response1.content[:100]}...")
# 第二次运行(同一个 Agent,会保持会话历史)
response2: RunOutput = agent.run("What are its main features?")
print(f"Run 2 - ID: {response2.run_id}, Content: {response2.content[:100]}...")
# 第三次运行
response3: RunOutput = agent.run("Compare it with JavaScript")
print(f"Run 3 - ID: {response3.run_id}, Content: {response3.content[:100]}...")
2. 运行输入
知识点说明
input 参数可以是字符串、列表、字典、消息、Pydantic 模型或消息列表。这让 Agent 可以处理各种格式的输入。
代码示例 1: 字符串输入
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
# 字符串输入(最常用)
response: RunOutput = agent.run("What is AI?")
print(f"Response: {response.content}")
代码示例 2: 使用 input 参数明确指定
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
# 使用 input 参数明确指定输入
response: RunOutput = agent.run(input="What is machine learning?")
print(f"Response: {response.content}")
代码示例 3: 列表输入(多轮对话)
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
# 列表输入 - 提供对话历史
messages = [
{"role": "user", "content": "What is Python?"},
{"role": "assistant", "content": "Python is a programming language."},
{"role": "user", "content": "What are its main features?"}
]
response: RunOutput = agent.run(messages)
print(f"Response: {response.content}")
代码示例 4: Pydantic 模型输入
python
from pydantic import BaseModel
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
class QueryInput(BaseModel):
question: str
context: str = ""
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer the question based on the context provided.",
)
# Pydantic 模型输入
query = QueryInput(
question="What is the capital?",
context="We are discussing France."
)
response: RunOutput = agent.run(query)
print(f"Response: {response.content}")
代码示例 5: 字典输入
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
# 字典输入
data = {
"question": "What is AI?",
"language": "English",
"detail_level": "brief"
}
response: RunOutput = agent.run(data)
print(f"Response: {response.content}")
3. 运行输出详解
知识点说明
Agent.run() 在非流式模式下返回 RunOutput 对象。这个对象包含了运行的所有信息,包括内容、元数据、指标等。
代码示例 1: RunOutput 核心属性
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
response: RunOutput = agent.run("What is AI?")
# 核心属性
print(f"run_id: {response.run_id}") # 运行的唯一标识
print(f"agent_id: {response.agent_id}") # Agent 标识
print(f"agent_name: {response.agent_name}") # Agent 名称
print(f"session_id: {response.session_id}") # 会话标识
print(f"user_id: {response.user_id}") # 用户标识
print(f"content: {response.content}") # 响应内容
print(f"content_type: {response.content_type}") # 内容类型
代码示例 2: 访问推理内容
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Think step by step.",
)
response: RunOutput = agent.run("What is 15 * 23?")
# 访问推理内容(如果模型支持)
if response.reasoning_content:
print(f"Reasoning: {response.reasoning_content}")
else:
print("No reasoning content available")
print(f"Final answer: {response.content}")
代码示例 3: 访问消息历史
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
response: RunOutput = agent.run("What is Python?")
# 访问所有消息
print(f"Total messages: {len(response.messages)}")
for i, msg in enumerate(response.messages):
print(f"Message {i}: {msg.role} - {msg.content[:50]}...")
代码示例 4: 访问运行指标
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
response: RunOutput = agent.run("Explain quantum computing")
# 访问指标
if response.metrics:
print(f"Metrics: {response.metrics}")
# 可能包含:token 使用量、运行时间等
代码示例 5: 检查运行状态
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
response: RunOutput = agent.run("What is AI?")
# 检查各种属性是否存在
print(f"Has content: {response.content is not None}")
print(f"Has messages: {len(response.messages) > 0}")
print(f"Has metrics: {response.metrics is not None}")
print(f"Model used: {response.model}")
4. 流式输出
知识点说明
设置 stream=True 以返回 RunOutputEvent 对象的迭代器。流式输出适合实时显示响应,提升用户体验。
代码示例 1: 基础流式输出
python
from typing import Iterator
from agno.agent import Agent, RunOutputEvent, RunEvent
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
# 流式输出
stream: Iterator[RunOutputEvent] = agent.run("Tell me a story", stream=True)
print("Streaming: ", end="", flush=True)
for chunk in stream:
if chunk.event == RunEvent.run_content:
print(chunk.content, end="", flush=True)
print("\nDone!")
代码示例 2: 异步流式输出
python
import asyncio
from agno.agent import Agent, RunEvent
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
async def main():
# 异步流式输出
stream = agent.arun("Tell me a joke", stream=True)
print("Streaming: ", end="", flush=True)
async for chunk in await stream:
if chunk.event == RunEvent.run_content:
print(chunk.content, end="", flush=True)
print("\nDone!")
asyncio.run(main())
代码示例 3: 带进度显示的流式输出
python
from typing import Iterator
from agno.agent import Agent, RunOutputEvent, RunEvent
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Write a long essay about AI.",
)
stream: Iterator[RunOutputEvent] = agent.run("Write about AI history", stream=True)
content_buffer = ""
chunk_count = 0
for chunk in stream:
if chunk.event == RunEvent.run_content:
content_buffer += chunk.content
chunk_count += 1
# 每 10 个块显示一次进度
if chunk_count % 10 == 0:
print(f"\rReceived {chunk_count} chunks, {len(content_buffer)} chars", end="")
print(f"\n\nTotal: {chunk_count} chunks, {len(content_buffer)} characters")
代码示例 4: 流式输出并保存到文件
python
from typing import Iterator
from agno.agent import Agent, RunOutputEvent, RunEvent
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Write a detailed report.",
)
stream: Iterator[RunOutputEvent] = agent.run("Report on climate change", stream=True)
# 同时显示和保存
with open("output.txt", "w", encoding="utf-8") as f:
print("Streaming: ", end="", flush=True)
for chunk in stream:
if chunk.event == RunEvent.run_content:
print(chunk.content, end="", flush=True)
f.write(chunk.content)
f.flush()
print("\n\nSaved to output.txt")
代码示例 5: 流式输出带打字机效果
python
import time
from typing import Iterator
from agno.agent import Agent, RunOutputEvent, RunEvent
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
stream: Iterator[RunOutputEvent] = agent.run("What is Python?", stream=True)
print("Response: ", end="", flush=True)
for chunk in stream:
if chunk.event == RunEvent.run_content:
for char in chunk.content:
print(char, end="", flush=True)
time.sleep(0.01) # 打字机效果延迟
print("\n")
5. 流式事件
知识点说明
默认情况下,只流式传输 RunContent 事件(模型响应)。要流式传输所有事件(工具调用、推理、记忆更新等),请设置 stream_events=True。
代码示例 1: 启用所有事件流
python
from typing import Iterator
from agno.agent import Agent, RunOutputEvent
from agno.models.deepseek import DeepSeek
from agno.tools.duckduckgo import DuckDuckGoTools
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[DuckDuckGoTools()],
instructions="Search for information.",
)
# 启用所有事件流
response_stream: Iterator[RunOutputEvent] = agent.run(
"Latest AI news",
stream=True,
stream_events=True # 启用所有事件
)
for event in response_stream:
print(f"Event type: {event.event}")
代码示例 2: 处理不同类型的事件
python
from typing import Iterator
from agno.agent import Agent, RunOutputEvent, RunEvent
from agno.models.deepseek import DeepSeek
from agno.tools.duckduckgo import DuckDuckGoTools
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[DuckDuckGoTools()],
instructions="Search for information.",
)
stream: Iterator[RunOutputEvent] = agent.run(
"What is machine learning?",
stream=True,
stream_events=True
)
for chunk in stream:
if chunk.event == RunEvent.run_started:
print("[🚀 Run started]")
elif chunk.event == RunEvent.run_content:
print(chunk.content, end="", flush=True)
elif chunk.event == RunEvent.tool_call_started:
print(f"\n[🔧 Tool call started: {chunk.tool.tool_name}]")
elif chunk.event == RunEvent.tool_call_completed:
print(f"[✅ Tool call completed]")
elif chunk.event == RunEvent.run_completed:
print("\n[✨ Run completed]")
elif chunk.event == RunEvent.run_error:
print(f"\n[❌ Error: {chunk.error}]")
代码示例 3: 统计各种事件数量
python
from typing import Iterator
from agno.agent import Agent, RunOutputEvent, RunEvent
from agno.models.deepseek import DeepSeek
from agno.tools.duckduckgo import DuckDuckGoTools
from collections import Counter
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[DuckDuckGoTools()],
instructions="Search for information.",
)
stream: Iterator[RunOutputEvent] = agent.run(
"Latest technology trends",
stream=True,
stream_events=True
)
event_counts = Counter()
content_chunks = 0
for chunk in stream:
event_counts[chunk.event] += 1
if chunk.event == RunEvent.run_content:
content_chunks += 1
print(chunk.content, end="", flush=True)
print("\n\n=== Event Statistics ===")
for event_type, count in event_counts.most_common():
print(f"{event_type}: {count}")
print(f"Total content chunks: {content_chunks}")
代码示例 4: 只监控工具调用事件
python
from typing import Iterator
from agno.agent import Agent, RunOutputEvent, RunEvent
from agno.models.deepseek import DeepSeek
from agno.tools.duckduckgo import DuckDuckGoTools
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[DuckDuckGoTools()],
instructions="Search for information.",
)
stream: Iterator[RunOutputEvent] = agent.run(
"What is Python programming?",
stream=True,
stream_events=True
)
print("Monitoring tool calls...")
tool_calls = []
for chunk in stream:
if chunk.event == RunEvent.tool_call_started:
tool_info = {
"name": chunk.tool.tool_name,
"arguments": chunk.tool.arguments if hasattr(chunk.tool, 'arguments') else None
}
tool_calls.append(tool_info)
print(f"[Tool started: {tool_info['name']}]")
elif chunk.event == RunEvent.tool_call_completed:
print(f"[Tool completed]")
elif chunk.event == RunEvent.run_content:
print(chunk.content, end="", flush=True)
print(f"\n\nTotal tool calls: {len(tool_calls)}")
for tool in tool_calls:
print(f" - {tool['name']}")
代码示例 5: 构建事件时间线
python
from typing import Iterator
from agno.agent import Agent, RunOutputEvent, RunEvent
from agno.models.deepseek import DeepSeek
from agno.tools.duckduckgo import DuckDuckGoTools
from datetime import datetime
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[DuckDuckGoTools()],
instructions="Search for information.",
)
stream: Iterator[RunOutputEvent] = agent.run(
"Latest AI developments",
stream=True,
stream_events=True
)
timeline = []
start_time = datetime.now()
for chunk in stream:
elapsed = (datetime.now() - start_time).total_seconds()
timeline.append({
"time": f"{elapsed:.3f}s",
"event": chunk.event
})
if chunk.event == RunEvent.run_content:
print(chunk.content, end="", flush=True)
print("\n\n=== Event Timeline ===")
for entry in timeline[:20]: # 只显示前 20 个事件
print(f"[{entry['time']}] {entry['event']}")
if len(timeline) > 20:
print(f"... and {len(timeline) - 20} more events")
6. 事件类型详解
知识点说明
Agent.run() 和 Agent.arun() 产生多种类型的事件,让你可以完全了解 Agent 的内部过程。
核心事件
| 事件类型 | 说明 |
|---|---|
RunStarted |
表示运行开始 |
RunContent |
包含模型响应文本的单个块 |
RunContentCompleted |
表示内容流式传输完成 |
RunIntermediateContent |
包含模型的中间响应文本 |
RunCompleted |
表示运行成功完成 |
RunError |
表示运行过程中发生错误 |
RunCancelled |
表示运行被取消 |
控制流事件
| 事件类型 | 说明 |
|---|---|
RunPaused |
表示运行已暂停 |
RunContinued |
表示暂停的运行已继续 |
工具事件
| 事件类型 | 说明 |
|---|---|
ToolCallStarted |
表示工具调用开始 |
ToolCallCompleted |
表示工具调用完成 |
推理事件
| 事件类型 | 说明 |
|---|---|
ReasoningStarted |
表示推理过程开始 |
ReasoningStep |
包含推理过程中的单个步骤 |
ReasoningCompleted |
表示推理过程完成 |
代码示例:处理所有事件类型
python
from typing import Iterator
from agno.agent import Agent, RunOutputEvent, RunEvent
from agno.models.deepseek import DeepSeek
from agno.tools.duckduckgo import DuckDuckGoTools
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[DuckDuckGoTools()],
instructions="Search for information.",
)
stream: Iterator[RunOutputEvent] = agent.run(
"What is quantum computing?",
stream=True,
stream_events=True
)
event_handlers = {
RunEvent.run_started: lambda: print("[🚀 Started]"),
RunEvent.run_content: lambda c: print(c.content, end="", flush=True),
RunEvent.run_content_completed: lambda: print("\n[✅ Content completed]"),
RunEvent.run_completed: lambda: print("[🎉 Run completed]"),
RunEvent.run_error: lambda c: print(f"[❌ Error: {c.error}]"),
RunEvent.tool_call_started: lambda c: print(f"\n[🔧 Tool: {c.tool.tool_name}]"),
RunEvent.tool_call_completed: lambda: print("[✅ Tool completed]"),
RunEvent.reasoning_started: lambda: print("[🤔 Reasoning started]"),
RunEvent.reasoning_step: lambda c: print(f"[💭 {c.reasoning_content[:50]}...]"),
RunEvent.reasoning_completed: lambda: print("[✅ Reasoning completed]"),
}
for chunk in stream:
handler = event_handlers.get(chunk.event)
if handler:
handler(chunk)
7. 自定义事件
知识点说明
通过扩展 CustomEvent 创建自定义事件,可以在工具中生成自定义事件,实现更丰富的交互。
代码示例 1: 创建自定义事件
python
from dataclasses import dataclass
from agno.run.agent import CustomEvent
from typing import Optional
@dataclass
class CustomerProfileEvent(CustomEvent):
"""自定义事件:客户资料"""
customer_name: Optional[str] = None
customer_email: Optional[str] = None
customer_phone: Optional[str] = None
customer_id: Optional[str] = None
代码示例 2: 在工具中生成自定义事件
python
from agno.tools import tool
from agno.agent import Agent
from agno.models.deepseek import DeepSeek
@tool()
async def get_customer_profile(customer_id: str):
"""获取客户资料的示例工具"""
# 模拟从数据库获取客户信息
yield CustomerProfileEvent(
customer_id=customer_id,
customer_name="John Doe",
customer_email="john.doe@example.com",
customer_phone="1234567890",
)
# 返回实际数据
return {
"id": customer_id,
"name": "John Doe",
"email": "john.doe@example.com"
}
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[get_customer_profile],
)
代码示例 3: 处理自定义事件
python
from typing import Iterator
from agno.agent import Agent, RunOutputEvent, RunEvent
from agno.models.deepseek import DeepSeek
# 假设我们已经定义了 CustomerProfileEvent
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[get_customer_profile],
)
stream: Iterator[RunOutputEvent] = agent.run(
"Get customer profile for ID 12345",
stream=True,
stream_events=True
)
for chunk in stream:
# 检查是否是自定义事件
if hasattr(chunk, 'customer_name'):
print(f"[Customer Event] Name: {chunk.customer_name}")
print(f"[Customer Event] Email: {chunk.customer_email}")
elif chunk.event == RunEvent.run_content:
print(chunk.content, end="", flush=True)
代码示例 4: 多个自定义事件类型
python
from dataclasses import dataclass
from agno.run.agent import CustomEvent
from typing import Optional
@dataclass
class ProgressEvent(CustomEvent):
"""进度事件"""
step: int
total_steps: int
message: str
@dataclass
class DataLoadedEvent(CustomEvent):
"""数据加载事件"""
source: str
record_count: int
@dataclass
class ValidationEvent(CustomEvent):
"""验证事件"""
field: str
is_valid: bool
error_message: Optional[str] = None
代码示例 5: 带进度报告的长时间运行工具
python
from agno.tools import tool
import asyncio
@tool()
async def process_large_dataset(dataset_id: str):
"""处理大型数据集,带进度报告"""
total_steps = 5
for step in range(1, total_steps + 1):
# 模拟处理
await asyncio.sleep(0.5)
# 发送进度事件
yield ProgressEvent(
step=step,
total_steps=total_steps,
message=f"Processing step {step}/{total_steps}"
)
return {"status": "completed", "dataset_id": dataset_id}
8. 指定运行的用户和会话
知识点说明
传递 user_id 和 session_id 将运行与特定用户和会话关联。这对于多用户应用和会话管理非常重要。
代码示例 1: 基础用户和会话指定
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
# 指定用户和会话
response: RunOutput = agent.run(
"What is AI?",
user_id="john@example.com",
session_id="session_123"
)
print(f"Response: {response.content}")
print(f"User ID: {response.user_id}")
print(f"Session ID: {response.session_id}")
代码示例 2: 多用户会话管理
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="You are a helpful assistant. Remember our conversation.",
)
# 用户 1 的会话
user1_session = "user1_session_001"
response1: RunOutput = agent.run(
"My name is Alice",
user_id="alice@example.com",
session_id=user1_session
)
response2: RunOutput = agent.run(
"What is my name?",
user_id="alice@example.com",
session_id=user1_session
)
print(f"User 1 - Should remember name: {response2.content}")
# 用户 2 的会话(不同的 session_id)
user2_session = "user2_session_001"
response3: RunOutput = agent.run(
"What is my name?",
user_id="bob@example.com",
session_id=user2_session
)
print(f"User 2 - Should not know name: {response3.content}")
代码示例 3: 会话状态传递
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer based on the context.",
)
# 传递会话状态
session_state = {
"user_name": "Alice",
"user_role": "premium",
"preferences": {"language": "English", "detail_level": "high"}
}
response: RunOutput = agent.run(
"What are my preferences?",
user_id="alice@example.com",
session_id="session_123",
session_state=session_state
)
print(f"Response: {response.content}")
代码示例 4: 为不同用户创建隔离的 Agent 实例
python
from agno.agent import Agent
from agno.models.deepseek import DeepSeek
# 为每个用户创建独立的 Agent 配置
def create_agent_for_user(user_id: str, user_role: str):
"""为特定用户创建 Agent"""
instructions = f"You are assisting user {user_id} with role {user_role}."
if user_role == "admin":
instructions += " You have access to advanced features."
return Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions=instructions,
)
# 为不同用户创建 Agent
admin_agent = create_agent_for_user("admin@example.com", "admin")
user_agent = create_agent_for_user("user@example.com", "standard")
# 运行查询
admin_response = admin_agent.run("What can you do?", user_id="admin@example.com")
user_response = user_agent.run("What can you do?", user_id="user@example.com")
print(f"Admin response: {admin_response.content}")
print(f"User response: {user_response.content}")
代码示例 5: 会话历史管理
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="You are a helpful assistant with memory.",
)
session_id = "persistent_session_001"
user_id = "user@example.com"
# 第一轮对话
response1: RunOutput = agent.run(
"I love Python programming",
user_id=user_id,
session_id=session_id
)
print(f"Turn 1: {response1.content}")
# 第二轮对话(应该记住上下文)
response2: RunOutput = agent.run(
"What programming language do I love?",
user_id=user_id,
session_id=session_id
)
print(f"Turn 2: {response2.content}")
# 第三轮对话
response3: RunOutput = agent.run(
"Can you recommend resources for learning it?",
user_id=user_id,
session_id=session_id
)
print(f"Turn 3: {response3.content}")
9. 传递多媒体内容
知识点说明
通过 images、audio、video 或 files 参数传递媒体,让 Agent 能够处理多模态输入。
代码示例 1: 传递图片 URL
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
from agno.media import Image
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Describe images in detail.",
)
# 传递图片 URL
response: RunOutput = agent.run(
"What is in this image?",
images=[Image(url="https://example.com/image.jpg")]
)
print(f"Response: {response.content}")
代码示例 2: 传递本地图片文件
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
from agno.media import Image
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Analyze images.",
)
# 传递本地图片
with open("local_image.png", "rb") as f:
image_data = f.read()
response: RunOutput = agent.run(
"Describe this image",
images=[Image(content=image_data)]
)
print(f"Response: {response.content}")
代码示例 3: 传递多个图片
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
from agno.media import Image
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Compare and analyze images.",
)
# 传递多个图片
images = [
Image(url="https://example.com/image1.jpg"),
Image(url="https://example.com/image2.jpg"),
Image(url="https://example.com/image3.jpg"),
]
response: RunOutput = agent.run(
"Compare these three images and tell me the differences",
images=images
)
print(f"Response: {response.content}")
代码示例 4: 传递音频文件
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
from agno.media import Audio
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Transcribe and analyze audio.",
)
# 传递音频文件
response: RunOutput = agent.run(
"Transcribe this audio",
audio=[Audio(filepath="recording.mp3")]
)
print(f"Transcription: {response.content}")
代码示例 5: 同时传递多种媒体类型
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
from agno.media import Image, Audio, Video
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Analyze multimedia content.",
)
# 同时传递图片和视频
response: RunOutput = agent.run(
"Analyze the content of these media files",
images=[Image(url="https://example.com/photo.jpg")],
video=[Video(url="https://example.com/video.mp4")],
)
print(f"Response: {response.content}")
10. 结构化输出
知识点说明
传递输出模式以进行结构化输出,让 Agent 返回特定格式的数据(如 JSON、Pydantic 模型等)。
代码示例 1: 使用 Pydantic 模型作为输出模式
python
from pydantic import BaseModel
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
# 定义输出模式
class TVShow(BaseModel):
title: str
genre: str
episodes: int
rating: float
description: str
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Create a TV show concept.",
)
# 使用 output_schema 指定输出格式
response: RunOutput = agent.run(
"Create a sci-fi TV show",
output_schema=TVShow
)
# 解析为 Pydantic 对象
tv_show = TVShow.model_validate_json(response.content)
print(f"Title: {tv_show.title}")
print(f"Genre: {tv_show.genre}")
print(f"Episodes: {tv_show.episodes}")
print(f"Rating: {tv_show.rating}")
print(f"Description: {tv_show.description}")
代码示例 2: 复杂的嵌套模型输出
python
from pydantic import BaseModel
from typing import List
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
class Character(BaseModel):
name: str
role: str
description: str
class Movie(BaseModel):
title: str
year: int
director: str
characters: List[Character]
plot_summary: str
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Create a movie concept with detailed characters.",
)
response: RunOutput = agent.run(
"Create a thriller movie concept",
output_schema=Movie
)
movie = Movie.model_validate_json(response.content)
print(f"Movie: {movie.title} ({movie.year})")
print(f"Director: {movie.director}")
print(f"\nCharacters:")
for char in movie.characters:
print(f" - {char.name} ({char.role}): {char.description}")
代码示例 3: 列表输出
python
from pydantic import BaseModel
from typing import List
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
class BookRecommendation(BaseModel):
title: str
author: str
reason: str
class BookRecommendations(BaseModel):
recommendations: List[BookRecommendation]
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Recommend books based on the user's interests.",
)
response: RunOutput = agent.run(
"Recommend 3 science fiction books",
output_schema=BookRecommendations
)
result = BookRecommendations.model_validate_json(response.content)
for book in result.recommendations:
print(f"📚 {book.title} by {book.author}")
print(f" Why: {book.reason}\n")
代码示例 4: 带验证的输出
python
from pydantic import BaseModel, Field, validator
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
class ProductReview(BaseModel):
product_name: str = Field(..., min_length=1)
rating: int = Field(..., ge=1, le=5)
review_text: str = Field(..., min_length=10)
would_recommend: bool
@validator('review_text')
def review_must_be_meaningful(cls, v):
if len(v.split()) < 5:
raise ValueError('Review must have at least 5 words')
return v
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Write a product review.",
)
response: RunOutput = agent.run(
"Write a review for a wireless headphone",
output_schema=ProductReview
)
review = ProductReview.model_validate_json(response.content)
print(f"Product: {review.product_name}")
print(f"Rating: {'⭐' * review.rating}")
print(f"Review: {review.review_text}")
print(f"Recommend: {'Yes' if review.would_recommend else 'No'}")
代码示例 5: 动态输出模式选择
python
from pydantic import BaseModel
from typing import Type, Union
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
class NewsArticle(BaseModel):
headline: str
summary: str
source: str
date: str
class BlogPost(BaseModel):
title: str
content: str
tags: list
reading_time: int
def get_output_format(format_type: str) -> Type[BaseModel]:
"""根据类型返回不同的输出模式"""
formats = {
"news": NewsArticle,
"blog": BlogPost,
}
return formats.get(format_type, BlogPost)
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Create content in the specified format.",
)
# 选择新闻格式
output_schema = get_output_format("news")
response: RunOutput = agent.run(
"Write about the latest AI breakthrough",
output_schema=output_schema
)
article = output_schema.model_validate_json(response.content)
print(f"Headline: {article.headline}")
11. 运行控制
知识点说明
Agent 运行可以暂停、继续或取消,用于实现人机交互流程和运行管理。
代码示例 1: 暂停和继续运行
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
# 开始运行
response: RunOutput = agent.run("Write a long story about space exploration")
# 暂停运行(在某些条件下)
# agent.pause_run()
# 继续运行
# continued_response = agent.continue_run()
print(f"Response: {response.content}")
代码示例 2: 取消运行
python
import threading
import time
from agno.agent import Agent
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Write a very long essay.",
)
# 在另一个线程中启动运行
run_thread = threading.Thread(
target=lambda: agent.run("Write a 5000 word essay on history")
)
run_thread.start()
# 5 秒后取消运行
time.sleep(5)
agent.cancel_run()
run_thread.join()
print("Run cancelled")
代码示例 3: 带超时的运行
python
import signal
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
class TimeoutError(Exception):
pass
def timeout_handler(signum, frame):
raise TimeoutError("Run timed out")
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions.",
)
# 设置 10 秒超时
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(10)
try:
response: RunOutput = agent.run("Write a detailed analysis")
print(f"Response: {response.content}")
except TimeoutError:
print("Run timed out after 10 seconds")
agent.cancel_run()
finally:
signal.alarm(0) # 取消闹钟
代码示例 4: 条件暂停(人机交互)
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="You are a coding assistant. Ask for clarification when needed.",
)
# 模拟人机交互流程
def run_with_human_in_the_loop():
# 第一轮:Agent 提出问题
response1: RunOutput = agent.run(
"I need to write a Python script. What should it do?"
)
print(f"Agent: {response1.content}")
# 人类输入
human_input = input("Your response: ")
# 第二轮:继续对话
response2: RunOutput = agent.run(human_input)
print(f"Agent: {response2.content}")
return response2
final_response = run_with_human_in_the_loop()
代码示例 5: 批量运行管理
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
from typing import List
import concurrent.futures
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions concisely.",
)
questions = [
"What is Python?",
"What is JavaScript?",
"What is Go?",
"What is Rust?",
"What is Java?",
]
def run_single_question(question: str) -> RunOutput:
"""运行单个问题"""
return agent.run(question)
# 使用线程池并行运行
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
futures = [executor.submit(run_single_question, q) for q in questions]
results: List[RunOutput] = [f.result() for f in futures]
# 打印结果
for question, result in zip(questions, results):
print(f"Q: {question}")
print(f"A: {result.content}\n")
12. 后台执行
知识点说明
使用 background=True 在后台运行 agent。即使客户端断开连接,agent 也会继续运行。结合 stream=True 实现可恢复的 SSE 流式传输。
代码示例 1: 基础后台执行
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Write a long report.",
)
# 后台运行
response: RunOutput = agent.run(
"Write a comprehensive report on climate change",
background=True
)
print(f"Run started with ID: {response.run_id}")
print(f"Status: {response.status}")
代码示例 2: 检查后台任务状态
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
import time
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Process large dataset.",
)
# 启动后台任务
response: RunOutput = agent.run(
"Analyze 1000 data points",
background=True
)
run_id = response.run_id
print(f"Started run: {run_id}")
# 轮询检查状态
for i in range(10):
time.sleep(2)
status = agent.get_run_status(run_id)
print(f"Status check {i+1}: {status}")
if status == "completed":
result = agent.get_run_result(run_id)
print(f"Result: {result.content}")
break
代码示例 3: 可恢复的后台流式执行
python
from agno.agent import Agent
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Generate content.",
)
# 启动可恢复的后台流式任务
stream = agent.run(
"Generate a long story",
background=True,
stream=True
)
# 处理流式输出
for chunk in stream:
if chunk.event == "run_content":
print(chunk.content, end="", flush=True)
# 如果连接断开,可以使用 run_id 恢复
# resumed_stream = agent.resume_run(run_id)
代码示例 4: 后台任务队列
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
from typing import List
import queue
import threading
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Process tasks.",
)
task_queue = queue.Queue()
results = []
def worker():
"""后台工作线程"""
while True:
task = task_queue.get()
if task is None:
break
response: RunOutput = agent.run(task, background=True)
results.append({
"task": task,
"run_id": response.run_id,
"status": "started"
})
task_queue.task_done()
# 启动工作线程
thread = threading.Thread(target=worker)
thread.start()
# 添加任务到队列
tasks = [
"Summarize document A",
"Summarize document B",
"Summarize document C",
]
for task in tasks:
task_queue.put(task)
task_queue.join()
task_queue.put(None)
thread.join()
print(f"Started {len(results)} background tasks")
for r in results:
print(f" - {r['task']}: {r['run_id']}")
代码示例 5: 带回调的后台执行
python
from agno.agent import Agent, RunOutput
from agno.models.deepseek import DeepSeek
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Process data.",
)
def on_complete(run_output: RunOutput):
"""完成回调"""
print(f"✅ Run {run_output.run_id} completed!")
print(f"Result: {run_output.content[:100]}...")
def on_error(error: Exception):
"""错误回调"""
print(f"❌ Error: {error}")
# 启动带回调的后台任务
response: RunOutput = agent.run(
"Process large dataset",
background=True,
on_complete=on_complete,
on_error=on_error
)
print(f"Started background run: {response.run_id}")
13. 完整可运行代码示例
以下是一个综合示例,演示了本章所有核心知识点:
python
"""
Agno Agent 运行完整示例
本示例演示:
1. 使用 run() 和 arun() 方法
2. 流式输出和事件处理
3. 用户和会话管理
4. 结构化输出
5. 后台执行
运行前请确保:
- 安装 agno: pip install agno
- 设置 DeepSeek API 密钥: export DEEPSEEK_API_KEY=your_key
"""
import os
import asyncio
from typing import Iterator, List
from pydantic import BaseModel
from agno.agent import Agent, RunOutput, RunOutputEvent, RunEvent
from agno.models.deepseek import DeepSeek
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.utils.pprint import pprint_run_response
# ============================================================
# 第一部分:基本运行
# ============================================================
def basic_run_example():
"""
基本运行示例
演示 run() 方法的基本用法
"""
print("=" * 60)
print("示例 1: 基本运行 (run())")
print("=" * 60)
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[DuckDuckGoTools()],
instructions="Search for information and provide concise answers.",
)
# 基本运行
response: RunOutput = agent.run("What is Python programming language?")
print(f"Content: {response.content}")
print(f"Run ID: {response.run_id}")
print(f"Session ID: {response.session_id}")
print("\n")
# ============================================================
# 第二部分:流式输出
# ============================================================
def streaming_example():
"""
流式输出示例
演示如何逐块处理响应
"""
print("=" * 60)
print("示例 2: 流式输出")
print("=" * 60)
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions concisely.",
)
# 流式输出
print("Streaming response: ", end="", flush=True)
stream: Iterator[RunOutputEvent] = agent.run(
"What are the benefits of Python?",
stream=True
)
for chunk in stream:
if chunk.event == RunEvent.run_content:
print(chunk.content, end="", flush=True)
print("\n\n")
# ============================================================
# 第三部分:事件处理
# ============================================================
def event_handling_example():
"""
事件处理示例
演示如何处理不同类型的运行事件
"""
print("=" * 60)
print("示例 3: 事件处理")
print("=" * 60)
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
tools=[DuckDuckGoTools()],
instructions="Search for information.",
)
stream: Iterator[RunOutputEvent] = agent.run(
"Latest AI news",
stream=True,
stream_events=True
)
event_count = {}
for chunk in stream:
event_type = str(chunk.event)
event_count[event_type] = event_count.get(event_type, 0) + 1
if chunk.event == RunEvent.run_started:
print("[🚀 Run started]")
elif chunk.event == RunEvent.run_content:
print(chunk.content, end="", flush=True)
elif chunk.event == RunEvent.tool_call_started:
print(f"\n[🔧 Tool: {chunk.tool.tool_name}]")
elif chunk.event == RunEvent.run_completed:
print("\n[✅ Run completed]")
print(f"\nEvent counts: {event_count}")
print("\n")
# ============================================================
# 第四部分:用户和会话管理
# ============================================================
def user_session_example():
"""
用户和会话管理示例
演示如何管理多用户和会话
"""
print("=" * 60)
print("示例 4: 用户和会话管理")
print("=" * 60)
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="You are a helpful assistant with memory.",
)
user_id = "alice@example.com"
session_id = "session_001"
# 第一轮对话
print("Turn 1: Setting context")
response1: RunOutput = agent.run(
"My name is Alice and I love Python",
user_id=user_id,
session_id=session_id
)
print(f"Response: {response1.content}\n")
# 第二轮对话(应该记住上下文)
print("Turn 2: Testing memory")
response2: RunOutput = agent.run(
"What is my name and what do I love?",
user_id=user_id,
session_id=session_id
)
print(f"Response: {response2.content}")
print("\n")
# ============================================================
# 第五部分:结构化输出
# ============================================================
def structured_output_example():
"""
结构化输出示例
演示如何使用 Pydantic 模型获取结构化数据
"""
print("=" * 60)
print("示例 5: 结构化输出")
print("=" * 60)
class ProgrammingLanguage(BaseModel):
name: str
year_created: int
creator: str
main_uses: List[str]
popularity_rank: int
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Provide accurate information about programming languages.",
)
response: RunOutput = agent.run(
"Tell me about Python",
output_schema=ProgrammingLanguage
)
# 解析结构化输出
lang = ProgrammingLanguage.model_validate_json(response.content)
print(f"Language: {lang.name}")
print(f"Created: {lang.year_created}")
print(f"Creator: {lang.creator}")
print(f"Main uses: {', '.join(lang.main_uses)}")
print(f"Popularity rank: #{lang.popularity_rank}")
print("\n")
# ============================================================
# 第六部分:异步运行
# ============================================================
async def async_run_example():
"""
异步运行示例
演示 arun() 和异步流式输出
"""
print("=" * 60)
print("示例 6: 异步运行")
print("=" * 60)
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions concisely.",
)
# 异步运行
response = await agent.arun("What is async programming?")
print(f"Response: {response.content}")
# 异步流式输出
print("\nAsync streaming: ", end="", flush=True)
stream = await agent.arun("Benefits of async programming", stream=True)
async for chunk in stream:
if chunk.event == RunEvent.run_content:
print(chunk.content, end="", flush=True)
print("\n\n")
# ============================================================
# 第七部分:批量运行
# ============================================================
def batch_run_example():
"""
批量运行示例
演示如何同时运行多个查询
"""
print("=" * 60)
print("示例 7: 批量运行")
print("=" * 60)
agent = Agent(
model=DeepSeek(id="deepseek-v4-flash"),
instructions="Answer questions in one sentence.",
)
questions = [
"What is AI?",
"What is machine learning?",
"What is deep learning?",
]
print("Running batch queries...")
for i, question in enumerate(questions, 1):
response: RunOutput = agent.run(question)
print(f"{i}. Q: {question}")
print(f" A: {response.content}\n")
# ============================================================
# 主函数:运行所有示例
# ============================================================
def main():
"""
主函数:按顺序运行所有示例
"""
print("\n" + "=" * 60)
print("Agno Agent 运行完整示例")
print("=" * 60 + "\n")
# 检查 API 密钥
if not os.getenv("DEEPSEEK_API_KEY"):
print("警告: 未设置 DEEPSEEK_API_KEY 环境变量")
print("请设置: export DEEPSEEK_API_KEY=your_key\n")
return
# 运行所有示例
try:
basic_run_example()
streaming_example()
event_handling_example()
user_session_example()
structured_output_example()
batch_run_example()
# 异步示例
asyncio.run(async_run_example())
except Exception as e:
print(f"Error: {e}")
import traceback
traceback.print_exc()
print("\n" + "=" * 60)
print("所有示例运行完成!")
print("=" * 60)
# ============================================================
# 入口点
# ============================================================
if __name__ == "__main__":
main()
运行说明
-
安装依赖:
bashpip install agno -
设置 API 密钥:
bashexport DEEPSEEK_API_KEY=your_deepseek_api_key -
运行示例:
bashpython running_agents_example.py
示例输出结构
运行后会依次展示:
- 基本 run() 方法的输出
- 流式输出的逐字显示效果
- 事件处理的详细日志
- 用户和会话的记忆功能
- 结构化输出的解析结果
- 异步运行的响应
- 批量运行的并行处理