OpenAI Agents SDK 完全指南:从“只会动嘴”到“真正干活”的AI

你有没有遇到过这样的情况------用AI写了一份营销方案,还要自己复制粘贴发邮件;AI跑完了数据分析,还得自己写代码取数;大模型给你列了操作步骤,最后每一步都需要你亲手去点。这就是传统大模型最大的痛点:它像一位聪明的顾问,什么都懂,但就是不会自己动手

OpenAI Agents SDK就是来解决这个"光说不练"的问题的------它让AI从只会回答问题的"解说员",变成了真正能干活、能调用工具、能处理复杂任务的"执行者"。截至2026年4月30日,这个Python框架在GitHub上已经接近22k颗星,且半个月前刚经历了一次从底层彻底重写。

这篇文章不讲抽象概念,不堆砌专业术语,我们从日常生活中最直观的例子出发,一步步带你搞懂Agent和Tool是怎么回事,然后直接上手写代码。


一、为什么你的AI只能"动嘴"?从两大局限说起

现代大模型本身就像一个天才:你问它"明天天气怎么样",它能给你写出几百字的天气分析,但它就是查不到明天的实时天气,因为它最后一次训练是在几个月前。你让它"把我桌面上的PDF整理成表格",它能告诉你具体操作步骤,但它自己不会去双击图标、不会去读文件窗口的内容、也不会帮你拖拽生成表格。

在2026年4月之前,开发者要让AI真正操作外部世界的任务时,通常需要自己搭建一套框架:用LangChain管理流程、用Docker做环境隔离、用Redis做状态缓存,写了一堆基建代码才能真正开始做业务逻辑。

简单来说就是:你有最聪明的"大脑",但它没有"手脚"。它只会思考,不会行动。

这就像你请了一位顶级顾问,他给你一份完美的策划案之后,你还要自己找团队,甚至自己动手执行。这时候你就想问了:"能不能让它替我执行?"

Agent就是那个能"执行"的答案,而Tool就是它的"五指"。


二、带你彻底搞懂Tool(工具):AI的"五指"

Tool到底是什么

我们用一个最日常的例子来理解。你晚上加班发现桌上出现了零食,可能是四个小伙伴中的一个塞过来的:办公桌对面的大伟、左边工位的莉莉、右边工位的哈娜,或者老板假借他人名义送来的。为了搞清是谁放的,你会列一个名单逐一排查。

Agent调用Tool的道理是一模一样的。Agent接到任务后,会判断它需要调用哪些"名单上的手段"来解决问题------它自己有一个工具列表,里面放着预定义好的Tool,它根据用户的问题,自行决定调用哪一个或哪几个。

在技术层面,Tool就是一个被装饰器标记的普通Python函数。在2026年4月的最新版本中,Agents SDK支持以Python函数、外来托管能力、甚至将另一个Agent本身作为Tool加入工具列表。

Tool帮你解决了什么问题

过去的大模型有三大局限:知识"超时"(学的资料截止在某一天)、无法实际操作(不能调用API、不能读写文件、不能访问内部系统)、以及容易"编造"答不出就拿假数据凑合------这就是俗称的AI"幻觉"。

Tool一次性突破了这三个局限。它让AI可以实时查询最新信息、执行真正的API操作、从企业数据库直接拉数据。当你把Agent + Tool组合使用时,AI就不再是"有建议但不干活"了------而是变成了一位能独立完成完整任务的"数字员工"。

Agent调用Tool的典型流程

假设你构建了一个天气助手Agent,并给它绑定了一个"获取实况气温"的Tool。用户发来一句询问:"厦门现在的温度是多少?"

Agent先收到用户的问题,读完立刻判断:"哦,这个问题需要我调用那个获取实时温度的Tool。"然后它将厦门作为参数传过去,Tool执行完之后拿到真实温度数据,返回给Agent。Agent再用自己的语言重组温度信息,用通顺的句子答复给用户。

这个过程对Agent来说几乎毫不费力,因为Tool已经帮它拿到了原本不可能拿到的实时数据。

三、从源码看懂Tool:手把手创建一个天气查询功能

聊完了原理,我们直接动手。以下这段Python代码定义了两个Tool来说明两个最常用的Tool粒度:一个是单独拉数据的Tool(查天气),一个是串联起来的Tool(多城市+空气质量)。

在开始之前,记得先安装Python包(在终端运行一行命令)并准备环境变量。

bash 复制代码
pip install openai-agents

在你的项目目录中创建一个.env文件,填入你的模型API配置。这里用国内的阿里通义千问Qwen作为例子:

