logo 范 · 拾光录
网址收集 关于作者 Github Gitee
杂文随笔5
Hexo博客:基础使用Hexo博客:Next主题Hexo博客:Next进阶使用Hexo博客:Next高级配置基于Node的WIKI管理
前端知识16
HTML常用知识CSS常用知识CSS美化checkbox复选框JavaScript常用知识JavaScript格式化时间戳JavaScript窗口宽高处理JavaScript黑夜主题切换实现方案JavaScript数字转大写简易图片查看器TypeScript基础知识Threejs基础三要素Threejs网格辅助和轨道控制器Threejs物体绘制Electron基础使用Nodejs基础知识animate.css页面动画
Vue框架19
Vite的使用及扩展Vue3父子组件Vue3使用Marked解析MarkdownMermaid图表生成库初始化页面加载动画Axios表单提交二维码解决方案NProgress加载进度条Vue3动态菜单实现Vue3使用ECharts图表Vue3处理Excel导入导出keep-alive页面缓存及setup问题Element:文件上传Element:结合Pinia实现动态菜单Element:图片上传组件Element:自定义统一弹窗组件Element:表格自定义指令控制按钮显示(鉴权)可视化大屏使用缩放适配分辨率
UniApp15
UniApp的基础使用封装网络请求工具及文件上传uni-app的开发记录微信小程序分享原生文件上传Pinia取消滚动条(兼容小程序)tabbar消息数量显示scroll-view上滑到底部加载数据状态栏高度动态设配数据共享与传递uview-plus导航栏实现背景融合Wot UIWot UI实现顶部背景图融合uni-app x
Java基础知识10
基础知识面向对象Lambda表达式常用API常用知识积累try-with-resource注解反射多线程经纬度距离计算
SpringBoot31
application配置Maven创建聚合项目全局异常处理锁机制项目启动初始化数据方式邮件功能集成原生定时任务异步集成阿里云OSS阿里OSS预签名上传基于hutool读excelJSR303WebSocketWebSocket版AI接口流式调用Smart-Doc接口文档生成器application配置信息加密雪花算法工具AOP实现请求参数脱敏思路JWT生成Token及工具类SpringBoot默认JSON与对象转换若依框架:安装使用若依框架:优化和调整文件上传若依框架:管理后台页面优化若依框架:后端接口代码优化SpringAISpringBoot实现AI接口流式调用服务启动时创建MySQL连接自建项目工程树形结构处理工具微信支付代码微信手机号登录
SpringMVC14
跨域处理拦截器RESTful风格伪前后端分离Jackson转换器调整Thymeleaf基于拦截器做权限校验AOP打印接口请求响应日志AOP打印接口请求响应耗时文件上传和回显POST请求加解密实现(AES)POST请求加解密实现(RSA+AES)参数动态校验实现方案真实IP和归属地
MyBatis8
MyBatis基本使用与配置Mapper使用相关MaBatis多数据源配置MyBatisPlus数据统计类处理方案MyBatisPlus条件查询正向工程的实现(H2)mybatis-plus-join
SpringCloud15
Netflix:微服务与搭建Netflix:服务的消费与提供Netflix:EurekaNetflix:ActuatorNetflix:RibbonNetflix:FeignNetflix:HystrixNetflix:ZuulAlibaba:简介与搭建Alibaba:Nacos注册中心Alibaba:RibbonAlibaba:OpenFeignAlibaba:Nacos配置中心Alibaba:GetewayAlibaba:Sentinel
MySQL6
MySQL基础知识MySQL多表查询与事务MySQL常用函数及解决方案MySQL视图MySQL索引安装MySQL
Redis7
Redis介绍和安装Redis配置文件Redis持久化Redis集群Redis语法基础Redis相关问题及解决方案SpringBoot集成Redis使用记录
MongoDB10
Linux安装MongoDBMongoDB基础语法MongoTemplate及SpringBoot配置MongoTemplate中Update操作MongoTemplate中聚合查询MongoTemplate日期归档示例项目使用相关知识归纳地理位置存储与距离查询MongoDB副本集与事务获取类名和属性名工具类
其他数据库1
H2数据库
Python编程6
Python基础知识Python语法yolo目标检测OpenCV的使用及树莓派平台condauv
工具集合13
IDEAMavenGradleGitNginx安装Nginx配置VSCodeJMeter压测DockerOllamaRustFSPicGoObs录制
Linux知识11
Linux常用命令Jar启动脚本VirtualBox安装CentOSVirtualBox安装Ubuntu树莓派安装及使用frp内网穿透ArchLinux:基础系统安装ArchLInux:图形化界面安装ArchLinux:常用软件ArchLinux:深度优化ArchLinux:Niri
创意设计2
Blender:入门知识UI设计基础知识
AI相关9
Claude CodeHermes AgentOpenAI基本使用OpenAI工具调用OpenAI记忆管理OpenAI推理执行OpenAI开发框架Langchainllama.cpp

