第 1 章:第一个 Agent -- 5 分钟跑通
本章目标:用 uv 创建项目环境,安装 SDK,创建一个最简单的 Agent,用三种方式把它跑起来,看懂返回结果。
1. 环境准备
安装 uv
uv 是新一代 Python 包管理器,速度极快。如果还没装:
# macOS / Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
创建项目
# 创建项目目录并初始化
uv init agent-tutorial
cd agent-tutorial
# 指定 Python 版本(SDK 要求 3.10+)
uv python pin 3.10
# 添加 openai-agents 依赖
uv add openai-agents
执行完后,uv 会自动创建虚拟环境(.venv)、生成 pyproject.toml 和 uv.lock。不需要手动 python -m venv 了。
配置模型
本教程使用兼容 OpenAI 格式的大模型服务(如 Ollama、vLLM、DeepSeek API、硅基流动等),需要设置两个环境变量:
# Linux / macOS
export MODEL_BASE_URL="http://localhost:8317/v1" # 你的模型服务地址
export MODEL_API_KEY="sk-12345678" # API Key
export MODEL_NAME="gpt-5.2" # 模型名称
# Windows PowerShell
$env:MODEL_BASE_URL="http://localhost:8317/v1"
$env:MODEL_API_KEY="sk-12345678"
$env:MODEL_NAME="gpt-5.2"
如果你用的是在线 API(如 DeepSeek、硅基流动),把
MODEL_BASE_URL换成对应的 API 地址,MODEL_API_KEY填真实 Key 即可。
SDK 默认走 OpenAI 的 Responses API,但大多数第三方模型只支持 Chat Completions API。所以我们在代码里会用 OpenAIChatCompletionsModel 来适配。每章代码开头都会有这段配置:
import os
from openai import AsyncOpenAI
from agents import OpenAIChatCompletionsModel, set_tracing_disabled
# 关闭追踪(如果没有 OpenAI 平台的 API Key,追踪会报错)
set_tracing_disabled(True)
# 创建兼容 OpenAI 格式的客户端
client = AsyncOpenAI(
base_url=os.getenv("MODEL_BASE_URL", "http://localhost:8317/v1"),
api_key=os.getenv("MODEL_API_KEY", "sk-12345678"),
)
# 创建模型实例
model = OpenAIChatCompletionsModel(
model=os.getenv("MODEL_NAME", "gpt-5.2"),
openai_client=client,
)
# 后续创建 Agent 时传入 model 参数
# agent = Agent(name="xxx", instructions="xxx", model=model)
运行代码
后面所有代码都通过 uv run 执行,它会自动使用项目的虚拟环境:
uv run python hello_agent.py
2. 核心概念:Agent 到底是什么?
一句话:Agent 就是一个有性格、有技能的 AI 员工。
你招一个员工,得告诉他:
- 你叫什么(name)—— 方便管理,尤其多个 Agent 协作时区分谁是谁
- 你的工作守则(instructions)—— 系统提示词,决定了这个 Agent 的行为风格
- 你会用什么工具(tools)—— 函数调用,让 AI 能做事而不只是说话
- 你能把活儿转给谁(handoffs)—— 多 Agent 协作,后面章节详细讲
SDK 里的 Agent 类就是对这些概念的封装。创建一个 Agent,本质上就是在描述一个"AI 员工"的 profile。
3. 第一个代码:最简 Agent
import asyncio
import os
from openai import AsyncOpenAI
from agents import Agent, Runner, OpenAIChatCompletionsModel, set_tracing_disabled
# --- 模型配置(每章都会有这段,后面不再重复解释)---
set_tracing_disabled(True)
client = AsyncOpenAI(
base_url=os.getenv("MODEL_BASE_URL", "http://localhost:8317/v1"),
api_key=os.getenv("MODEL_API_KEY", "sk-12345678"),
)
model = OpenAIChatCompletionsModel(
model=os.getenv("MODEL_NAME", "gpt-5.2"),
openai_client=client,
)
async def main():
# 创建一个 Agent:名字、指令、模型
agent = Agent(
name="俳句诗人",
instructions="你只用俳句(三行诗,5-7-5音节)的形式回答问题。",
model=model,
)
# 运行 Agent,传入用户消息
result = await Runner.run(agent, "给我讲讲递归")
print(result.final_output)
if __name__ == "__main__":
asyncio.run(main())
运行一下:
uv run python hello_agent.py
你会看到类似这样的输出:
自己呼自己,
层层拆解到尽头,
归来已成空。
就这么简单。两个核心对象:Agent(描述员工)和 Runner(让员工干活)。
4. 三种运行方式
SDK 提供了三种方式来运行 Agent,适用于不同场景:
4.1 Runner.run() -- 异步运行
import asyncio
from agents import Agent, Runner
# ... 省略模型配置(参考上面的 client/model 初始化代码)...
async def main():
agent = Agent(name="助手", instructions="用简洁的中文回答问题。", model=model)
# 异步运行,需要 await
result = await Runner.run(agent, "Python 的 GIL 是什么?")
print(result.final_output)
asyncio.run(main())
适用场景: 你的代码本身就是 async 的(比如 FastAPI、异步爬虫)。这是最常用的方式。
4.2 Runner.run_sync() -- 同步运行
from agents import Agent, Runner
# ... 省略模型配置 ...
agent = Agent(name="助手", instructions="用简洁的中文回答问题。", model=model)
# 同步运行,不需要 async/await
result = Runner.run_sync(agent, "Python 的 GIL 是什么?")
print(result.final_output)
适用场景: 脚本、命令行工具、不想写 async 的场合。内部其实就是帮你调了 asyncio.run()。
注意:如果当前已经有事件循环在跑(比如在 Jupyter Notebook 或 FastAPI 的异步上下文里),
run_sync()会报错。这时候老老实实用Runner.run()。
4.3 Runner.run_streamed() -- 流式运行
import asyncio
from agents import Agent, Runner
# ... 省略模型配置 ...
async def main():
agent = Agent(name="助手", instructions="用简洁的中文回答问题。", model=model)
# 流式运行,逐步获取事件
result = Runner.run_streamed(agent, "Python 的 GIL 是什么?")
async for event in result.stream_events():
# 每个 event 都是一个语义事件,带有 type 字段
print(event, flush=True)
# 流结束后,result 上也能拿到最终输出
print("\n最终输出:", result.final_output)
asyncio.run(main())
适用场景: 需要"打字机效果"的实时输出,比如聊天界面。后面章节会详细展开。
三种方式对比
| 方式 | 异步 | 返回类型 | 适合场景 |
|---|---|---|---|
Runner.run() |
是 | RunResult |
async 代码,最通用 |
Runner.run_sync() |
否 | RunResult |
脚本、CLI |
Runner.run_streamed() |
是 | RunResultStreaming |
实时输出、聊天 UI |
5. RunResult 结果解读
Runner.run() 和 Runner.run_sync() 返回的都是 RunResult 对象。重点关注这几个属性:
import asyncio
from agents import Agent, Runner
# ... 省略模型配置 ...
async def main():
agent = Agent(name="助手", instructions="用简洁的中文回答问题。", model=model)
result = await Runner.run(agent, "什么是装饰器?")
# 最终输出文本 —— 最常用的,就是 Agent 的回答
print("回答:", result.final_output)
# 最后一个处理请求的 Agent(多 Agent 协作时有用)
print("最后处理的 Agent:", result.last_agent.name)
# 运行过程中产生的所有新项目(消息、工具调用等)
print("新产生的项目数:", len(result.new_items))
for item in result.new_items:
print(f" - {type(item).__name__}")
# 原始模型响应列表
print("模型调用次数:", len(result.raw_responses))
asyncio.run(main())
| 属性 | 类型 | 说明 |
|---|---|---|
final_output |
Any |
Agent 的最终输出。默认是 str,设了 output_type 就是对应的结构化对象 |
last_agent |
Agent |
最后实际执行的 Agent。有 handoff 时可能跟起始 Agent 不同 |
new_items |
list[RunItem] |
运行过程中新产生的所有项目:消息、工具调用、工具结果等 |
raw_responses |
list[ModelResponse] |
原始的模型响应,用于调试或审计 |
input |
str \| list |
传入的原始输入 |
input_guardrail_results |
list |
输入护栏的检查结果 |
output_guardrail_results |
list |
输出护栏的检查结果 |
6. Agent 核心参数速查
from agents import Agent
agent = Agent(
# === 必填 ===
name="客服助手", # Agent 名称,用于标识和日志
# === 常用 ===
instructions="你是一个友善的客服...", # 系统提示词,定义 Agent 的行为
model=model, # 使用的模型(传入 OpenAIChatCompletionsModel 实例)
tools=[], # 工具列表(函数调用),下一章详解
handoffs=[], # 可以转交的其他 Agent
output_type=None, # 输出类型,None 表示纯文本 str
# === 进阶 ===
model_settings=None, # 模型参数调优(temperature 等)
input_guardrails=[], # 输入护栏,检查用户输入
output_guardrails=[], # 输出护栏,检查 Agent 输出
hooks=None, # 生命周期钩子,用于监控和干预
tool_use_behavior="run_llm_again", # 工具调用后的行为策略
)
几个要点:
name是唯一真正"必填"的参数(虽然没有instructions的 Agent 也能跑,但基本没意义)model传入我们创建的OpenAIChatCompletionsModel实例,也可以传模型名字符串(此时走 OpenAI 官方 API)instructions支持字符串,也支持函数(动态生成提示词),后面章节会讲output_type设成 Pydantic 模型或 dataclass,就能拿到结构化输出而不是纯文本
7. 完整可运行代码
把所有知识点串起来,下面是两个完整版本,直接复制就能跑。
异步版
"""
hello_agent_async.py
异步版 Hello Agent -- 展示 Runner.run() 的用法
"""
import asyncio
import os
from openai import AsyncOpenAI
from agents import Agent, Runner, OpenAIChatCompletionsModel, set_tracing_disabled
# --- 模型配置 ---
set_tracing_disabled(True)
client = AsyncOpenAI(
base_url=os.getenv("MODEL_BASE_URL", "http://localhost:8317/v1"),
api_key=os.getenv("MODEL_API_KEY", "sk-12345678"),
)
model = OpenAIChatCompletionsModel(
model=os.getenv("MODEL_NAME", "gpt-5.2"),
openai_client=client,
)
async def main():
# 创建 Agent
agent = Agent(
name="旅行顾问",
instructions="你是一个专业的旅行顾问,用简洁友好的中文回答旅行相关问题。",
model=model,
)
# 异步运行
result = await Runner.run(agent, "推荐三个适合冬天去的国内城市,每个一句话说明理由。")
# 输出结果
print("=== Agent 回答 ===")
print(result.final_output)
print("\n=== 运行信息 ===")
print(f"最后处理的 Agent: {result.last_agent.name}")
print(f"模型调用次数: {len(result.raw_responses)}")
print(f"新产生的项目数: {len(result.new_items)}")
if __name__ == "__main__":
asyncio.run(main())
同步版
"""
hello_agent_sync.py
同步版 Hello Agent -- 展示 Runner.run_sync() 的用法
"""
import os
from openai import AsyncOpenAI
from agents import Agent, Runner, OpenAIChatCompletionsModel, set_tracing_disabled
# --- 模型配置 ---
set_tracing_disabled(True)
client = AsyncOpenAI(
base_url=os.getenv("MODEL_BASE_URL", "http://localhost:8317/v1"),
api_key=os.getenv("MODEL_API_KEY", "sk-12345678"),
)
model = OpenAIChatCompletionsModel(
model=os.getenv("MODEL_NAME", "gpt-5.2"),
openai_client=client,
)
def main():
# 创建 Agent
agent = Agent(
name="旅行顾问",
instructions="你是一个专业的旅行顾问,用简洁友好的中文回答旅行相关问题。",
model=model,
)
# 同步运行,不需要 async/await
result = Runner.run_sync(agent, "推荐三个适合冬天去的国内城市,每个一句话说明理由。")
# 输出结果
print("=== Agent 回答 ===")
print(result.final_output)
print("\n=== 运行信息 ===")
print(f"最后处理的 Agent: {result.last_agent.name}")
print(f"模型调用次数: {len(result.raw_responses)}")
print(f"新产生的项目数: {len(result.new_items)}")
if __name__ == "__main__":
main()
8. 小结
这一章你学到了:
uv init+uv add openai-agents创建项目并安装 SDK,配好模型服务的环境变量Agent(name, instructions)就能创建一个最简单的 Agent- 三种运行方式:
run()(异步)、run_sync()(同步)、run_streamed()(流式) RunResult上最常用的是final_output,其次是last_agent和new_items- Agent 的核心参数:
name、instructions、model、tools、handoffs、output_type
下一章我们给 Agent 装上工具(Tools),让它不只会说话,还能干活。