bash 复制代码
OPENAI_API_KEY=你的通义千问API密钥
OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
OPENAI_MODEL_NAME=qwen-plus

现在来看一个完整的Tool定义和调用示例:

bash 复制代码
import asyncio
import json
import os
from openai import AsyncOpenAI
from agents import Agent, OpenAIChatCompletionsModel, Runner, function_tool
from dotenv import load_dotenv
 
# ----- 第一步:加载环境变量中的模型API密钥 -----
load_dotenv()
 
# ----- 第二步:创建一个异步模型客户端(必须AsyncOpenAI)-----
client = AsyncOpenAI(
    base_url=os.getenv("OPENAI_BASE_URL"),
    api_key=os.getenv("OPENAI_API_KEY")
)
 
# ----- 第三步:用装饰器定义第一个Tool(查当前天气)-----
@function_tool
def get_current_weather(city: str) -> str:
    """
    获取指定城市的实时天气信息。
    参数:
        city: 城市名称(如"武汉"、"上海")
    返回:
        JSON字符串,包含天气描述和当前温度。
    """
    # 这里本应调用真正的实时天气API,目前用模拟数据演示
    weather_data = {
        "city": city,
        "condition": "晴天 ☀️",
        "temperature_celsius": 24,
        "wind": "东南风3级"
    }
    return json.dumps(weather_data, ensure_ascii=False)
 
# ----- 第四步:定义第二个Tool(查询空气质量AQI)-----
@function_tool
def get_air_quality(city: str) -> str:
    """
    获取指定城市的空气质量指数(AQI)。
    参数:
        city: 城市名称
    返回:
        JSON字符串,包含AQI值和建议。
    """
    # 模拟空气质量数据
    air_data = {
        "city": city,
        "aqi": 48,
        "level": "优",
        "advice": "非常适合户外活动"
    }
    return json.dumps(air_data, ensure_ascii=False)
 
# ----- 第五步:创建Agent,并绑定上面两个Tool -----
async def main():
    agent = Agent(
        name="全能天气助手",
        instructions=(
            "你是一个专业的城市天气查询助手。当用户问某个城市的天气时,"
            "你必须调用 get_current_weather 来获取实时天气。"
            "当用户问空气质量时,必须调用 get_air_quality。"
            "如果用户同时问了天气和空气质量,你需要依次调用两个函数。"
            "最终用亲切友好的口吻整合结果回答用户。"
        ),
        model=OpenAIChatCompletionsModel(
            model=os.getenv("OPENAI_MODEL_NAME"),
            openai_client=client
        ),
        tools=[get_current_weather, get_air_quality],  # 把两个工具绑定给Agent
    )
 
    # ----- 第六步:运行Agent,可以看到它自动调用了两个Tool -----
    result = await Runner.run(
        agent,
        "重庆市今天的天气怎么样?空气质量如何?适合出门散步吗?"
    )
    print("\n=== Agent最终回复 ===")
    print(result.final_output)
 
if __name__ == "__main__":
    asyncio.run(main())

上述代码的关键点:

  • 每个函数用 @function_tool 装饰器标记后,Agent就能在决策过程中"看到"这些函数。
  • Tool的执行结果可以是字符串、JSON、甚至是完整的Pydantic数据结构体,Agent会自动接管。
  • instructions 字段写得字越多越好:告诉Agent"什么场景下调用哪个Tool",这比提示它"别猜答案直接取工具数据"效果要好得多。

四、Agent(智能体)的完整概念与三种模型配置

说完了Tool,现在来组装整个AI的"大脑"。主流的Agent开发SDK都会遇到一个实际问题:你用的模型不是OpenAI官方模型怎么办?万一你有多个不同大模型需要串在一起怎么配置?

OpenAI Agents SDK的一个重要设计,就是从设计之初就跟模型供应商解耦:它能兼容100多种不同的LLM(阿里通义、智谱GLM、Claude、甚至开源的LLaMA等)

针对不同使用场景,新版SDK提供了三种模型客户端配置方式:


方式一:全局一次性配置(适合只用一个模型的场景)

如果你手头只有一个大模型(例如阿里通义千问Qwen),并且所有Agent都用它,用全局配置最快。

bash 复制代码
import asyncio
import os
from openai import AsyncOpenAI
from agents import (
    Agent,
    Runner,
    set_default_openai_client,
    set_default_openai_api,
    set_tracing_disabled,
)
from dotenv import load_dotenv
 
load_dotenv()
 
# ---- 创建唯一的客户端 ----
client = AsyncOpenAI(
    base_url=os.getenv("OPENAI_BASE_URL"),
    api_key=os.getenv("OPENAI_API_KEY")
)
 