OpenAI Agent SDK

设计原则

主要功能

安装

pip install openai-agents

基础使用

from openai import AsyncOpenAI
from agents import (
    set_default_openai_client,
    set_default_openai_api,
    set_tracing_disabled
)

# Ollama 配置
OPENAI_BASE_URL = "http://localhost:11434/v1"
OPENAI_API_KEY = "ollama"
OPENAI_MODEL_NAME = "qwen2.5:7b-instruct-q4_K_M"

client = AsyncOpenAI(
    base_url=OPENAI_BASE_URL,
    api_key=OPENAI_API_KEY,
)

# 使用自定义客户端
set_default_openai_client(client=client, use_for_tracing=False)
# 使用兼容的API模式
set_default_openai_api("chat_completions")
# 禁用OpenAI的跟踪服务
set_tracing_disabled(disabled=True)

from agents import Agent, Runner

# 关键:在 Agent 构造函数中直接指定 model 参数
agent = Agent(
    name="AI助手",
    instructions="你是一个友好的AI助手,使用中文交流",
    model=OPENAI_MODEL_NAME  # 添加这一行,明确指定模型名称
)

result = Runner.run_sync(agent, "你是谁")
print(result.final_output)

异步写法

from openai import AsyncOpenAI
from agents import (
    set_default_openai_client,
    set_default_openai_api,
    set_tracing_disabled
)
from agents import Agent, Runner
import asyncio

# Ollama 配置
OPENAI_BASE_URL = "http://localhost:11434/v1"
OPENAI_API_KEY = "ollama"
OPENAI_MODEL_NAME = "qwen2.5:7b-instruct-q4_K_M"

client = AsyncOpenAI(
    base_url=OPENAI_BASE_URL,
    api_key=OPENAI_API_KEY,
)

# 使用自定义客户端
set_default_openai_client(client=client, use_for_tracing=False)
# 使用兼容的API模式
set_default_openai_api("chat_completions")
# 禁用OpenAI的跟踪服务
set_tracing_disabled(disabled=True)

agent = Agent(
    name="AI助手",
    instructions="你是一个友好的AI助手,使用中文交流",
    model=OPENAI_MODEL_NAME  # 添加这一行,明确指定模型名称
)

async def main():
    result = await Runner.run(agent, "你是谁")
    print(result.final_output)

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

流式传输

from openai import AsyncOpenAI
from agents import (
    set_default_openai_client,
    set_default_openai_api,
    set_tracing_disabled
)
from agents import Agent, Runner
import asyncio

# Ollama 配置
OPENAI_BASE_URL = "http://localhost:11434/v1"
OPENAI_API_KEY = "ollama"
OPENAI_MODEL_NAME = "qwen2.5:7b-instruct-q4_K_M"

client = AsyncOpenAI(
    base_url=OPENAI_BASE_URL,
    api_key=OPENAI_API_KEY,
)

# 使用自定义客户端
set_default_openai_client(client=client, use_for_tracing=False)
# 使用兼容的API模式
set_default_openai_api("chat_completions")
# 禁用OpenAI的跟踪服务
set_tracing_disabled(disabled=True)

