OpenAI Agents SDK 智能体定义

2026-11-06 16:09 更新

智能体是基于SDK的工作流的核心单元。它封装模型、指令,以及可选的运行时行为,例如工具、护栏、MCP服务器、交接和结构化输出。

哪些设置属于智能体

与某个专项智能体职责固有相关的决定,放在智能体配置中:

属性 用途 延伸阅读
name 在追踪、工具及交接界面显示的易读身份 本页
instructions 工作、约束和表达风格 本页
prompt 基于Responses运行时使用的已保存提示词配置 模型与提供商
model与模型设置 选择模型、调整行为 模型与提供商
tools 智能体可直接调用的能力 使用工具
TypeScript的handoffDescription、Python的handoff_description 提示其他智能体何时应把工作交给它 编排与交接
handoffs 把工作交给其他智能体 编排与交接
TypeScript的outputType、Python的output_type 返回结构化输出,代替纯文本 本页
护栏与批准 验证、阻断及审查流程 护栏与人工审查
MCP服务器及托管MCP工具 接入由MCP提供的能力 集成与可观测性

从一个职责明确的智能体开始

先定义能负责明确任务的最小智能体。需要不同职责、指令、工具或批准策略时,再添加更多智能体。

来源示例 1(javascript):

// [中文] 示例1:从一个职责明确的智能体开始。
// [中文] 定义天气工具和天气助手,参数city是城市;示例固定返回“该城市天气晴朗”,没有请求真实天气服务。
// [中文] 智能体指令是“你是乐于助人的天气助手”;本段只构造配置,没有调用run。
import { Agent, tool } from "@openai/agents";
import { z } from "zod";

const getWeather = tool({
  name: "get_weather",
  description: "Return the weather for a given city.",
  parameters: z.object({ city: z.string() }),
  async execute({ city }) {
    return `The weather in ${city} is sunny.`;
  },
});

const agent = new Agent({
  name: "Weather bot",
  instructions: "You are a helpful weather bot.",
  model: "gpt-6-astra",
  tools: [getWeather],
});

来源示例 2(python):

## [中文] 示例2:从一个职责明确的智能体开始。
## [中文] 定义天气工具和天气助手,参数city是城市;示例固定返回“该城市天气晴朗”,没有请求真实天气服务。
## [中文] 智能体指令是“你是乐于助人的天气助手”;本段只构造配置,没有调用run。
from agents import Agent, function_tool


@function_tool
def get_weather(city: str) -> str:
    """Return the weather for a given city."""
    return f"The weather in {city} is sunny."


agent = Agent(
    name="Weather bot",
    instructions="You are a helpful weather bot.",
    model="gpt-6-astra",
    tools=[get_weather],
)

设计指令、交接和输出

以下三类配置尤其需要仔细设计:

  • 先使用静态instructions。指导内容依赖当前用户、租户或运行时上下文时,改用动态指令回调,不要在调用位置不断拼接字符串。
  • TypeScript的handoffDescription、Python的handoff_description应简短具体,让路由智能体知道何时选择这个专项智能体。
  • 下游代码需要有类型的数据而非自由文本时,使用TypeScript的outputType或Python的output_type。

以下示例返回结构化输出:

来源示例 3(javascript):

// [中文] 示例3:设计指令、交接和输出。
// [中文] 用name、date、participants定义日程结构,指令要求从文本提取日程。
// [中文] 输入意为“周五与Priya、Sam吃晚饭”;运行后打印结构化最终输出,不把自由文本当作已验证字段。
import { Agent, run } from "@openai/agents";
import { z } from "zod";

const calendarEvent = z.object({
  name: z.string(),
  date: z.string(),
  participants: z.array(z.string()),
});

const agent = new Agent({
  name: "Calendar extractor",
  instructions: "Extract calendar events from text.",
  outputType: calendarEvent,
});