# ---- 设置全局长效配置 ----
set_default_openai_client(client)               # 所有Agent共用此client
set_default_openai_api("chat_completions")      # 必须指定这行,否则报错400
set_tracing_disabled(disabled=True)             # 可选,关闭追踪以防止401报错
 
async def main():
    agent = Agent(
        name="写作助理",
        instructions="你是一个专业的诗歌写手,所有回复都用古典七言绝句。",
        model="qwen-plus"  # 注意这里只写字符串,不用再导入模型对象
    )
    result = await Runner.run(agent, "写一首关于大雨的古风诗")
    print(result.final_output)
 
if __name__ == "__main__":
    asyncio.run(main())

这种方式的优点就是干净简单,适合一个团队内统一了模型选型、快速跑通MVP的场景。

方式二:运行时切换模型(适合多模型混合)

许多场景需要在运行时动态改变模型:例如白天用通义千问跑知识库问答,晚上用智谱GLM跑针对科研论文的分析。使用自定义Provider的方式,不需要重启进程就可以切换模型。

bash 复制代码
from __future__ import annotations
import asyncio
import os
from openai import AsyncOpenAI
from agents import (
    Agent,
    Model,
    ModelProvider,
    OpenAIChatCompletionsModel,
    RunConfig,
    Runner,
)
from dotenv import load_dotenv
 
load_dotenv()
 
client = AsyncOpenAI(
    base_url=os.getenv("OPENAI_BASE_URL"),
    api_key=os.getenv("OPENAI_API_KEY")
)
 
# ---- 自定义Provider:实现get_model接口 ----
class CustomModelProvider(ModelProvider):
    def get_model(self, model_name: str) -> Model:
        return OpenAIChatCompletionsModel(
            model=model_name,
            openai_client=client
        )
 
CUSTOM_PROVIDER = CustomModelProvider()
 
async def main():
    agent = Agent(
        name="多模型翻译员",
        instructions="你是专业的中英互译助手,回复要精炼准确。",
        model="qwen-plus"     # 目前用字符串先占位
    )
 
    result = await Runner.run(
        agent,
        input="请将'人工智能正在改变世界'翻译成英语。",
        run_config=RunConfig(model_provider=CUSTOM_PROVIDER),
    )
 
    print("翻译结果:", result.final_output)
 
if __name__ == "__main__":
    asyncio.run(main())

方式三:Agent绑定单一模型(最细粒度,适合多Agent分工)

如果你的系统里有一张复杂的分工表------接待Agent用通义千问,风控Agent用DeepSeek,科研Agent用GLM------那就用这种直接绑定的方法。

bash 复制代码
import asyncio
import os
from openai import AsyncOpenAI
from agents import Agent, OpenAIChatCompletionsModel, Runner
from dotenv import load_dotenv
 
load_dotenv()
 
client = AsyncOpenAI(
    base_url=os.getenv("OPENAI_BASE_URL"),
    api_key=os.getenv("OPENAI_API_KEY")
)
 
async def main():
    agent = Agent(
        name="安全敏感助手",
        instructions="你只处理有严格合规要求的政务类问题。",
        model=OpenAIChatCompletionsModel(          # 直接传模型对象,不是字符串
            model=os.getenv("OPENAI_MODEL_NAME"),
            openai_client=client
        ),
    )
 
    result = await Runner.run(agent, "请帮我解读最近的个人所得税政策变化。")
    print(result.final_output)
 
if __name__ == "__main__":
    asyncio.run(main())

五、Agent的三种运行模式(同步、异步、流式)

初学者最常困惑的是:我的大模型响应很慢怎么办?我的场景需要服务器实时逐字输出吗?Agents SDK提供了三种灵活的运行模式来解决不同场景下的诉求:

  • 同步调用:适合一次性跑通Shell脚本,或者半夜跑批量数据。
  • 异步调用:适合用FastAPI/Django做大模型的REST后端服务。
  • 流式调用:适合做网页对话时"打字机效果",即UI上一字一字往外蹦回答。

逻辑上只需要记住一点:如果你不需要UI实时效果,就用最简单的 async/await 异步模式。只有当你在做聊天室、SSE、实时语音对话场景时,才采用第三种流式。

流式调用最像我们平时跟ChatGPT打字的情形:

bash 复制代码
async def stream_example():
    # 启动流式运行
    streaming_result = Runner.run_streamed(agent, "写一篇关于森林的短日记")
 
    # 接收模型逐个字吐出的增量
    async for event in streaming_result.stream_events():
        if event.type == "raw_response_event":
            delta = event.data.delta
            if delta:
                print(delta, end="", flush=True)   # 实时打印,不换行
 
    print("\n--- 完整全文在此 ---")
    print(streaming_result.final_output)

六、实战争取------让Agent不仅回答问题,还能输出结构化JSON

你和后端工程师对接时,最难受的一个点往往是:大模型输出一段散装文本,后端要费很大力气做正则清洗、提取关键字段。Agents SDK直接内置了Pydantic输出格式,让大模型输出严格符合JSON Schema的结构化Object。

我们拿物流行业的实际场景来说明:假设你的Agent需要调用物流API查询某张运单的流转记录,之后把这批记录同步到数据库,Agent只负责组装符合 ShipmentTrace 格式的结果,剩下的入库由后端用强类型接收。

下面这段代码里,Agent输出的结果不是自然语言,而是一个可直接存数据库的Python对象:

bash 复制代码
import asyncio
import json
import os
from openai import AsyncOpenAI
from agents import Agent, OpenAIChatCompletionsModel, Runner, function_tool
from pydantic import BaseModel
from dotenv import load_dotenv
 
load_dotenv()
 
client = AsyncOpenAI(
    base_url=os.getenv("OPENAI_BASE_URL"),
    api_key=os.getenv("OPENAI_API_KEY")
)
 
# --- 定义输出的结构体规范 ---
class ShipmentTrace(BaseModel):
    order_id: str          # 运单号
    current_location: str  # 当前所在地
    status: str            # 状态
    estimated_days: int    # 预计剩余天数
    message: str           # 一句话概要
 
# --- 定义一个叫车联网查单的Tool ---
@function_tool
def search_shipment(order_id: str) -> str:
    """根据运单号从数据库中查询物流追踪信息。"""
    # 模拟真实物流API查询结果
    data = {
        "order_id": order_id,
        "location": "上海市浦东中转站",
        "status": "正在转运中",
        "remaining_days": 2
    }
    return json.dumps(data, ensure_ascii=False)
 
async def main():
    agent = Agent(
        name="物流情报员",
        instructions=(
            "当用户询问快递流向时,你必须调用search_shipment获取后端实时数据。"
            "然后输出符合ShipmentTrace结构的最终结果。"
        ),
        model=OpenAIChatCompletionsModel(
            model=os.getenv("OPENAI_MODEL_NAME"),
            openai_client=client
        ),
        tools=[search_shipment],
        output_type=ShipmentTrace,      # 关键:强制Agent输出这个结构
    )
 
    result = await Runner.run(agent, "帮我查一下快递单号SF1234567890的物流状态")
    # result.final_output 的类型是 ShipmentTrace,不是字符串
    print("=== 结构化结果 ===")
    print(result.final_output)
 
    # 转换为字典直接使用
    print("\n=== 转为字典入库 ===")
    dict_data = result.final_output.model_dump()
    print(dict_data)
 
if __name__ == "__main__":
    asyncio.run(main())

七、Agent的真正"新生代能力":沙盒执行体

文章开头提到,2026年4月中旬Agents SDK经历了一次从底层开始的重写。这次更新引入了两个核心能力:沙盒执行环境和长期Harness控制流。

什么是沙盒(Sandbox)?

简单说,沙盒就是一个完全隔离的、轻量级的执行场所。Agent在沙盒里可以安全地执行计算机命令、读/写文件、安装依赖包、甚至生成最终产物(如PDF报告或Excel文件)------但它绝对不能碰到你的本地核心系统文件,也不能外泄你的服务器API密钥。新版SDK原生已经接入七家主流沙盒提供商:Cloudflare、Vercel、Modal、E2B等等。

传统AI Agent容易出问题的原因是:你调用API给的模型是一个"黑盒",它可能会执行你意料之外的指令,比如在代码解释器里无意中运行rm -rf等危险操作。沙盒技术的意义在于,即便Agent犯了错,也只限制在沙盒那间独立的"隔离小屋"里,不会炸毁整栋楼或拖垮你的核心系统。

什么是Harness(模型控制流)?

如果你做一个"长周期Agent",比如让AI分析一整年的10万条客户物流记录,最终出一份PowerPoint版的年度报告------这个流程可能需要持续运行几个小时。中间一旦临时崩溃或网络抖动,所有进度就全没了。

Harness相当于给Agent配备了"暂停/恢复"功能,可以快照记录Agent当前状态(读到了哪一行日志、做了哪几步任务),等计算恢复后从最近的断点继续执行,不需要重启整个Agent。它同时还包括审批流、状态追踪、多步Handoff记录等各种企业级工具体系。过去这些能力必须靠开发者自己用一连串额外框架来拼凑,现在一个import就能搞定。