agent = Agent(
    name="AI助手",
    instructions="你是一个友好的AI助手,使用中文交流",
    model=OPENAI_MODEL_NAME  # 添加这一行,明确指定模型名称
)


async def main():
    # 注意:不需要 await,直接调用
    result = Runner.run_streamed(agent, "讲一个300字的故事")

    # 遍历流式事件
    async for event in result.stream_events():
        if event.type == "raw_response_event":
            # raw_response_event 来自LLM的响应
            if hasattr(event.data, 'delta') and event.data.delta:
                print(event.data.delta, end='', flush=True)
        elif event.type == "run_item_stream_event":
            # run_item_stream_event 来自runner事件(工具调用,交接)
            # 可以选择打印工具调用等信息
            pass

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

连续对话

from openai import AsyncOpenAI
from agents import (
    set_default_openai_client,
    set_default_openai_api,
    set_tracing_disabled
)
from agents import Agent, Runner
import asyncio

# Ollama 配置
OPENAI_BASE_URL = "http://localhost:11434/v1"
OPENAI_API_KEY = "ollama"
OPENAI_MODEL_NAME = "qwen2.5:7b-instruct-q4_K_M"

client = AsyncOpenAI(
    base_url=OPENAI_BASE_URL,
    api_key=OPENAI_API_KEY,
)

# 使用自定义客户端
set_default_openai_client(client=client, use_for_tracing=False)
# 使用兼容的API模式
set_default_openai_api("chat_completions")
# 禁用OpenAI的跟踪服务
set_tracing_disabled(disabled=True)

agent = Agent(
    name="AI助手",
    instructions="你是一个友好的AI助手,使用中文交流",
    model=OPENAI_MODEL_NAME  # 添加这一行,明确指定模型名称
)

# 使用列表存储对话历史
conversation_history = []


async def main(msg):
    global conversation_history
    conversation_history.append({
        "role": "user",
        "content": msg,
    })
    result = Runner.run_streamed(agent, conversation_history)
    # 收集助手的完整回复
    full_response = ""
    # 遍历流式事件
    async for event in result.stream_events():
        if event.type == "raw_response_event":
            # raw_response_event 来自LLM的响应
            if hasattr(event.data, 'delta') and event.data.delta:
                print(event.data.delta, end='', flush=True)
                full_response += event.data.delta
        elif event.type == "run_item_stream_event":
            # run_item_stream_event 来自runner事件(工具调用,交接)
            # 可以选择打印工具调用等信息
            pass

    # 添加助手的回复到历史
    conversation_history.append({
        "role": "assistant",
        "content": full_response,
    })


async def run_conversation():
    await main("1+1=?")
    await asyncio.sleep(3)
    print()
    await main("再加1呢")
    await asyncio.sleep(3)
    print()
    await main("再加1呢")


if __name__ == '__main__':
    asyncio.run(run_conversation())

多模态

import base64
from openai import AsyncOpenAI
from agents import (
    set_default_openai_client,
    set_default_openai_api,
    set_tracing_disabled
)
from agents import Agent, Runner
import asyncio

# Ollama 配置
OPENAI_BASE_URL = "http://localhost:11434/v1"
OPENAI_API_KEY = "ollama"
OPENAI_MODEL_NAME = "qwen3-vl:2b"  # 改成支持多模态的模型!

client = AsyncOpenAI(
    base_url=OPENAI_BASE_URL,
    api_key=OPENAI_API_KEY,
)

# 使用自定义客户端
set_default_openai_client(client=client, use_for_tracing=False)
# 使用兼容的API模式
set_default_openai_api("chat_completions")
# 禁用OpenAI的跟踪服务
set_tracing_disabled(disabled=True)

agent = Agent(
    name="AI助手",
    instructions="你是一个友好的AI助手,使用中文交流",
    model=OPENAI_MODEL_NAME
)


# 图片转base64
def encode_image(image_path):
    with open(image_path, 'rb') as image_file:
        bin_content = image_file.read()
        return base64.b64encode(bin_content).decode("utf-8")


