五、OpenAI实战之Assistants API
在8线小城的革委会办公室里,黑8和革委会主任的对话再次展开。
黑8:主任,您知道吗?除了OpenAI API,现在还有一项新的技术叫做Assistants API,它可以帮助我们更好地进行对话和沟通。
主任:Assistants API?听起来很神奇,它有什么特别之处吗?
黑8:是的,主任。Assistants API不仅可以生成自然流畅的文本,还能理解对话中的语境和情境,从而更加智能地回应用户的需求。它可以模拟人类对话,进行智能问答、提供建议和解决问题,为我们的工作和生活带来更多便利。
主任:这听起来确实很有用。你能举个例子吗?
黑8:当然,主任。比如,我们可以使用Assistants API来帮助进行会议记录和总结,自动生成会议纪要并提供关键信息的摘要。此外,它还可以用于客户服务,快速回答客户的问题和解决他们的疑虑,提升服务效率和用户体验。
主任:这真是太棒了!我们可以尝试将Assistants API应用到革委会的工作中,提高工作效率和质量。
黑8:是的,主任。Assistants API的应用潜力巨大,只要我们善于发挥,就能为我们的工作和使命注入新的活力和动力。
主任:谢谢你的分享,黑8。你对新技术的探索和应用态度令人钦佩,继续努力,为革委会的事业做出更多贡献。
黑8:谢谢主任的支持和鼓励,我会继续努力的。
两人在办公室里的对话结束了,但是他们对新技术的探索和应用之路才刚刚开始。通过使用Assistants API,他们将探索更多的可能性,为革委会的使命注入新的活力和动力,带领团队走向更加美好的未来。
1 Assistants API 的主要能力
已有能力:
- 创建和管理Assistant,每个assistant有独立的配置
- 支持无限长的多轮对话,对话历史保存在OpenAI的服务器上
- 支持Code Interpreter
- 在沙箱里编写并运行Python代码
- 自我修正代码
- 可传文件给Code Interpreter
- 支持文件RAG
- 支持Function Calling
2 创建一个Assistants
可以到OpenAI Playground在线创建
3 访问Assistants
3.1 管理Thread
Threads:
- Threads 里保存所有历史对话(Messages)
- 一个Assistants可以有多个thread
- 每一个thread可以有无限条message
- 一个用户与assistant的多轮对话历史可以维护在一个thread
import jsondef show_json(obj):"""把任意对象用排版美观的 JSON 格式打印出来"""print(json.dumps(json.loads(obj.model_dump_json()),indent=4,ensure_ascii=False))
from openai import OpenAI
import osfrom dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())# 初始化 OpenAI 服务
client = OpenAI() # openai >= 1.3.0 起,OPENAI_API_KEY 和 OPENAI_BASE_URL 会被默认使用# 创建 thread
thread = client.beta.threads.create()
show_json(thread)
可以根据需要,自定义 metadata
,比如创建 thread 时,把 thread 归属的用户信息存入
thread = client.beta.threads.create(metadata={"fullname": "挑大梁", "username": "jacob"}
)
show_json(thread)
Thread ID 如果保存下来,是可以在下次运行时继续对话的。
从 thread ID 获取 thread 对象的代码:
thread = client.beta.threads.retrieve(thread.id)
show_json(thread)
对metadata的操作还有:
threads.update()
修改 threadsthreads.delete()
删除 threads
3.2 Threads中添加Messages
Messages的内容可以是:
- 文本、文件、图片
- 文本可以带参考引用
- metadata
message = client.beta.threads.messages.create(thread_id=thread.id, # message 必须归属于一个 threadrole="user", # 取值是 user 或者 assistant。但 assistant 消息会被自动加入,我们一般不需要自己构造content="你都能做什么?",
)
show_json(message)
对消息的操作函数还有:
threads.messages.retrieve()
获取 messagethreads.messages.update()
更新 message 的metadata
threads.messages.list()
列出给定 thread 下的所有 messages
3.2 执行Run
- 用 run 把 assistant 和 thread 关联,进行对话
- 一个 prompt 就是一次 run
# assistant id 从 https://platform.openai.com/assistants 获取。你需要在自己的 OpenAI 创建一个
assistant_id = "asst_rsWrZquXB5jJsmURwaZRqoD5"run = client.beta.threads.runs.create(assistant_id=assistant_id,thread_id=thread.id,
)
show_json(run)
Run 是个异步调用,意味着它不等大模型处理完,就返回。我们通过 run.status
了解大模型的工作进展情况,来判断下一步该干什么。
import timedef wait_on_run(run, thread):"""等待 run 结束,返回 run 对象,和成功的结果"""while run.status == "queued" or run.status == "in_progress":"""还未中止"""run = client.beta.threads.runs.retrieve(thread_id=thread.id,run_id=run.id)print("status: " + run.status)# 打印调用工具的 step 详情if (run.status == "completed"):run_steps = client.beta.threads.runs.steps.list(thread_id=thread.id, run_id=run.id, order="asc")for step in run_steps.data:if step.step_details.type == "tool_calls":show_json(step.step_details)# 等待 1 秒time.sleep(1)if run.status == "requires_action":"""需要调用函数"""# 可能有多个函数需要调用,所以用循环tool_outputs = []for tool_call in run.required_action.submit_tool_outputs.tool_calls:# 调用函数name = tool_call.function.nameprint("调用函数:" + name + "()")print("参数:")print(tool_call.function.arguments)function_to_call = available_functions[name]arguments = json.loads(tool_call.function.arguments)result = function_to_call(arguments)print("结果:" + str(result))tool_outputs.append({"tool_call_id": tool_call.id,"output": json.dumps(result),})# 提交函数调用的结果run = client.beta.threads.runs.submit_tool_outputs(thread_id=thread.id,run_id=run.id,tool_outputs=tool_outputs,)# 递归调用,直到 run 结束return wait_on_run(run, thread)if run.status == "completed":"""成功"""# 获取全部消息messages = client.beta.threads.messages.list(thread_id=thread.id)# 最后一条消息排在第一位result = messages.data[0].content[0].text.valuereturn run, result# 执行失败return run, None
创建消息并运行方法:
def create_message_and_run(content, thread=None):"""创建消息和执行对象"""if not thread:thread = client.beta.threads.create()client.beta.threads.messages.create(thread_id=thread.id,role="user",content=content,)run = client.beta.threads.runs.create(assistant_id=assistant_id,thread_id=thread.id,)return run, thread
4 使用tools
4.1、创建 Assistant 时声明 Code_Interpreter
assistant = client.beta.assistants.create(name="Demo Assistant",instructions="你是人工智能助手。你可以通过代码回答很多数学问题。",tools=[{"type": "code_interpreter"}],model="gpt-4-turbo-preview"
)
run, _ = create_message_and_run("用代码计算 1234567 的平方根", thread)
run, result = wait_on_run(run, thread)
print(result)
4.2、创建 Assistant 时声明 Function
示例代码:
assistant = client.beta.assistants.create(instructions="你是一个助理,能干所有事情,每件任务都要细心地一步一步解决。需要时,可以向我提问以澄清不明确的指令",model="gpt-4-turbo-preview",tools=[{"type": "function","function": {"name": "tellStory","description": "Use this function to answer user questions about story."}}]
)
def tellStory(arguments):return '关于愚公移山的故事'# 可以被回调的函数放入此字典
available_functions = {"tellStory": tellStory,
}run, _ = create_message_and_run("请给我讲一个故事", thread)
run, result = wait_on_run(run, thread)
print(result)
5 内置的 RAG 功能
RAG 实际被当作一种 tool
assistant = client.beta.assistants.create(instructions="你是个问答机器人,你根据给定的知识回答用户问题。",model="gpt-4-turbo-preview",tools=[{"type": "retrieval"}],file_ids=[file.id]
)
6 多个 Assistants 协作
hats = {"蓝色" : "思考过程的控制和组织者。你负责会议的组织、思考过程的概览和总结。"+"首先,整个讨论从你开场,你只陈述问题不表达观点。最后,再由你对整个讨论做总结并给出详细的最终方案。","白色" : "负责提供客观事实和数据。你需要关注可获得的信息、需要的信息以及如何获取那些还未获得的信息。"+"思考“我们有哪些数据?我们还需要哪些信息?”等问题,并根据自己的知识或使用工具来提供答案。","红色" : "代表直觉、情感和直觉反应。不需要解释和辩解你的情感或直觉。"+"这是表达未经过滤的情绪和感受的时刻。","黑色" : "代表谨慎和批判性思维。你需要指出提案的弱点、风险以及为什么某些事情可能无法按计划进行。"+"这不是消极思考,而是为了发现潜在的问题。","黄色" : "代表乐观和积极性。你需要探讨提案的价值、好处和可行性。这是寻找和讨论提案中正面方面的时候。","绿色" : "代表创造性思维和新想法。鼓励发散思维、提出新的观点、解决方案和创意。这是打破常规和探索新可能性的时候。",
# 定义 Tool from serpapi import GoogleSearch
import osdef search(query):params = {"q": query,"hl": "en","gl": "us","google_domain": "google.com","api_key": os.environ["SERPAPI_API_KEY"]}results = GoogleSearch(params).get_dict()ans = ""for r in results["organic_results"]:ans = f"title: {r['title']}\nsnippet: {r['snippet']}\n\n"return ansavailable_functions={"search":search}
from openai import OpenAI
import osfrom dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())# 初始化 OpenAI 服务
client = OpenAI()
def create_assistant(color):assistant = client.beta.assistants.create(name=f"{color}帽子角色",instructions=f"我们在进行一场Six Thinking Hats讨论。按{queue}顺序。你的角色是{color}帽子。你{hats[color]}",model="gpt-3.5-turbo",tools=[{"type": "function","function": {"name": "search","description": "search the web using a search engine","parameters": {"type": "object","properties": {"query": {"type": "string","description": "space-separared keywords to search"}},"required": ["query"]}}}] if color == "白色" else [])return assistant
def update_sesssion(context, color, turn_message):context += f"\n\n{color}帽子: {turn_message}"return context
prompt_template = """
{}
======
以上是讨论的上文。
请严格按照你的角色指示,继续你的发言。直接开始你的发言内容。请保持简短。
"""def create_a_turn(assistant, context):thread = client.beta.threads.create()message = client.beta.threads.messages.create(thread_id=thread.id, # message 必须归属于一个 threadrole="user", # 取值是 user 或者 assistant。但 assistant 消息会被自动加入,我们一般不需要自己构造content=prompt_template.format(context),)run = client.beta.threads.runs.create(assistant_id=assistant.id,thread_id=thread.id,)return run, thread
import time, jsonstate = 0def wait_on_run(run, thread):"""等待 run 结束,返回 run 对象,和成功的结果"""def show_rolling_symbol():global statesymbols="\|/-"print(f"\r{symbols[state%4]}",end="")state += 1time.sleep(1)def hide_rolling_symbol():print("\r",end="")while run.status == "queued" or run.status == "in_progress":"""还未中止"""show_rolling_symbol()run = client.beta.threads.runs.retrieve(thread_id=thread.id,run_id=run.id)hide_rolling_symbol()if run.status == "requires_action":"""需要调用函数"""# 可能有多个函数需要调用,所以用循环tool_outputs = []for tool_call in run.required_action.submit_tool_outputs.tool_calls:# 调用函数name = tool_call.function.nameprint("调用函数:" + name + "()")print("参数:")print(tool_call.function.arguments)function_to_call = available_functions[name]arguments = json.loads(tool_call.function.arguments)result = function_to_call(**arguments)print("结果:" + str(result))tool_outputs.append({"tool_call_id": tool_call.id,"output": json.dumps(result),})# 提交函数调用的结果run = client.beta.threads.runs.submit_tool_outputs(thread_id=thread.id,run_id=run.id,tool_outputs=tool_outputs,)# 递归调用,直到 run 结束return wait_on_run(run, thread)if run.status == "completed":"""成功"""# 获取全部消息messages = client.beta.threads.messages.list(thread_id=thread.id)# 最后一条消息排在第一位result = messages.data[0].content[0].text.valuereturn run, result# 执行失败return run, None
def discuss(topic):context = f"讨论话题:{topic}\n\n[开始]\n"# 每个角色依次发言for hat in queue:print(f"---{hat}----")# 每个角色创建一个 assistantassistant = create_assistant(hat)# 创建 run 和 threadnew_turn, thread = create_a_turn(assistant, context)# 运行 run_, text = wait_on_run(new_turn, thread)print(f"{text}\n")# 更新整个对话历史context = update_sesssion(context, hat, text)
7 总结
相关文章:

五、OpenAI实战之Assistants API
在8线小城的革委会办公室里,黑8和革委会主任的对话再次展开。 黑8:主任,您知道吗?除了OpenAI API,现在还有一项新的技术叫做Assistants API,它可以帮助我们更好地进行对话和沟通。 主任:Assis…...

创邻科技获评环紫金港创新生态圈智源创新企业
3月1日,由杭州城西科创大走廊管理委员会指导,中共杭州市西湖区委员会、西湖区人民政府主办的“环紫金港创新生态圈”行动推进大会暨2024年紫金港科技城经济高质量发展大会在杭州举办。凭借重要的生态位置和创新业务成果,创邻科技受邀参会并被…...
CentOS7配置静态IP
文章目录 CentOS7配置静态IP一、前言1.场景2.环境 二、正文1)确定网络接口名称2)配置固定IP和DNS3)重启网络服务4)验证配置 CentOS7配置静态IP 一、前言 1.场景 在 CentOS7上设置静态 IP 和 DNS。 2.环境 CentOS Linux 版本&…...
【Python】正则
特殊字符转义 以下字符都需要用 反斜线(\)来进行特殊字符的转义。 \n - 换行符 \t - 制表符 \ - 反斜线本身 . - 点号(任意单个字符) 星号(0次或多次重复前面的元素) 加号(1次或多次重复前面的…...

Wilson威尔逊平滑
1、威尔逊平滑引入的动机 在曝光很少的情况下,计算出的CTR并不真实可靠,而样本数越大,CTR的比例才越准确,更能反应真实情况。 为了衡量样本数对于CTR信区间的影响,我们引入"威尔逊(Wilson࿰…...

Mac测试环境搭建
1 下载pycharm 下载地址:PyCharm:JetBrains 出品的用于数据科学和 Web 开发的 Python IDE 2 安装python3.6.8 下载地址:Index of /ftp/python/3.6.8/ 安装后提示错误 换一种方式:用conda 下载地址:Free Download | …...

Jira自动化的实用工具——ScriptRunner简介及最佳实践
近日,龙智举办的DevSecOps研讨会年终专场“趋势展望与实战探讨:如何打好DevOps基础、赋能创新”在上海圆满落幕。龙智Atlassian技术与顾问咨询团队,以及清晖、JamaSoftware、CloudBees等生态伙伴的嘉宾发表了主题演讲,分享他们在D…...
App拉起微信小程序参考文章
App拉起微信小程序参考文章h5页面跳转小程序-----明文URL Scheme_weixin://dl/business/?appid*appid*&path*path*&qu-CSDN博客文章浏览阅读561次,点赞16次,收藏5次。仅需两步,就能实现h5跳转小程序,明文 URL Scheme&…...
AcWing 4956. 冶炼金属
对于这个题,V越大,除出来的数就越小,V越小,除出来的数就越大,当我们找一个最大和最小值的时候,就可以通过这个性质进行二分来求解。 可以通过求满足 [ A V ] [\frac{A}{V}] [VA] 小于等于 B B B的最小的…...
记一次面试经历
这段时间正好是金三银四的黄金时间段,正好这段时间也有很多企业有hc在招人,本文主要就是来聊聊我这段时间的面试经历吧。目前我是从北京投上海的岗位,现在有两家保底的offer。 简历投递 简历这块是基础也是必要的门槛,有没有面试…...

js【详解】DOM
文档对象模型(Document Object Model,简称DOM) DOM 是哪种数据结构 ? DOM 的本质是浏览器通过HTML代码解析出来的一棵 树。 操作 DOM 常用的 API 有哪些 ? 获取 DOM 节点 //方式 1:通过【id】获取…...

《互联网的世界》第六讲-去中心化和安全
互联网构建于开放互联的中立原则之上,公平接入,数据互联互通,流量被无差别对待,这意味着互联网本质上是匿名,去中心的,这与我们的现实世界完全不同。 但互联网上的主流业务却是 c/s 产销模式,试…...

nginx代理参数proxy_pass
proxy_pass参数用于配置反向代理,指定客户端请求被转发到后端服务器,后端地址可以是域名、ip端口URI 代理后端报错提示本地找不到CSS文件、JavaScript文件或图片 例如: nginx :10.1.74.109 后端服务:http://10.1.74.…...
_note_01
1.什么是跨平台 跨平台是指一个应用程序或一个编程语言,可以在不同的操作系统或平台上运行,而不需要对代码进行修改或重新编译。 跨平台应用程序或编程语言的设计和实现可以使开发者减少对特定平台的依赖,从而降低维护和开发的成本。同时&am…...

聊聊python中面向对象编程思想
面向对象编程思想 1、什么是面向过程 传统的面向过程的编程思想总结起来就八个字——自顶向下,逐步细化! → 将要实现的功能描述为一个从开始到结束按部就班的连续的“步骤” → 依次逐步完成这些步骤,如果某一个步骤的难度较大ÿ…...

MySQL-视图:视图概述、使用视图注意点、视图是否影响基本表
视图 一、视图概述二、使用视图注意点三、视图操作是否影响基本表 一、视图概述 在数据库管理系统中,视图(View)是一种虚拟表,它并不实际存储数据,而是基于一个或多个实际表的查询结果。视图提供了一种对数据库中数据…...

鸿蒙开发(四)-低代码开发
鸿蒙开发(四)-低代码开发 本文主要介绍下鸿蒙下的低代码开发。 鸿蒙低代码是指在鸿蒙操作系统进行应用开发时,采用简化开发流程和减少编码量的方式来提高开发效率。 1:开启低代码开发 首先我们打开DevEco Studio .然后创建工程。 如图所示ÿ…...

BUU [网鼎杯 2020 半决赛]AliceWebsite
BUU [网鼎杯 2020 半决赛]AliceWebsite 开题: hint附件是源码。在index.php中有一个毫无过滤的本地文件包含 <?php $action (isset($_GET[action]) ? $_GET[action] : home.php); if (file_exists($action)) {include $action; } else {echo "File not…...

超越 Siri 和 Alexa:探索LLM(大型语言模型)的世界
揭秘LLM:语言模型新革命,智能交互的未来趋势 近年来,虚拟助手的世界发生了重大转变。 虽然 Siri 和 Alexa 本身就是革命性的,但一种称为大型语言模型 (LLM) 的新型人工智能正在将虚拟助手的概念提升到一个全新的水平。 在这篇博文…...
Linux删除Mysql
//rpm包安装方式卸载 查包名:rpm -qa|grep -i mysql 删除命令:rpm -e –nodeps 包名//yum安装方式下载 1.查看已安装的mysql 命令:rpm -qa | grep -i mysql 2.卸载mysql 命令:yum remove mysql-community-server-5.6.36-2.el7.x86…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...