Assistants API
https://platform.openai.com/docs/assistants/overview
Assistants API 的主要能力
已有能力:
- 创建和管理 assistant,每个 assistant 有独立的配置
- 支持无限长的多轮对话,对话历史保存在 OpenAI 的服务器上
- 通过自有向量数据库支持基于文件的 RAG
- 支持 Code Interpreter
a. 在沙箱里编写并运行 Python 代码
b. 自我修正代码
c. 可传文件给 Code Interpreter - 支持 Function Calling
- 支持在线调试的 Playground
承诺未来会有的能力:
- 支持 DALL·E
- 支持图片消息
- 支持自定义调整 RAG 的配置项
收费:
- 按 token 收费。无论多轮对话,还是 RAG,所有都按实际消耗的 token 收费
- 如果对话历史过多超过大模型上下文窗口,会自动放弃最老的对话消息
- 文件按数据大小和存放时长收费。1 GB 向量存储 一天收费 0.10 美元
- Code interpreter 跑一次 $0.03
划重点:使用 assistant 的意义之一,是可以隔离不同角色的 instruction 和 function 能力。
可以为每个应用,甚至应用中的每个有对话历史的使用场景,创建一个 assistant。
1 | assistant = client.beta.assistants.create( |
管理 thread
Threads:
- Threads 里保存的是对话历史,即 messages
- 一个 assistant 可以有多个 thread
- 一个 thread 可以有无限条 message
- 一个用户与 assistant 的多轮对话历史可以维护在一个 thread 里
1 | # 可以根据需要,自定义 `metadata`,比如创建 thread 时,把 thread 归属的用户信息存入。也可以不传 |
Thread ID 如果保存下来,是可以在下次运行时继续对话的。
从 thread ID 获取 thread 对象的代码
1 | thread = client.beta.threads.retrieve(thread.id) |
此外,还有:
- threads.modify() 修改 thread 的 metadata和tool_resources
- threads.retrieve() 获取 thread
- threads.delete() 删除 thread。
具体文档参考:https://platform.openai.com/docs/api-reference/threads
给 Threads 添加 Messages
这里的 messages 结构要复杂一些:
- 不仅有文本,还可以有图片和文件
- 也有metadata
1 |
|
还有如下函数:
- threads.messages.retrieve() 获取 message
- threads.messages.update() 更新 message 的 metadata
- threads.messages.list() 列出给定 thread 下的所有 messages
具体文档参考:https://platform.openai.com/docs/api-reference/messages
也可以在创建 thread 同时初始化一个 message 列表
1 | thread = client.beta.threads.create( |
开始 Run
- 用 run 把 assistant 和 thread 关联,进行对话
- 一个 prompt 就是一次 run
(执行一次run, 如果run 入参的thread 里面携带(有绑定)message 就相当于向LLM 进行一次提问)
1 | assistant_id = "asst_ahXpE6toS71zFyq9h4iMIDj2" # 从 Playground 中拷贝 |
Run 的底层是个异步调用,意味着它不等大模型处理完,就返回。我们通过 run.status了解大模型的工作进展情况,来判断下一步该干什么。
run.status 有的状态,和状态之间的转移关系如图。
流式运行
- 创建回调函数
1 | from typing_extensions import override |
更多流中的 Event: https://platform.openai.com/docs/api-reference/assistants-streaming/events
- 运行 run
1 | # 添加新一轮的 user message |
还有如下函数:
- threads.runs.list() 列出 thread 归属的 run
- threads.runs.retrieve() 获取 run
- threads.runs.update() 修改 run 的 metadata
- threads.runs.cancel() 取消 in_progress 状态的 run
具体文档参考:https://platform.openai.com/docs/api-reference/runs
使用 Tools
创建 Assistant 时声明 Code_Interpreter
1 | 如果用代码创建: |
发个 Code Interpreter 请求
1 | # 创建 thread |
Code_Interpreter 操作文件
1 | # 上传文件到 OpenAI |
关于文件操作,还有如下函数:
- client.files.list() 列出所有文件
- client.files.retrieve() 获取文件对象
- client.files.delete() 删除文件
- client.files.content() 读取文件内容
具体文档参考:https://platform.openai.com/docs/api-reference/files
创建 Assistant 时声明 Function calling
1 | assistant = client.beta.assistants.create( |
两个无依赖的 function 会在一次请求中一起被调用
1 | # 创建 thread |
创建 Assistant 时声明file_search
tool.type 为file_search时相当于内置的 RAG 功能
创建 Vector Store,上传文件
- 通过代码创建 Vector Store
1 | vector_store = client.beta.vector_stores.create( |
Vector store 和 vector store file 也有对应的 list,retrieve 和 delete等操作。
具体文档参考:
- Vector store: https://platform.openai.com/docs/api-reference/vector-stores
- Vector store file: https://platform.openai.com/docs/api-reference/vector-stores-files
- Vector store file 批量操作: https://platform.openai.com/docs/api-reference/vector-stores-file-batches
创建 Assistant 时声明 RAG 能力
RAG 实际被当作一种 tool
1 | assistant = client.beta.assistants.create( |
指定检索源
1 | assistant = client.beta.assistants.update( |
RAG 请求
1 | # 创建 thread |
多个 Assistants 协作
划重点: 使用 assistant 的意义之一,是可以隔离不同角色的 instruction 和 function 能力。
6顶思维帽实验
技术选型参考
GPTs 现状:
- 界面不可定制,不能集成进自己的产品
- 只有 ChatGPT Plus/Team/Enterprise 用户才能访问
- 未来开发者可以根据使用量获得报酬,北美先开始
- 承诺会推出 Team/Enterprise 版的组织内部专属 GPTs
适合使用 Assistants API 的场景:
- 定制界面,或和自己的产品集成
- 需要传大量文件
- 服务国外用户,或国内 B 端客户
- 数据保密性要求不高
- 不差钱
适合使用原生 API 的场景:
- 需要极致调优
- 追求性价比
- 服务国外用户,或国内 B 端客户
- 数据保密性要求不高
适合使用国产或开源大模型的场景:
- 服务国内用户
- 数据保密性要求高
- 压缩长期成本
- 需要极致调优