async def main():
    base64_image = encode_image("img.png")

    message = [
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/png;base64,{base64_image}"
                    }
                },
                {
                    "type": "text",
                    "text": "图片中有什么内容?"
                }
            ]
        }
    ]

    result = Runner.run_streamed(agent, message)

    # 遍历流式事件
    async for event in result.stream_events():
        if event.type == "raw_response_event":
            # raw_response_event 来自LLM的响应
            if hasattr(event.data, 'delta') and event.data.delta:
                print(event.data.delta, end='', flush=True)
        elif event.type == "run_item_stream_event":
            # run_item_stream_event 来自runner事件(工具调用,交接)
            pass


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

结构化输出示例

import base64
from openai import AsyncOpenAI
from agents import (
    set_default_openai_client,
    set_default_openai_api,
    set_tracing_disabled
)
from agents import Agent, Runner
import asyncio
from pydantic import BaseModel

# Ollama 配置
OPENAI_BASE_URL = "http://localhost:11434/v1"
OPENAI_API_KEY = "ollama"
OPENAI_MODEL_NAME = "qwen3-vl:2b"  # 改成支持多模态的模型!

client = AsyncOpenAI(
    base_url=OPENAI_BASE_URL,
    api_key=OPENAI_API_KEY,
)

# 使用自定义客户端
set_default_openai_client(client=client, use_for_tracing=False)
# 使用兼容的API模式
set_default_openai_api("chat_completions")
# 禁用OpenAI的跟踪服务
set_tracing_disabled(disabled=True)


# 结构化输出
class Data(BaseModel):
    原信息: str
    建议: str


agent = Agent(
    name="AI助手",
    instructions="你是一个友好的AI助手,使用中文交流",
    model=OPENAI_MODEL_NAME,
    output_type=Data,  # 指定输出结构
)


# 图片转base64
def encode_image(image_path):
    with open(image_path, 'rb') as image_file:
        bin_content = image_file.read()
        return base64.b64encode(bin_content).decode("utf-8")


async def main():
    base64_image = encode_image("2.jpg")

    message = [
        {
            "role": "user",
            "content": [
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/png;base64,{base64_image}"
                    }
                },
                {
                    "type": "text",
                    "text": "图片中有什么内容?你对排版和配色有什么建议"
                }
            ]
        }
    ]

    result = Runner.run_streamed(agent, message)

    # 遍历流式事件
    async for event in result.stream_events():
        if event.type == "raw_response_event":
            # raw_response_event 来自LLM的响应
            if hasattr(event.data, 'delta') and event.data.delta:
                print(event.data.delta, end='', flush=True)
        elif event.type == "run_item_stream_event":
            # run_item_stream_event 来自runner事件(工具调用,交接)
            pass


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

工具调用