const result = await run(agent, "Dinner with Priya and Sam on Friday.");

console.log(result.finalOutput);

来源示例 4(python):

## [中文] 示例4:设计指令、交接和输出。
## [中文] 用name、date、participants定义日程结构,指令要求从文本提取日程。
## [中文] 输入意为“周五与Priya、Sam吃晚饭”;运行后打印结构化最终输出,不把自由文本当作已验证字段。
import asyncio

from pydantic import BaseModel

from agents import Agent, Runner


class CalendarEvent(BaseModel):
    name: str
    date: str
    participants: list[str]


agent = Agent(
    name="Calendar extractor",
    instructions="Extract calendar events from text.",
    output_type=CalendarEvent,
)


async def main() -> None:
    result = await Runner.run(
        agent,
        "Dinner with Priya and Sam on Friday.",
    )
    print(result.final_output)


if __name__ == "__main__":
    asyncio.run(main())

希望引用Responses API中保存的提示词配置,而非把整段系统提示词嵌入代码时,使用prompt。

分开本地上下文与模型上下文

SDK允许把应用状态和依赖传入运行,而不发送给模型,例如已认证用户信息、数据库客户端、日志组件和辅助函数。下面把本地上下文传给工具:

来源示例 5(javascript):

// [中文] 示例5:分开本地上下文与模型上下文。
// [中文] 工具从本地运行上下文读取用户名;示例把年龄固定为47,并非查询数据库。
// [中文] 输入询问用户年龄;John与uid=123放在context中,context本身不自动发给模型,但工具返回的年龄文字会供模型使用。
import { Agent, run, tool } from "@openai/agents";
import { z } from "zod";

const fetchUserAge = tool({
  name: "fetch_user_age",
  description: "Return the age of the current user.",
  parameters: z.object({}),
  // TypeScript users can type this as RunContext<{ name: string; uid: number }>.
  async execute(_args, runContext) {
    return `User ${runContext?.context.name} is 47 years old`;
  },
});

const agent = new Agent({
  name: "Assistant",
  tools: [fetchUserAge],
});

const result = await run(agent, "What is the age of the user?", {
  context: { name: "John", uid: 123 },
});

console.log(result.finalOutput);

来源示例 6(python):

## [中文] 示例6:分开本地上下文与模型上下文。
## [中文] 工具从本地运行上下文读取用户名;示例把年龄固定为47,并非查询数据库。
## [中文] 输入询问用户年龄;John与uid=123放在context中,context本身不自动发给模型,但工具返回的年龄文字会供模型使用。
import asyncio
from dataclasses import dataclass

from agents import Agent, RunContextWrapper, Runner, function_tool


@dataclass
class UserInfo:
    name: str
    uid: int


@function_tool
async def fetch_user_age(wrapper: RunContextWrapper[UserInfo]) -> str:
    """Fetch the age of the current user."""
    return f"The user {wrapper.context.name} is 47 years old."


agent = Agent[UserInfo](
    name="Assistant",
    tools=[fetch_user_age],
)


async def main() -> None:
    result = await Runner.run(
        agent,
        "What is the age of the user?",
        context=UserInfo(name="John", uid=123),
    )
    print(result.final_output)


if __name__ == "__main__":
    asyncio.run(main())

这里的关键边界是:对话历史是模型看到的内容,运行上下文是应用代码看到的内容。

模型需要某项事实时,通过指令、输入、检索或工具提供;只有运行时需要的数据,留在本地上下文。

何时拆成多个智能体

某个专项智能体不应负责整份回复,或不同能力存在明显差异时,可以拆分。常见原因包括:

  • 需要不同工具或MCP能力。
  • 需要不同批准策略或护栏。
  • 某个工作流分支需要不同模型或输出风格。
  • 希望追踪中有明确路由记录,而非只使用一段庞大提示词。

后续步骤

定义好单个专项智能体后,按下一个设计问题选择指南:

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号