OpenAI Agents SDK02
这篇文章介绍了两种AI代理交互模式:Handoffs(任务转交)和Streaming(流式输出)。在Handoffs模式下,主代理根据问题类型将任务转交给专业代理(如天气查询、新闻检索、数学计算),形成协作团队。Streaming模式则实现了边生成边显示的效果,通过设置stream=True参数,AI可以实时逐块返回响应内容,提升交互体验。文章提供了Python代码示例,展示了如何实现这两种模式,
=5/3=========================
Handoffs概念,把任务给另一个Agent
1.每个Agent做专门的事
2.遇到需要的领域,handoff给专业Agent
3.专业Agent处理完,结果返回
4.可以多次handoff,形成Agent团队
例子:
用户:帮我写个爬虫,然后发到我邮箱
Agent1(助手):收到!写爬虫我交给 —>Agent2(爬虫专家)
Agent2(爬虫专家):写好代码,handoff给 —》agent3(邮件专家)
Agent(邮件专家):发送邮件到xxx@email.com
不是真agent只是函数的模拟
import os #操作系统模块,读取环境变量
import json #JSON解析,解析AI返回的参数
from dotenv import load_dotenv #加载.env文件
from openai import OpenAI #OpenAI客户端(MiniMax兼容)
load_dotenv() #加载.env文件到环境变量
client = OpenAI(
base_url=“https://api.minimaxi.com/v1”,
api_key=os.getenv(“ANTHROPIC_API_KEY”)
)
===== 两个专业Agent函数 =====
def agent_weather(city: str) -> str:
“”“天气Agent - 只负责查天气”“”
data = {
“北京”: “晴天,25度”,
“上海”: “雨天,20度”,
“广州”: “多云,28度”,
“深圳”: “晴天,27度”
}
return data.get(city, f"{city}的天气未知")
def agent_news(topic: str) -> str:
“”“新闻Agent - 只负责查新闻”“”
return f"{topic}的最新新闻:AI技术持续发展中…"
def agent_calculator(expression: str) -> str:
“”“计算Agent - 只负责数学计算”“”
try:
result = eval(expression)
return str(result)
except:
return “计算错误”
===== 工具定义 =====
tools = [{
“type”: “function”,
“function”: {
“name”: “agent_weather”, #调用时用的名字
“description”: “天气Agent - 查询城市天气,专门负责天气相关问题”,
“parameters”: {
“type”: “object”,
“properties”: {
“city”: {“type”: “string”, “description”: “城市名称”}
},
“required”: [“city”]
}
}
}, {
“type”: “function”,
“function”: {
“name”: “agent_news”,
“description”: “新闻Agent - 查询新闻资讯,专门负责新闻相关问题”,
“parameters”: {
“type”: “object”,
“properties”: {
“topic”: {“type”: “string”, “description”: “新闻主题”}
},
“required”: [“topic”]
}
}
}, {
“type”: “function”,
“function”: {
“name”: “agent_calculator”,
“description”: “计算Agent - 计算数学表达式,专门负责计算问题”,
“parameters”: {
“type”: “object”,
“properties”: {
“expression”: {“type”: “string”, “description”: “数学表达式,如2+3*5”}
},
“required”: [“expression”]
}
}
}]
TOOLS = {
“agent_weather”: agent_weather,
“agent_news”: agent_news,
“agent_calculator”: agent_calculator
}
===== 系统提示 =====
system_msg = “”"你是一个智能助手,有多个专业Agent可以帮助你:
- agent_weather: 专门查询天气
- agent_news: 专门查询新闻
- agent_calculator: 专门计算数学
当用户问题时,判断需要哪个Agent处理,直接调用对应的Agent。“”"
===== 对话循环 =====
messages = [{“role”: “system”, “content”: system_msg}]
print(“=== Handoffs实验开始 ===”)
print(“你有3个专业Agent: 天气、新闻、计算”)
print(“试试问: ‘北京天气怎么样?’ 或 ‘AI最新新闻’ 或 ‘2+3*5等于多少?’\n”)
while True:
user_input = input("你: ")
if user_input.lower() in [“exit”, “quit”, “退出”]:
print(“再见!”)
break
messages.append({"role": "user", "content": user_input})
response = client.chat.completions.create(
model="MiniMax-M2.7",
messages=messages,
tools=tools
)
assistant_msg = response.choices[0].message
messages.append({"role": "assistant", "content": assistant_msg.content, "tool_calls": assistant_msg.tool_calls})
if not assistant_msg.tool_calls:
print(f"AI: {assistant_msg.content}\n")
continue
# 执行工具(handoff给专业Agent)
for tool_call in assistant_msg.tool_calls:
func_name = tool_call.function.name
args = json.loads(tool_call.function.arguments)
print(f"→ Handoff给: {func_name}")
if func_name in TOOLS:
result = TOOLS[func_name](**args)
print(f"← Agent返回: {result}")
messages.append({"role": "tool", "tool_call_id": tool_call.id, "content": str(result)})
else:
print(f"← 未知Agent: {func_name}")
# AI根据Agent结果生成最终回答
response2 = client.chat.completions.create(
model="MiniMax-M2.7",
messages=messages,
tools=tools
)
final_msg = response2.choices[0].message
print(f"AI: {final_msg.content}\n")
messages.append({"role": "assistant", "content": final_msg.content})
=Streaming=========================
什么是Streaming?边生成边显示,流水输出
import os
import json
from dotenv import load_dotenv
from openai import OpenAI
import urllib.request
import urllib.error
load_dotenv()
client = OpenAI(
base_url=“https://api.minimaxi.com/v1”,
api_key=os.getenv(“ANTHROPIC_API_KEY”)
)
print(“=== Streaming实验 ===”)
print(“AI会边生成边显示,不用等全部完成\n”)
user_input = input("你: ")
print(“\nAI: “, end=””, flush=True) #end=""不换行,保持在一行 flush=True立即显示,不缓冲
===== Streaming实现 =====
response = client.chat.completions.create(
model=“MiniMax-M2.7”,
messages=[{“role”: “user”, “content”: user_input}],
stream=True # 开启Streaming! 告诉API要流式响应,边生成边返回,返回一个生成器,不是普通列表
)
逐块读取流式响应
for chunk in response: #api返回的每一小快数据
if chunk.choices and chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
print(content, end=“”, flush=True)
print(“\n”)
=Memory概念=================
什么是Memonry?
让AI记住之前的对话历史
就像人的记忆一样
实现方式=
1.文件存储:每次对话保存到文件 例子:JSON文件
2.数据库:存到SQLite/MySQL 对话记录表
3.向量数据库 用Embedding存储 Milvus/Pinecone
4.SDK内置 OpenAI Agent SDK 自带 SesionMemory
Memory的核心操作
我自己的想法:全保存,结合对话智能索取,加载
1.保存(Save)
每轮对话后保存
messages.append({“role”: “user”, “content”: “你好”})
save_to_file(messages) # 保存到文件/数据库
2.加载(Load)
下次对话开始时加载
messages = load_from_file() # 从文件/数据库读取
3.压缩(Compress)-进阶
对话太长时压缩
if len(messages) > 100:
messages = compress(messages) # 精简历史
import os #文件操作(删除,重建文件)
import json #
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(
base_url=“https://api.minimaxi.com/v1”,
api_key=os.getenv(“ANTHROPIC_API_KEY”)
)
HISTORY_FILE = “conversation_memory.json” #文件存储位置
===== Memory核心函数 =====
def load_memory():
“”“加载记忆(自动处理编码)”“”
if os.path.exists(HISTORY_FILE): #判断文件是否存在
try:
with open(HISTORY_FILE, “r”, encoding=“utf-8”) as f:
return json.load(f)
except UnicodeDecodeError:
# 旧文件是GBK编码,删除重建
os.remove(HISTORY_FILE)
return [{“role”: “system”, “content”: “你是一个有帮助的助手,用简短的语言回答。”}] #默认返回系统消息
def save_memory(messages):
“”“保存记忆”“”
with open(HISTORY_FILE, “w”, encoding=“utf-8”) as f: #必须用utf-8编码,否则emoji会崩溃
json.dump(messages, f, ensure_ascii=False) #ensure_ascii=False保持emoji等Unicode字符
def compress_memory(messages, max_len=20):
“”“压缩记忆(只保留最近N条)”“”
if len(messages) > max_len:
# 保留系统消息 + 最近N条 永远保留第一条,保存近20条
return [messages[0]] + messages[-(max_len):]
return messages
===== 加载记忆 =====
messages = load_memory()
print(“=== Memory实验 ===”)
print(f"已加载 {len(messages)} 条历史记录\n")
显示历史(除了system)
for msg in messages:
if msg[“role”] != “system”:
print(f"{msg[‘role’]}: {msg[‘content’][:30]}…")
print(“\n” + “=”*40 + “\n”)
===== 对话循环 =====
while True:
user_input = input(“你: “)
if user_input.lower() in [“exit”, “quit”, “退出”]:
print(“保存记忆,再见!”)
save_memory(messages)
break
if user_input.lower() == “clear”:
“”“清空记忆”””
os.remove(HISTORY_FILE)
messages = [{“role”: “system”, “content”: “你是一个有帮助的助手。”}]
print(“记忆已清空!\n”)
continue
messages.append({"role": "user", "content": user_input})
response = client.chat.completions.create(
model="MiniMax-M2.7",
messages=messages
)
assistant_msg = response.choices[0].message.content
print(f"AI: {assistant_msg}\n")
messages.append({"role": "assistant", "content": assistant_msg})
# 压缩记忆(防止太长)
messages = compress_memory(messages, max_len=20)
# 保存记忆
save_memory(messages)
Guardrails(安全护栏)====================
用户恶意输入 --> Guardrails拦截 ----> 返回安全响应
1.防SQL注入
2.防止敏感信息泄露
3.过滤恶意指令
更多推荐



所有评论(0)