使用"""描述好工具说明,agent会自己调用,并再次执行,不需手动执行

import httpx
from openai import AsyncOpenAI
from agents import (
    set_default_openai_client,
    set_default_openai_api,
    set_tracing_disabled
)
from agents import Agent, Runner, function_tool
import asyncio

# Ollama 配置
OPENAI_BASE_URL = "http://localhost:11434/v1"
OPENAI_API_KEY = "ollama"
OPENAI_MODEL_NAME = "qwen2.5:7b-instruct-q4_K_M"

client = AsyncOpenAI(
    base_url=OPENAI_BASE_URL,
    api_key=OPENAI_API_KEY,
)

# 使用自定义客户端
set_default_openai_client(client=client, use_for_tracing=False)
# 使用兼容的API模式
set_default_openai_api("chat_completions")
# 禁用OpenAI的跟踪服务
set_tracing_disabled(disabled=True)


# 天气工具
@function_tool
def get_weather(latitude, longitude):
    """根据指定坐标提供当地摄氏温度"""
    url = f"https://api.open-meteo.com/v1/forecast"
    params = {
        'latitude': latitude,
        'longitude': longitude,
        'current': 'temperature_2m,relative_humidity_2m,wind_speed_10m',
        'hourly': 'temperature_2m,relative_humidity_2m,precipitation,wind_speed_10m,cloud_cover',
        'timezone': 'Asia/Shanghai',
        'forecast_days': 1
    }

    response = httpx.get(url, params=params)
    data = response.json()

    return f"当前温度: {data['current']['temperature_2m']}°C"


agent = Agent(
    name="AI助手",
    instructions="你是一个友好的AI助手,使用中文交流",
    model=OPENAI_MODEL_NAME,
    tools=[get_weather]  # 工具,可以多个

)


async def main():
    # 注意:不需要 await,直接调用
    result = Runner.run_streamed(agent, "今天贵阳天气如何")

    # 遍历流式事件
    async for event in result.stream_events():
        if event.type == "raw_response_event":
            # raw_response_event 来自LLM的响应
            if hasattr(event.data, 'delta') and event.data.delta:
                print(event.data.delta, end='', flush=True)
        elif event.type == "run_item_stream_event":
            # run_item_stream_event 来自runner事件(工具调用,交接)
            # 可以选择打印工具调用等信息
            pass


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

MCP

pip install mcp

MCP脚本

import os
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("MCP Demo")

@mcp.tool()
def ls():
    """列出目录中的文件名"""
    return os.listdir(".")

if __name__ == '__main__':
    mcp.run()

测试运行

from openai import AsyncOpenAI
from agents import (
    set_default_openai_client,
    set_default_openai_api,
    set_tracing_disabled
)
from agents import Agent, Runner
import asyncio
from agents.mcp import MCPServerStdio

# Ollama 配置
OPENAI_BASE_URL = "http://localhost:11434/v1"
OPENAI_API_KEY = "ollama"
OPENAI_MODEL_NAME = "qwen2.5:7b-instruct-q4_K_M"

client = AsyncOpenAI(
    base_url=OPENAI_BASE_URL,
    api_key=OPENAI_API_KEY,
)

# 使用自定义客户端
set_default_openai_client(client=client, use_for_tracing=False)
set_default_openai_api("chat_completions")
set_tracing_disabled(disabled=True)


async def main():
    # 启动独立的 MCP 服务器进程
    async with MCPServerStdio(
            name="MCP Demo",
            params={
                "command": "python",
                "args": ["mcp_server.py"]  # 指向服务器文件
            }
    ) as mcp_server:

        agent = Agent(
            name="AI助手",
            instructions="你是一个友好的AI助手,使用中文交流,可以使用 ls 工具查看文件列表",
            model=OPENAI_MODEL_NAME,
            mcp_servers=[mcp_server],
        )

        result = Runner.run_streamed(agent, "当前目录有哪些文件")

        async for event in result.stream_events():
            if event.type == "raw_response_event":
                if hasattr(event.data, 'delta') and event.data.delta:
                    print(event.data.delta, end='', flush=True)


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

多Agent编排

模式:

顺序

from openai import AsyncOpenAI
from agents import (
    set_default_openai_client,
    set_default_openai_api,
    set_tracing_disabled
)
from agents import Agent, Runner
import asyncio

# Ollama 配置
OPENAI_BASE_URL = "http://localhost:11434/v1"
OPENAI_API_KEY = "ollama"
OPENAI_MODEL_NAME = "qwen3-vl:2b"

client = AsyncOpenAI(
    base_url=OPENAI_BASE_URL,
    api_key=OPENAI_API_KEY,
)

# 使用自定义客户端
set_default_openai_client(client=client, use_for_tracing=False)
# 使用兼容的API模式
set_default_openai_api("chat_completions")
# 禁用OpenAI的跟踪服务
set_tracing_disabled(disabled=True)

agent_a = Agent(
    name="AI助手",
    instructions="你是一个友好的AI助手,使用中文交流",
    model=OPENAI_MODEL_NAME  # 添加这一行,明确指定模型名称
)

agent_b = Agent(
    name="AI助手",
    instructions="对前一个Agent回答进行简要总结",
    model=OPENAI_MODEL_NAME  # 添加这一行,明确指定模型名称
)


async def main():
    result1 = await Runner.run(agent_a, "太阳围绕地球,还是地球围绕太阳?")
    print(result1.final_output)
    print("----------------------------")
    result2 = await Runner.run(agent_b, result1.final_output)
    print(result2.final_output)


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

并行

from openai import AsyncOpenAI
from agents import (
    set_default_openai_client,
    set_default_openai_api,
    set_tracing_disabled
)
from agents import Agent, Runner
import asyncio

# Ollama 配置
OPENAI_BASE_URL = "http://localhost:11434/v1"
OPENAI_API_KEY = "ollama"
OPENAI_MODEL_NAME = "qwen3-vl:2b"

client = AsyncOpenAI(
    base_url=OPENAI_BASE_URL,
    api_key=OPENAI_API_KEY,
)

# 使用自定义客户端
set_default_openai_client(client=client, use_for_tracing=False)
# 使用兼容的API模式
set_default_openai_api("chat_completions")
# 禁用OpenAI的跟踪服务
set_tracing_disabled(disabled=True)

agent_a = Agent(
    name="AI助手",
    instructions="你是一个友好的AI助手,只使用中文交流",
    model=OPENAI_MODEL_NAME  # 添加这一行,明确指定模型名称
)

agent_b = Agent(
    name="AI助手",
    instructions="你是一个友好的AI助手,只使用英文交流",
    model=OPENAI_MODEL_NAME  # 添加这一行,明确指定模型名称
)


async def main():
    result1, result2 = await asyncio.gather(
        Runner.run(agent_a, "每天应该喝多少水?"),
        Runner.run(agent_b, "每天应该喝多少水?")
    )
    print(result1.final_output)
    print("----------------------------")
    print(result2.final_output)


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

路由/交接

原理是把其他的Agent封装为了函数进行调用

from openai import AsyncOpenAI
from agents import (
    set_default_openai_client,
    set_default_openai_api,
    set_tracing_disabled
)
from agents import Agent, Runner
import asyncio

# Ollama 配置
OPENAI_BASE_URL = "http://localhost:11434/v1"
OPENAI_API_KEY = "ollama"
OPENAI_MODEL_NAME = "qwen3-vl:2b"

client = AsyncOpenAI(
    base_url=OPENAI_BASE_URL,
    api_key=OPENAI_API_KEY,
)

# 使用自定义客户端
set_default_openai_client(client=client, use_for_tracing=False)
# 使用兼容的API模式
set_default_openai_api("chat_completions")
# 禁用OpenAI的跟踪服务
set_tracing_disabled(disabled=True)

agent_a = Agent(
    name="AI助手Java",
    instructions="很擅长Java解答,只用英文交流",
    model=OPENAI_MODEL_NAME,
    handoff_description="只使用英文回答"
)

agent_b = Agent(
    name="AI助手Python",
    instructions="很擅长Python解答,只用中文交流",
    model=OPENAI_MODEL_NAME,
    handoff_description="只是用中文回答"
)

agent_c = Agent(
    name="前台助手",
    instructions="不回答问题,根据问题范畴把问题交给适合的Agent",
    model=OPENAI_MODEL_NAME,
    handoffs=[agent_a, agent_b] # 可交接Agent
)


async def main():
    result = Runner.run_streamed(agent_c, "Java的基础数据类型,直接说答案")
    async for event in result.stream_events():
        # print(event)
        if event.type == "raw_response_event":
            # raw_response_event 来自LLM的响应
            if hasattr(event.data, 'delta') and event.data.delta:
                print(event.data.delta, end='', flush=True)
        elif event.type == "run_item_stream_event":
            # run_item_stream_event 来自runner事件(工具调用,交接)
            # 可以选择打印工具调用等信息
            pass


if __name__ == '__main__':
    asyncio.run(main())
OpenAI Agent SDK
设计原则
主要功能
安装
基础使用
异步写法
流式传输
连续对话
多模态
结构化输出示例
工具调用
MCP
MCP脚本
测试运行
多Agent编排
顺序
并行
路由/交接