八、Agent运行追踪与可视化

当你的智能体系统膨胀到三五个Agent互相交互的时候,调试工作会变得异常复杂------你很难判断是哪个Agent把指令给错,还是Tool给错了参数。SDK内置的追踪(Tracing)会在这里派上用场。

简单来说,Agent一次完整的请求会被打成一个Trace (追踪ID),Trace内部会进一步拆分成多个Span(跨度),可以分别观察到每次LLM生成用时多久、每次Tool调用花了多少秒、是否有Handoff挂起异常等。

在常见的Web框架或FastAPI中,你只需要像这样把Agent调用包裹进一个Trace代码块:

bash 复制代码
from agents import trace, Runner
 
with trace("完整客服助手业务流程"):
    result1 = await Runner.run(sales_agent, "用户想要最新的电脑报价")
    result2 = await Runner.run(audit_agent, f"核查订单 {result1.final_output} 是否合规")

SDK会自动把两次Agent对话收拢在同一个trace_id下,后端开发者可以通过OpenAI官方Traces面板或第三方集成(W&B、LangSmith、MLflow、Pydantic Logfire)查看到完整链路。这在排查"到底哪个子Agent给我的数据是脏数据"时,效率提升是巨大的。

九、总结:从今天开始拥抱真正"能干活"的Agent

至此,我们已经从Tool、Agent、模型配置、运行方式、结构化输出,一路走到沙盒执行与生产级Harness。

我们把本文最重要的几个点浓缩成一张清单:

  1. Tool是Agent的手和脚:你只需要实现两个辅助函数并用 @function_tool 装饰,Agent就能调用它们完成外部真实任务。
  2. Agent是大脑与调度中心:它根据用户问题决定调哪些Tool,然后把Tool返回的数据转译成回复。
  3. 模型配置非常灵活:Adapter设计使得100多种非OpenAI的模型都能在SDK上运行,团队可以自由选择最合适的模型服务商。
  4. 三种运行模式灵活可变:同步版本跑脚本/批量任务;异步版本与Web后端集成;流式版本专为UI做实时对话效果。
  5. 结构化输出极度友好:用Pydantic定义业务对象,Agent直接返回格式正确的JSON,后端工程师拿到就能入库。
  6. 沙盒与Harness是2026年4月更新的核心:让Agent跑得又安全又持久,企业级应用的生产力得到了质的飞跃。
  7. 追踪调试功能让多Agent系统的调试不再是盲人摸象。

你现在可以立刻做的事情:

如果你从来没用过AI Agent框架,建议先拷贝全局配置方式一的代码跑通第一个Agent。五分钟之后,你会看到大模型终于能"动起来"调取外部数据了。

如果你已经是开发者,想要直接搬上生产环境、跑长时任务处理:直接上手引入沙盒环境+自定义Tool列表。

不管你有多少大模型调用的使用经验,Agents SDK提供了一种思维观念的转变:AI不再是被动的"问答机",而是一台真正能帮你解决复杂业务的操作系统。

相关推荐
ACME204420 分钟前
破产财产处置新规落地,管理人如何选聘拍卖机构?
人工智能
AI让世界更懂你23 分钟前
计算机专业研究生核心能力培养(6)——论文写作的表达与打磨
人工智能
风之清扬26 分钟前
Agent学习之四-初识Agent CLI
人工智能·科技·学习
零依赖极客33 分钟前
Day 9·1 KV 也量化——q8 KV 把缓存与 decode 带宽压到一半
c语言·开发语言·arm开发·人工智能·缓存·矩阵
陈童学哦33 分钟前
AI术语大全
人工智能
tuanxiang34 分钟前
用去AI味工具调整大模型生成的技术文档,我踩了检测阈值的坑
人工智能
天辛大师37 分钟前
天辛大师谈AI时代的沉思录,All in AI 持续做事与放大效应
大数据·人工智能·随机森林·重构·启发式算法
不要生病了39 分钟前
Brain-JEPA:用功能梯度定位与时空遮蔽预训练 fMRI 基础模型
人工智能·深度学习
艺杯羹44 分钟前
穿透深度慢思考黑盒:DeepSeek-R1 蒸馏模型量化压缩、vLLM 极限吞吐与私网落地实战
人工智能·大模型·部署
韦韦(Carina)1 小时前
技术博客结构化:让 AI 准确引用你的 7 条排版铁律
大数据·人工智能