Name | openai2 JSON |
Version |
1.7.12
JSON |
| download |
home_page | None |
Summary | ChatGPT 工具包,支持多模态对话(gpt-4o)、连续对话、流式对话(逐字显示)、生成图像(DALL·E)、对话存档与载入、对话回滚、对话伪造、轮询 api_key 池、群聊多角色模拟、在命令行对话、限制历史消息数量、异步请求。 |
upload_time | 2024-09-14 02:06:44 |
maintainer | None |
docs_url | None |
author | None |
requires_python | None |
license | None |
keywords |
openai
chatgpt
openai2
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# 项目描述
ChatGPT 工具包,支持多模态对话(gpt-4o)、连续对话、流式对话(逐字显示)、生成图像(DALL·E)、对话存档与载入、对话回滚、对话伪造、轮询 api_key 池、群聊多角色模拟、在命令行对话、限制历史消息数量、异步请求。
# 作者
江南雨上
[主页](https://lcctoor.com/index.html) \| [Github](https://github.com/lcctoor) \| [PyPi](https://pypi.org/user/lcctoor) \| [微信](https://lcctoor.com/cdn/WeChatQRC.jpg) \| [邮箱](mailto:lcctoor@outlook.com) \| [捐赠](https://lcctoor.com/cdn/DonationQRC-0rmb.jpg)
# Bug提交、功能提议
你可以通过 [Github-Issues](https://github.com/lcctoor/arts/issues)、[微信](https://lcctoor.com/cdn/WeChatQRC.jpg) 与我联系。
# 安装
```
pip install openai2
```
# 获取api_key
[获取链接1](https://platform.openai.com/account/api-keys)
[获取链接2](https://www.baidu.com/s?wd=%E8%8E%B7%E5%8F%96%20openai%20api_key)
# 教程 ([查看美化版](https://github.com/lcctoor/arts/blob/main/arts/openai2/README.md#项目描述) 👈)
## 导入
```python
from openai2 import Chat
```
## 创建对话
```python
api_key = 'api_key' # 更换成自己的api_key
Tony = Chat(api_key=api_key, model="gpt-3.5-turbo")
Lucy = Chat(api_key=api_key, model="gpt-3.5-turbo") # 每个实例可使用 相同 或者 不同 的api_key
```
## 对话
```python
Tony.request('自然数50的后面是几?') # >>> '51'
Lucy.request('自然数100的后面是几?') # >>> '101'
Tony.request('再往后是几?') # >>> '52'
Lucy.request('再往后是几?') # >>> '102'
Tony.request('再往后呢?') # >>> '53'
Lucy.request('再往后呢?') # >>> '103'
```
## 流式对话 ([查看演示](https://lcctoor.com/openai2/oa_/流式对话演示.mp4) 👈)
```python
for answer in Lucy.stream_request('世界上最大的海洋是哪个?'):
print(answer)
世
界
上
最
大
的
海
洋
是
太
平
洋
。
```
## 异步对话
```python
import asyncio
from openai2 import Chat
Tony = Chat(api_key=api_key, model="gpt-3.5-turbo")
async def main():
answer = await Tony.async_request('世界上最大的海洋是哪个')
print(answer)
asyncio.run(main()) # >>> '世界上最大的海洋是太平洋。'
```
## 异步流式对话
```python
async for answer in Tony.async_stream_request('世界上最大的海洋是哪个?'):
print(answer)
世
界
上
最
大
的
海
洋
是
太
平
洋
。
```
## 多模态对话(gpt-4o)
```python
from pathlib import Path
from openai2 import Chat, Multimodal_Part
Bruce = Chat(api_key='sk-jg93...', model="gpt-4o")
pic = Path(rf'C:\鼠标.jpeg').read_bytes()
answer = Bruce.request(
'下面这张图片里画了什么?',
Multimodal_Part.jpeg(pic)
)
print(answer) # >>> '这张图片里画了一个鼠标。'
```
注:
1、Multimodal_Part 除了 jpeg 方法以外,还有 png、text …… 等方法。
2、对于 str 型对象,以下这两种写法是等价的:`Bruce.request(..., '这张图片里画了什么', ...)`、`Bruce.request(..., Multimodal_Part.text('这张图片里画了什么'), ...)`。
3、多模态对话支持同步对话、异步对话、同步流式对话、异步流式对话…… 相对于普通对话,唯一的区别就是支持多模态。
4、目前已知支持多模态对话的模型有:gpt-4o、gpt-4o-mini、gpt-4o-2024-05-13、gpt-4o-mini-2024-07-18。
## 对话回滚
```python
Anna = Chat(api_key=api_key, model="gpt-3.5-turbo")
Anna.request('自然数1的后面是几?') # >>> 2
Anna.request('再往后是几?') # >>> 3
Anna.request('再往后呢?') # >>> 4
Anna.request('再往后呢?') # >>> 5
Anna.request('再往后呢?') # >>> 6
Anna.request('再往后呢?') # >>> 7
Anna.request('再往后呢?') # >>> 8
# 回滚1轮对话
Anna.rollback() # >>> [user]:再往后呢? [assistant]:7
# 再回滚3轮对话
Anna.rollback(n=3) # >>> [user]:再往后呢? [assistant]:4
Anna.request('再往后呢?') # >>> 5
```
注:
1、执行 `Anna.rollback(n=x)` 可回滚 x 轮对话。
2、`Anna.rollback()` 相当于 `Anna.rollback(n=1)` 。
## 轮询 api_key 池
```python
from openai2 import Chat, AKPool
AK1 = 'sk-ug8w...'
AK2 = AKPool(['sk-mf40...', 'sk-m6g7...', ...])
AK3 = AKPool(['sk-affe...', 'sk-fam4...', ...])
Duke = Chat(api_key=AK1, model="gpt-3.5-turbo") # 令 Duke 使用固定的 api_key
Carl = Chat(api_key=AK2, model="gpt-3.5-turbo") # 令 Carl 和 Denny 使用同一个'api_key池', 系统将自动充分利用每个api_key
Denny = Chat(api_key=AK2, model="gpt-3.5-turbo")
Chris = Chat(api_key=AK3, model="gpt-3.5-turbo") # 令 Chris 使用独立的'api_key池'
```
注:允许(而非不允许)同一个 api_key 投放到不同的 api_key 池中,但每个 api_key 池都是独立调度,不会互相通信。
## 重置 api_key
```python
AK5 = 'sk-jg93...'
AK6 = AKPool(['sk-vb7l...', 'sk-d3lv...'])
...
Carl.reset_api_key(AK5) # 重置 api_key
Carl.reset_api_key(AK6) # 再次重置 api_key
...
```
## 对话导出与导入
### 对话导出
```python
Ariel = Chat(api_key=api_key, model="gpt-3.5-turbo")
Ariel.request('自然数1的后面是几?') # >>> 2
Ariel.request('再往后是几?') # >>> 3
Ariel.fetch_messages()
# 返回:
# [
# {'role': 'user', 'content': '自然数1的后面是几?'},
# {'role': 'assistant', 'content': '2'},
# {'role': 'user', 'content': '再往后是几?'},
# {'role': 'assistant', 'content': '3'}
# ]
```
### 对话存档
你可以把导出的对话持久化保存:
```python
import json
from pathlib import Path
record = Ariel.fetch_messages()
record = json.dumps(record, ensure_ascii=False)
Path('record.json').write_text(record, encoding="utf8")
```
### 对话导入
导出的对话可以再导入到其它对话中:
```python
record = Ariel.fetch_messages()
Jenny = Chat(api_key=api_key, model="gpt-3.5-turbo")
Jenny.add_dialogs(*record)
Jenny.request('再往后呢?') # >>> 4
```
导出的对话也可以再导入到原对话中,但这样做会在原对话中产生重复的历史消息。
### 对话伪造
利用对话导入功能,可以伪造对话:
```python
from openai2 import Chat, user_msg, assistant_msg
Mickey = Chat(api_key=api_key, model="gpt-3.5-turbo")
Mickey.add_dialogs(
user_msg('请问1+1=几?'), # 等价于 {"role": "user", "content": '请问1+1=几?'}
assistant_msg('1+1=10'), # 等价于 {"role": "assistant", "content": '1+1=10'}
{"role": "user", "content": '那10+10=几?'},
{"role": "assistant", "content": '10+10=你大爷, 你提的这些问题真弱智!'},
)
answer = Mickey.request('哦吼, 你还敢骂我呀?')
print(answer) # >>> 非常抱歉,我刚才的回答有些不适当。1+1=2, 10+10=20。非常抱歉给你带来困扰!
```
注:对话导出与导入可以穿插在对话中的任何时刻。
## 生成图像(DALL·E)
返回图片的二进制:
```python
from pathlib import Path
from openai2 import Chat
Tony = Chat(api_key='sk-jg93...', model="dall-e-2")
images = Tony.dalle('请画一只猫', image_count=2)
for i, x in enumerate(images):
Path(f"第{i}张.png").write_bytes(x)
```
返回图片的URL:
```python
from pathlib import Path
from openai2 import Chat
Tony = Chat(api_key='sk-jg93...', model="dall-e-2")
images = Tony.dalle('请画一只猫', image_count=2, return_format='url')
for i, url in enumerate(images):
print(f"第{i}张的URL是:", url)
```
## 异步生成图像(DALL·E)
返回图片的二进制:
```python
import asyncio
from pathlib import Path
from openai2 import Chat
async def main():
Tony = Chat(api_key='sk-jg93...', model="dall-e-2")
images = await Tony.async_dalle('请画一只猫', image_count=2)
for i, x in enumerate(images):
Path(f"第{i}张.png").write_bytes(x)
asyncio.run(main())
```
返回图片的URL:
```python
import asyncio
from pathlib import Path
from openai2 import Chat
async def main():
Tony = Chat(api_key='sk-jg93...', model="dall-e-2")
images = await Tony.async_dalle('请画一只猫', image_count=2, return_format='url')
for i, url in enumerate(images):
print(f"第{i}张的URL是:", url)
asyncio.run(main())
```
## 群聊多角色模拟
```python
import json
from openai2 import GroupChat
api_key = '...' # 更换成自己的 api_key
group = GroupChat(api_key=api_key, model="gpt-3.5-turbo")
# 设置角色
group.roles['苏轼'] = '宋朝诗人,他的词风格独特,既有儒家的教诲,又有生活的乐趣。'
group.roles['李清照'] = '宋代著名的女词人,其词句优美,情感真挚。'
group.roles['杜甫'] = '唐朝著名诗人。'
# 添加角色历史对话
group.add_dialog(speaker='苏轼', audiences=['李清照'], remark='你好呀')
group.add_dialog(speaker='李清照', audiences=['苏轼'], remark='好久不见, 你最近在忙什么?')
group.add_dialog(speaker='杜甫', audiences=['苏轼'], remark='上次托你帮我写的那首《茅屋为秋风所破歌》写好了吗?')
# 让 ChatGPT 模拟角色发言
answer = group.request([
('苏轼', ['李清照']), # 第 1 个元素表示说话人, 第 2 个元素表示对谁说话. 由于一个人可以同时对多个人说话, 因此第 2 个元素为列表
('苏轼', ['杜甫']),
])
try:
print( json.loads(answer) )
except:
print(answer)
# 返回:
[
{
"speaker": "苏轼",
"audiences": "李清照",
"remark": "最近我在写一首新的诗,题目是《听雨》"
},
{
"speaker": "苏轼",
"audiences": "杜甫",
"remark": "那首《茅屋为秋风所破歌》已经写好啦,我在信里寄给你了,请查收"
}
]
```
## 限制历史消息数量
### 限制历史消息数量
随着对话次数越来越多,最终上下文长度就会超出 openai 接口限定的最大 token 数量,此时可使用 msg_max_count 参数来限制历史消息数量。当消息数量超出 msg_max_count 后,程序会自动移除最早的记录,使消息数量减少到恰好等于 msg_max_count 。
```python
msg_max_count = 6 # 最多保留6条历史消息
Ariel = Chat(api_key=api_key, model="gpt-3.5-turbo", msg_max_count=msg_max_count)
Ariel.request('英国的首都是什么?') # >>> '伦敦'
Ariel.request('日本首都是什么?') # >>> '东京'
Ariel.request('意大利的首都是什么?') # >>> '罗马'
Ariel.request('美国的首都是什么?') # >>> '华盛顿'
Ariel.request('世界上国土面积最大的国家是哪个?') # >>> '俄罗斯'
Ariel.request('法国的首都叫什么?') # >>> '巴黎'
Ariel.request('青蛙的幼体叫什么?') # >>> '蝌蚪'
Ariel.request('世界上最大的海洋是什么?') # >>> '太平洋'
Ariel.fetch_messages()
# 返回:
# [
# {'role': 'user', 'content': '法国的首都叫什么?'},
# {'role': 'assistant', 'content': '巴黎'},
# {'role': 'user', 'content': '青蛙的幼体叫什么?'},
# {'role': 'assistant', 'content': '蝌蚪'},
# {'role': 'user', 'content': '世界上最大的海洋是什么?'},
# {'role': 'assistant', 'content': '太平洋'}
# ]
```
### 锁定消息
当程序自动移除消息记录时,也许我们希望某些消息不要被移除,此时可将这些消息锁定。
```python
msg_max_count = 6
Ariel = Chat(api_key=api_key, model="gpt-3.5-turbo", msg_max_count=msg_max_count)
Ariel.request('英国的首都是什么?') # >>> '伦敦'
Ariel.request('日本首都是什么?') # >>> '东京'
Ariel.request('意大利的首都是什么?') # >>> '罗马'
```
此时共有 6 条消息记录:
| 消息 | 正序索引 | 逆序索引 |
| -------------------- | :------: | :------: |
| 英国的首都是什么? | 0 | -6 |
| 伦敦 | 1 | -5 |
| 日本首都是什么? | 2 | -4 |
| 东京 | 3 | -3 |
| 意大利的首都是什么? | 4 | -2 |
| 罗马 | 5 | -1 |
锁定索引为 0、-2、-1 的消息:
```python
Ariel.pin_messages(0, -2, -1) # 索引无须按顺序填写: pin_messages(0, 1, 2) 与 pin_messages(0, 2, 1) 等价.
```
继续请求:
```python
Ariel.request('美国的首都是什么?') # >>> '华盛顿'
```
由于设置了 msg_max_count = 6,此时共有 6 条消息记录:
| 消息 | 正序索引 | 逆序索引 | 锁定状态 |
| -------------------- | :------: | :------: | :------: |
| 英国的首都是什么? | 0 | -6 | 已锁定 |
| 东京 | 1 | -5 | - |
| 意大利的首都是什么? | 2 | -4 | 已锁定 |
| 罗马 | 3 | -3 | 已锁定 |
| 美国的首都是什么? | 4 | -2 | - |
| 华盛顿 | 5 | -1 | - |
继续执行:
```python
Ariel.pin_messages(-2) # 锁定'美国的首都是什么?'
Ariel.request('世界上国土面积最大的国家是哪个?') # >>> '俄罗斯'
Ariel.request('法国的首都叫什么?') # >>> '巴黎'
Ariel.request('青蛙的幼体叫什么?') # >>> '蝌蚪'
Ariel.request('世界上最大的海洋是什么?') # >>> '太平洋'
Ariel.fetch_messages()
# 返回:
# [
# {'role': 'user', 'content': '英国的首都是什么?'}, # 被锁定的消息
# {'role': 'user', 'content': '意大利的首都是什么?'}, # 被锁定的消息
# {'role': 'assistant', 'content': '罗马'}, # 被锁定的消息
# {'role': 'user', 'content': '美国的首都是什么?'}, # 被锁定的消息
# {'role': 'user', 'content': '世界上最大的海洋是什么?'},
# {'role': 'assistant', 'content': '太平洋'}
# ]
```
注:pin_messages 方法也允许传入“已锁定的消息”的索引,这使得当不确定某些消息的状态时,可以放心地将它们的索引传进去。
### 解锁消息
可使用 unpin_messages 方法将已锁定的消息解除锁定。
```python
Ariel.unpin_messages(0, -2, -1) # 解锁索引为 0、-2、-1 的消息
```
注:unpin_messages 方法也允许传入“未锁定的消息”的索引,这使得当不确定某些消息的状态时,可以放心地将它们的索引传进去。
## 更多方法
1、`openai2.Chat` 底层调用了 `openai.OpenAI`,支持 `openai.OpenAI` 的所有参数。
2、`openai2.Chat.request` 与 `openai2.Chat.stream_request` 底层调用了 `openai.OpenAI.chat.completions.create`,支持 `openai.OpenAI.chat.completions.create` 的所有参数。
3、`openai2.Chat.async_request` 与 `openai2.Chat.async_stream_request` 底层调用了 `openai.AsyncOpenAI.chat.completions.create`,支持 `openai.AsyncOpenAI.chat.completions.create` 的所有参数。
[查看相关参数](https://platform.openai.com/docs/api-reference/chat) 👈
## 在命令行对话 ([查看演示](https://lcctoor.com/openai2/oa_/命令行对话演示.mp4) 👈)
```cpp
openai2 add_apikey sk-T92mZYXHLWKt1234gtPKT3BlbkFJ
openai2 chat
```
指令集
| 指令 | 功能 | 说明 |
| ---------------------------------- | ---------------------------- | ------------------------ |
| openai2 add_apikey 你的apikey | 添加 1 个 apikey | 如需添加多个,可执行多次 |
| openai2 read_apikey | 查看所有 apikey | |
| openai2 clear_apikey | 清除所有 apikey | |
| openai2 chat | 继续上次的对话 | |
| openai2 newchat | 清空对话记录, 然后开始新对话 | |
Raw data
{
"_id": null,
"home_page": null,
"name": "openai2",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "openai, chatgpt, openai2",
"author": null,
"author_email": "\u6c5f\u5357\u96e8\u4e0a <lcctoor@outlook.com>",
"download_url": "https://files.pythonhosted.org/packages/d8/21/c9d1da0df1275f1dd4e300738679879b7111a75535ed3d061d9edc71990d/openai2-1.7.12.tar.gz",
"platform": null,
"description": "# \u9879\u76ee\u63cf\u8ff0\n\nChatGPT \u5de5\u5177\u5305\uff0c\u652f\u6301\u591a\u6a21\u6001\u5bf9\u8bdd\uff08gpt-4o\uff09\u3001\u8fde\u7eed\u5bf9\u8bdd\u3001\u6d41\u5f0f\u5bf9\u8bdd\uff08\u9010\u5b57\u663e\u793a\uff09\u3001\u751f\u6210\u56fe\u50cf\uff08DALL\u00b7E\uff09\u3001\u5bf9\u8bdd\u5b58\u6863\u4e0e\u8f7d\u5165\u3001\u5bf9\u8bdd\u56de\u6eda\u3001\u5bf9\u8bdd\u4f2a\u9020\u3001\u8f6e\u8be2 api_key \u6c60\u3001\u7fa4\u804a\u591a\u89d2\u8272\u6a21\u62df\u3001\u5728\u547d\u4ee4\u884c\u5bf9\u8bdd\u3001\u9650\u5236\u5386\u53f2\u6d88\u606f\u6570\u91cf\u3001\u5f02\u6b65\u8bf7\u6c42\u3002\n\n# \u4f5c\u8005\n\n\u6c5f\u5357\u96e8\u4e0a\n\n[\u4e3b\u9875](https://lcctoor.com/index.html) \\| [Github](https://github.com/lcctoor) \\| [PyPi](https://pypi.org/user/lcctoor) \\| [\u5fae\u4fe1](https://lcctoor.com/cdn/WeChatQRC.jpg) \\| [\u90ae\u7bb1](mailto:lcctoor@outlook.com) \\| [\u6350\u8d60](https://lcctoor.com/cdn/DonationQRC-0rmb.jpg)\n\n# Bug\u63d0\u4ea4\u3001\u529f\u80fd\u63d0\u8bae\n\n\u4f60\u53ef\u4ee5\u901a\u8fc7 [Github-Issues](https://github.com/lcctoor/arts/issues)\u3001[\u5fae\u4fe1](https://lcctoor.com/cdn/WeChatQRC.jpg) \u4e0e\u6211\u8054\u7cfb\u3002\n\n# \u5b89\u88c5\n\n```\npip install openai2\n```\n\n# \u83b7\u53d6api_key\n\n[\u83b7\u53d6\u94fe\u63a51](https://platform.openai.com/account/api-keys)\n\n[\u83b7\u53d6\u94fe\u63a52](https://www.baidu.com/s?wd=%E8%8E%B7%E5%8F%96%20openai%20api_key)\n\n# \u6559\u7a0b ([\u67e5\u770b\u7f8e\u5316\u7248](https://github.com/lcctoor/arts/blob/main/arts/openai2/README.md#\u9879\u76ee\u63cf\u8ff0) \ud83d\udc48)\n\n## \u5bfc\u5165\n\n```python\nfrom openai2 import Chat\n```\n\n## \u521b\u5efa\u5bf9\u8bdd\n\n```python\napi_key = 'api_key' # \u66f4\u6362\u6210\u81ea\u5df1\u7684api_key\n\nTony = Chat(api_key=api_key, model=\"gpt-3.5-turbo\")\nLucy = Chat(api_key=api_key, model=\"gpt-3.5-turbo\") # \u6bcf\u4e2a\u5b9e\u4f8b\u53ef\u4f7f\u7528 \u76f8\u540c \u6216\u8005 \u4e0d\u540c \u7684api_key\n```\n\n## \u5bf9\u8bdd\n\n```python\nTony.request('\u81ea\u7136\u657050\u7684\u540e\u9762\u662f\u51e0?') # >>> '51'\nLucy.request('\u81ea\u7136\u6570100\u7684\u540e\u9762\u662f\u51e0?') # >>> '101'\n\nTony.request('\u518d\u5f80\u540e\u662f\u51e0?') # >>> '52'\nLucy.request('\u518d\u5f80\u540e\u662f\u51e0?') # >>> '102'\n\nTony.request('\u518d\u5f80\u540e\u5462?') # >>> '53'\nLucy.request('\u518d\u5f80\u540e\u5462?') # >>> '103'\n```\n\n## \u6d41\u5f0f\u5bf9\u8bdd ([\u67e5\u770b\u6f14\u793a](https://lcctoor.com/openai2/oa_/\u6d41\u5f0f\u5bf9\u8bdd\u6f14\u793a.mp4) \ud83d\udc48)\n\n```python\nfor answer in Lucy.stream_request('\u4e16\u754c\u4e0a\u6700\u5927\u7684\u6d77\u6d0b\u662f\u54ea\u4e2a?'):\n print(answer)\n\u4e16\n\u754c\n\u4e0a\n\u6700\n\u5927\n\u7684\n\u6d77\n\u6d0b\n\u662f\n\u592a\n\u5e73\n\u6d0b\n\u3002\n```\n\n## \u5f02\u6b65\u5bf9\u8bdd\n\n```python\nimport asyncio\nfrom openai2 import Chat\n\nTony = Chat(api_key=api_key, model=\"gpt-3.5-turbo\")\n\nasync def main():\n answer = await Tony.async_request('\u4e16\u754c\u4e0a\u6700\u5927\u7684\u6d77\u6d0b\u662f\u54ea\u4e2a')\n print(answer)\n\nasyncio.run(main()) # >>> '\u4e16\u754c\u4e0a\u6700\u5927\u7684\u6d77\u6d0b\u662f\u592a\u5e73\u6d0b\u3002'\n```\n\n## \u5f02\u6b65\u6d41\u5f0f\u5bf9\u8bdd\n\n```python\nasync for answer in Tony.async_stream_request('\u4e16\u754c\u4e0a\u6700\u5927\u7684\u6d77\u6d0b\u662f\u54ea\u4e2a?'):\n print(answer)\n\u4e16\n\u754c\n\u4e0a\n\u6700\n\u5927\n\u7684\n\u6d77\n\u6d0b\n\u662f\n\u592a\n\u5e73\n\u6d0b\n\u3002\n```\n\n## \u591a\u6a21\u6001\u5bf9\u8bdd\uff08gpt-4o\uff09\n\n```python\nfrom pathlib import Path\nfrom openai2 import Chat, Multimodal_Part\n\n\nBruce = Chat(api_key='sk-jg93...', model=\"gpt-4o\")\n\n\npic = Path(rf'C:\\\u9f20\u6807.jpeg').read_bytes()\n\nanswer = Bruce.request(\n\n '\u4e0b\u9762\u8fd9\u5f20\u56fe\u7247\u91cc\u753b\u4e86\u4ec0\u4e48\uff1f',\n \n Multimodal_Part.jpeg(pic)\n)\n\nprint(answer) # >>> '\u8fd9\u5f20\u56fe\u7247\u91cc\u753b\u4e86\u4e00\u4e2a\u9f20\u6807\u3002'\n```\n\n\u6ce8\uff1a\n\n1\u3001Multimodal_Part \u9664\u4e86 jpeg \u65b9\u6cd5\u4ee5\u5916\uff0c\u8fd8\u6709 png\u3001text \u2026\u2026 \u7b49\u65b9\u6cd5\u3002\n\n2\u3001\u5bf9\u4e8e str \u578b\u5bf9\u8c61\uff0c\u4ee5\u4e0b\u8fd9\u4e24\u79cd\u5199\u6cd5\u662f\u7b49\u4ef7\u7684\uff1a`Bruce.request(..., '\u8fd9\u5f20\u56fe\u7247\u91cc\u753b\u4e86\u4ec0\u4e48', ...)`\u3001`Bruce.request(..., Multimodal_Part.text('\u8fd9\u5f20\u56fe\u7247\u91cc\u753b\u4e86\u4ec0\u4e48'), ...)`\u3002\n\n3\u3001\u591a\u6a21\u6001\u5bf9\u8bdd\u652f\u6301\u540c\u6b65\u5bf9\u8bdd\u3001\u5f02\u6b65\u5bf9\u8bdd\u3001\u540c\u6b65\u6d41\u5f0f\u5bf9\u8bdd\u3001\u5f02\u6b65\u6d41\u5f0f\u5bf9\u8bdd\u2026\u2026 \u76f8\u5bf9\u4e8e\u666e\u901a\u5bf9\u8bdd\uff0c\u552f\u4e00\u7684\u533a\u522b\u5c31\u662f\u652f\u6301\u591a\u6a21\u6001\u3002\n\n4\u3001\u76ee\u524d\u5df2\u77e5\u652f\u6301\u591a\u6a21\u6001\u5bf9\u8bdd\u7684\u6a21\u578b\u6709\uff1agpt-4o\u3001gpt-4o-mini\u3001gpt-4o-2024-05-13\u3001gpt-4o-mini-2024-07-18\u3002\n\n## \u5bf9\u8bdd\u56de\u6eda\n\n```python\nAnna = Chat(api_key=api_key, model=\"gpt-3.5-turbo\")\n\nAnna.request('\u81ea\u7136\u65701\u7684\u540e\u9762\u662f\u51e0?') # >>> 2\nAnna.request('\u518d\u5f80\u540e\u662f\u51e0?') # >>> 3\nAnna.request('\u518d\u5f80\u540e\u5462?') # >>> 4\nAnna.request('\u518d\u5f80\u540e\u5462?') # >>> 5\nAnna.request('\u518d\u5f80\u540e\u5462?') # >>> 6\nAnna.request('\u518d\u5f80\u540e\u5462?') # >>> 7\nAnna.request('\u518d\u5f80\u540e\u5462?') # >>> 8\n\n# \u56de\u6eda1\u8f6e\u5bf9\u8bdd\nAnna.rollback() # >>> [user]:\u518d\u5f80\u540e\u5462? [assistant]:7\n\n# \u518d\u56de\u6eda3\u8f6e\u5bf9\u8bdd\nAnna.rollback(n=3) # >>> [user]:\u518d\u5f80\u540e\u5462? [assistant]:4\n\nAnna.request('\u518d\u5f80\u540e\u5462?') # >>> 5\n```\n\n\u6ce8\uff1a\n\n1\u3001\u6267\u884c `Anna.rollback(n=x)` \u53ef\u56de\u6eda x \u8f6e\u5bf9\u8bdd\u3002\n\n2\u3001`Anna.rollback()` \u76f8\u5f53\u4e8e `Anna.rollback(n=1)` \u3002\n\n## \u8f6e\u8be2 api_key \u6c60\n\n```python\nfrom openai2 import Chat, AKPool\n\nAK1 = 'sk-ug8w...'\nAK2 = AKPool(['sk-mf40...', 'sk-m6g7...', ...])\nAK3 = AKPool(['sk-affe...', 'sk-fam4...', ...])\n\nDuke = Chat(api_key=AK1, model=\"gpt-3.5-turbo\") # \u4ee4 Duke \u4f7f\u7528\u56fa\u5b9a\u7684 api_key\n\nCarl = Chat(api_key=AK2, model=\"gpt-3.5-turbo\") # \u4ee4 Carl \u548c Denny \u4f7f\u7528\u540c\u4e00\u4e2a'api_key\u6c60', \u7cfb\u7edf\u5c06\u81ea\u52a8\u5145\u5206\u5229\u7528\u6bcf\u4e2aapi_key\nDenny = Chat(api_key=AK2, model=\"gpt-3.5-turbo\")\n\nChris = Chat(api_key=AK3, model=\"gpt-3.5-turbo\") # \u4ee4 Chris \u4f7f\u7528\u72ec\u7acb\u7684'api_key\u6c60'\n```\n\n\u6ce8\uff1a\u5141\u8bb8\uff08\u800c\u975e\u4e0d\u5141\u8bb8\uff09\u540c\u4e00\u4e2a api_key \u6295\u653e\u5230\u4e0d\u540c\u7684 api_key \u6c60\u4e2d\uff0c\u4f46\u6bcf\u4e2a api_key \u6c60\u90fd\u662f\u72ec\u7acb\u8c03\u5ea6\uff0c\u4e0d\u4f1a\u4e92\u76f8\u901a\u4fe1\u3002\n\n## \u91cd\u7f6e api_key\n\n```python\nAK5 = 'sk-jg93...'\nAK6 = AKPool(['sk-vb7l...', 'sk-d3lv...'])\n...\n\nCarl.reset_api_key(AK5) # \u91cd\u7f6e api_key\nCarl.reset_api_key(AK6) # \u518d\u6b21\u91cd\u7f6e api_key\n...\n```\n\n## \u5bf9\u8bdd\u5bfc\u51fa\u4e0e\u5bfc\u5165\n\n### \u5bf9\u8bdd\u5bfc\u51fa\n\n```python\nAriel = Chat(api_key=api_key, model=\"gpt-3.5-turbo\")\n\nAriel.request('\u81ea\u7136\u65701\u7684\u540e\u9762\u662f\u51e0?') # >>> 2\nAriel.request('\u518d\u5f80\u540e\u662f\u51e0?') # >>> 3\n\nAriel.fetch_messages()\n# \u8fd4\u56de:\n# [\n# {'role': 'user', 'content': '\u81ea\u7136\u65701\u7684\u540e\u9762\u662f\u51e0?'},\n# {'role': 'assistant', 'content': '2'},\n# {'role': 'user', 'content': '\u518d\u5f80\u540e\u662f\u51e0?'},\n# {'role': 'assistant', 'content': '3'}\n# ]\n```\n\n### \u5bf9\u8bdd\u5b58\u6863\n\n\u4f60\u53ef\u4ee5\u628a\u5bfc\u51fa\u7684\u5bf9\u8bdd\u6301\u4e45\u5316\u4fdd\u5b58\uff1a\n\n```python\nimport json\nfrom pathlib import Path\n\nrecord = Ariel.fetch_messages()\nrecord = json.dumps(record, ensure_ascii=False)\nPath('record.json').write_text(record, encoding=\"utf8\")\n```\n\n### \u5bf9\u8bdd\u5bfc\u5165\n\n\u5bfc\u51fa\u7684\u5bf9\u8bdd\u53ef\u4ee5\u518d\u5bfc\u5165\u5230\u5176\u5b83\u5bf9\u8bdd\u4e2d\uff1a\n\n```python\nrecord = Ariel.fetch_messages()\n\nJenny = Chat(api_key=api_key, model=\"gpt-3.5-turbo\")\nJenny.add_dialogs(*record)\n\nJenny.request('\u518d\u5f80\u540e\u5462?') # >>> 4\n```\n\n\u5bfc\u51fa\u7684\u5bf9\u8bdd\u4e5f\u53ef\u4ee5\u518d\u5bfc\u5165\u5230\u539f\u5bf9\u8bdd\u4e2d\uff0c\u4f46\u8fd9\u6837\u505a\u4f1a\u5728\u539f\u5bf9\u8bdd\u4e2d\u4ea7\u751f\u91cd\u590d\u7684\u5386\u53f2\u6d88\u606f\u3002\n\n### \u5bf9\u8bdd\u4f2a\u9020\n\n\u5229\u7528\u5bf9\u8bdd\u5bfc\u5165\u529f\u80fd\uff0c\u53ef\u4ee5\u4f2a\u9020\u5bf9\u8bdd\uff1a\n\n```python\nfrom openai2 import Chat, user_msg, assistant_msg\n\nMickey = Chat(api_key=api_key, model=\"gpt-3.5-turbo\")\n\nMickey.add_dialogs(\n user_msg('\u8bf7\u95ee1+1=\u51e0?'), # \u7b49\u4ef7\u4e8e {\"role\": \"user\", \"content\": '\u8bf7\u95ee1+1=\u51e0?'}\n assistant_msg('1+1=10'), # \u7b49\u4ef7\u4e8e {\"role\": \"assistant\", \"content\": '1+1=10'}\n {\"role\": \"user\", \"content\": '\u90a310+10=\u51e0?'},\n {\"role\": \"assistant\", \"content\": '10+10=\u4f60\u5927\u7237, \u4f60\u63d0\u7684\u8fd9\u4e9b\u95ee\u9898\u771f\u5f31\u667a!'},\n)\n\nanswer = Mickey.request('\u54e6\u543c, \u4f60\u8fd8\u6562\u9a82\u6211\u5440?')\nprint(answer) # >>> \u975e\u5e38\u62b1\u6b49\uff0c\u6211\u521a\u624d\u7684\u56de\u7b54\u6709\u4e9b\u4e0d\u9002\u5f53\u30021+1=2, 10+10=20\u3002\u975e\u5e38\u62b1\u6b49\u7ed9\u4f60\u5e26\u6765\u56f0\u6270\uff01\n```\n\n\u6ce8\uff1a\u5bf9\u8bdd\u5bfc\u51fa\u4e0e\u5bfc\u5165\u53ef\u4ee5\u7a7f\u63d2\u5728\u5bf9\u8bdd\u4e2d\u7684\u4efb\u4f55\u65f6\u523b\u3002\n\n## \u751f\u6210\u56fe\u50cf\uff08DALL\u00b7E\uff09\n\n\u8fd4\u56de\u56fe\u7247\u7684\u4e8c\u8fdb\u5236\uff1a\n\n```python\nfrom pathlib import Path\nfrom openai2 import Chat\n\nTony = Chat(api_key='sk-jg93...', model=\"dall-e-2\")\n\nimages = Tony.dalle('\u8bf7\u753b\u4e00\u53ea\u732b', image_count=2)\n\nfor i, x in enumerate(images):\n Path(f\"\u7b2c{i}\u5f20.png\").write_bytes(x)\n```\n\n\u8fd4\u56de\u56fe\u7247\u7684URL\uff1a\n\n```python\nfrom pathlib import Path\nfrom openai2 import Chat\n\nTony = Chat(api_key='sk-jg93...', model=\"dall-e-2\")\n\nimages = Tony.dalle('\u8bf7\u753b\u4e00\u53ea\u732b', image_count=2, return_format='url')\n\nfor i, url in enumerate(images):\n print(f\"\u7b2c{i}\u5f20\u7684URL\u662f\uff1a\", url)\n```\n\n## \u5f02\u6b65\u751f\u6210\u56fe\u50cf\uff08DALL\u00b7E\uff09\n\n\u8fd4\u56de\u56fe\u7247\u7684\u4e8c\u8fdb\u5236\uff1a\n\n```python\nimport asyncio\nfrom pathlib import Path\nfrom openai2 import Chat\n\nasync def main():\n Tony = Chat(api_key='sk-jg93...', model=\"dall-e-2\")\n\n images = await Tony.async_dalle('\u8bf7\u753b\u4e00\u53ea\u732b', image_count=2)\n \n for i, x in enumerate(images):\n Path(f\"\u7b2c{i}\u5f20.png\").write_bytes(x)\n\nasyncio.run(main())\n```\n\n\u8fd4\u56de\u56fe\u7247\u7684URL\uff1a\n\n```python\nimport asyncio\nfrom pathlib import Path\nfrom openai2 import Chat\n\nasync def main():\n Tony = Chat(api_key='sk-jg93...', model=\"dall-e-2\")\n\n images = await Tony.async_dalle('\u8bf7\u753b\u4e00\u53ea\u732b', image_count=2, return_format='url')\n \n for i, url in enumerate(images):\n print(f\"\u7b2c{i}\u5f20\u7684URL\u662f\uff1a\", url)\n\nasyncio.run(main())\n```\n\n## \u7fa4\u804a\u591a\u89d2\u8272\u6a21\u62df\n\n```python\nimport json\nfrom openai2 import GroupChat\n\napi_key = '...' # \u66f4\u6362\u6210\u81ea\u5df1\u7684 api_key\ngroup = GroupChat(api_key=api_key, model=\"gpt-3.5-turbo\")\n\n# \u8bbe\u7f6e\u89d2\u8272\ngroup.roles['\u82cf\u8f7c'] = '\u5b8b\u671d\u8bd7\u4eba\uff0c\u4ed6\u7684\u8bcd\u98ce\u683c\u72ec\u7279\uff0c\u65e2\u6709\u5112\u5bb6\u7684\u6559\u8bf2\uff0c\u53c8\u6709\u751f\u6d3b\u7684\u4e50\u8da3\u3002'\ngroup.roles['\u674e\u6e05\u7167'] = '\u5b8b\u4ee3\u8457\u540d\u7684\u5973\u8bcd\u4eba\uff0c\u5176\u8bcd\u53e5\u4f18\u7f8e\uff0c\u60c5\u611f\u771f\u631a\u3002'\ngroup.roles['\u675c\u752b'] = '\u5510\u671d\u8457\u540d\u8bd7\u4eba\u3002'\n\n# \u6dfb\u52a0\u89d2\u8272\u5386\u53f2\u5bf9\u8bdd\ngroup.add_dialog(speaker='\u82cf\u8f7c', audiences=['\u674e\u6e05\u7167'], remark='\u4f60\u597d\u5440')\ngroup.add_dialog(speaker='\u674e\u6e05\u7167', audiences=['\u82cf\u8f7c'], remark='\u597d\u4e45\u4e0d\u89c1, \u4f60\u6700\u8fd1\u5728\u5fd9\u4ec0\u4e48?')\ngroup.add_dialog(speaker='\u675c\u752b', audiences=['\u82cf\u8f7c'], remark='\u4e0a\u6b21\u6258\u4f60\u5e2e\u6211\u5199\u7684\u90a3\u9996\u300a\u8305\u5c4b\u4e3a\u79cb\u98ce\u6240\u7834\u6b4c\u300b\u5199\u597d\u4e86\u5417?')\n\n# \u8ba9 ChatGPT \u6a21\u62df\u89d2\u8272\u53d1\u8a00\nanswer = group.request([\n ('\u82cf\u8f7c', ['\u674e\u6e05\u7167']), # \u7b2c 1 \u4e2a\u5143\u7d20\u8868\u793a\u8bf4\u8bdd\u4eba, \u7b2c 2 \u4e2a\u5143\u7d20\u8868\u793a\u5bf9\u8c01\u8bf4\u8bdd. \u7531\u4e8e\u4e00\u4e2a\u4eba\u53ef\u4ee5\u540c\u65f6\u5bf9\u591a\u4e2a\u4eba\u8bf4\u8bdd, \u56e0\u6b64\u7b2c 2 \u4e2a\u5143\u7d20\u4e3a\u5217\u8868\n ('\u82cf\u8f7c', ['\u675c\u752b']),\n])\n\ntry:\n print( json.loads(answer) )\nexcept:\n print(answer)\n\n# \u8fd4\u56de:\n[\n {\n \"speaker\": \"\u82cf\u8f7c\",\n \"audiences\": \"\u674e\u6e05\u7167\",\n \"remark\": \"\u6700\u8fd1\u6211\u5728\u5199\u4e00\u9996\u65b0\u7684\u8bd7\uff0c\u9898\u76ee\u662f\u300a\u542c\u96e8\u300b\"\n },\n {\n \"speaker\": \"\u82cf\u8f7c\",\n \"audiences\": \"\u675c\u752b\",\n \"remark\": \"\u90a3\u9996\u300a\u8305\u5c4b\u4e3a\u79cb\u98ce\u6240\u7834\u6b4c\u300b\u5df2\u7ecf\u5199\u597d\u5566\uff0c\u6211\u5728\u4fe1\u91cc\u5bc4\u7ed9\u4f60\u4e86\uff0c\u8bf7\u67e5\u6536\"\n }\n]\n```\n\n## \u9650\u5236\u5386\u53f2\u6d88\u606f\u6570\u91cf\n\n### \u9650\u5236\u5386\u53f2\u6d88\u606f\u6570\u91cf\n\n\u968f\u7740\u5bf9\u8bdd\u6b21\u6570\u8d8a\u6765\u8d8a\u591a\uff0c\u6700\u7ec8\u4e0a\u4e0b\u6587\u957f\u5ea6\u5c31\u4f1a\u8d85\u51fa openai \u63a5\u53e3\u9650\u5b9a\u7684\u6700\u5927 token \u6570\u91cf\uff0c\u6b64\u65f6\u53ef\u4f7f\u7528 msg_max_count \u53c2\u6570\u6765\u9650\u5236\u5386\u53f2\u6d88\u606f\u6570\u91cf\u3002\u5f53\u6d88\u606f\u6570\u91cf\u8d85\u51fa msg_max_count \u540e\uff0c\u7a0b\u5e8f\u4f1a\u81ea\u52a8\u79fb\u9664\u6700\u65e9\u7684\u8bb0\u5f55\uff0c\u4f7f\u6d88\u606f\u6570\u91cf\u51cf\u5c11\u5230\u6070\u597d\u7b49\u4e8e msg_max_count \u3002\n\n```python\nmsg_max_count = 6 # \u6700\u591a\u4fdd\u75596\u6761\u5386\u53f2\u6d88\u606f\n\nAriel = Chat(api_key=api_key, model=\"gpt-3.5-turbo\", msg_max_count=msg_max_count)\n\nAriel.request('\u82f1\u56fd\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f') # >>> '\u4f26\u6566'\nAriel.request('\u65e5\u672c\u9996\u90fd\u662f\u4ec0\u4e48\uff1f') # >>> '\u4e1c\u4eac'\nAriel.request('\u610f\u5927\u5229\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f') # >>> '\u7f57\u9a6c'\nAriel.request('\u7f8e\u56fd\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f') # >>> '\u534e\u76db\u987f'\nAriel.request('\u4e16\u754c\u4e0a\u56fd\u571f\u9762\u79ef\u6700\u5927\u7684\u56fd\u5bb6\u662f\u54ea\u4e2a\uff1f') # >>> '\u4fc4\u7f57\u65af'\nAriel.request('\u6cd5\u56fd\u7684\u9996\u90fd\u53eb\u4ec0\u4e48\uff1f') # >>> '\u5df4\u9ece'\nAriel.request('\u9752\u86d9\u7684\u5e7c\u4f53\u53eb\u4ec0\u4e48\uff1f') # >>> '\u874c\u86aa'\nAriel.request('\u4e16\u754c\u4e0a\u6700\u5927\u7684\u6d77\u6d0b\u662f\u4ec0\u4e48\uff1f') # >>> '\u592a\u5e73\u6d0b'\n\nAriel.fetch_messages()\n\n# \u8fd4\u56de:\n# [\n# {'role': 'user', 'content': '\u6cd5\u56fd\u7684\u9996\u90fd\u53eb\u4ec0\u4e48\uff1f'},\n# {'role': 'assistant', 'content': '\u5df4\u9ece'},\n# {'role': 'user', 'content': '\u9752\u86d9\u7684\u5e7c\u4f53\u53eb\u4ec0\u4e48\uff1f'},\n# {'role': 'assistant', 'content': '\u874c\u86aa'},\n# {'role': 'user', 'content': '\u4e16\u754c\u4e0a\u6700\u5927\u7684\u6d77\u6d0b\u662f\u4ec0\u4e48\uff1f'},\n# {'role': 'assistant', 'content': '\u592a\u5e73\u6d0b'}\n# ]\n```\n\n### \u9501\u5b9a\u6d88\u606f\n\n\u5f53\u7a0b\u5e8f\u81ea\u52a8\u79fb\u9664\u6d88\u606f\u8bb0\u5f55\u65f6\uff0c\u4e5f\u8bb8\u6211\u4eec\u5e0c\u671b\u67d0\u4e9b\u6d88\u606f\u4e0d\u8981\u88ab\u79fb\u9664\uff0c\u6b64\u65f6\u53ef\u5c06\u8fd9\u4e9b\u6d88\u606f\u9501\u5b9a\u3002\n\n```python\nmsg_max_count = 6\n\nAriel = Chat(api_key=api_key, model=\"gpt-3.5-turbo\", msg_max_count=msg_max_count)\n\nAriel.request('\u82f1\u56fd\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f') # >>> '\u4f26\u6566'\nAriel.request('\u65e5\u672c\u9996\u90fd\u662f\u4ec0\u4e48\uff1f') # >>> '\u4e1c\u4eac'\nAriel.request('\u610f\u5927\u5229\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f') # >>> '\u7f57\u9a6c'\n```\n\n\u6b64\u65f6\u5171\u6709 6 \u6761\u6d88\u606f\u8bb0\u5f55\uff1a\n\n| \u6d88\u606f | \u6b63\u5e8f\u7d22\u5f15 | \u9006\u5e8f\u7d22\u5f15 |\n| -------------------- | :------: | :------: |\n| \u82f1\u56fd\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f | 0 | -6 |\n| \u4f26\u6566 | 1 | -5 |\n| \u65e5\u672c\u9996\u90fd\u662f\u4ec0\u4e48\uff1f | 2 | -4 |\n| \u4e1c\u4eac | 3 | -3 |\n| \u610f\u5927\u5229\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f | 4 | -2 |\n| \u7f57\u9a6c | 5 | -1 |\n\n\u9501\u5b9a\u7d22\u5f15\u4e3a 0\u3001-2\u3001-1 \u7684\u6d88\u606f\uff1a\n\n```python\nAriel.pin_messages(0, -2, -1) # \u7d22\u5f15\u65e0\u987b\u6309\u987a\u5e8f\u586b\u5199: pin_messages(0, 1, 2) \u4e0e pin_messages(0, 2, 1) \u7b49\u4ef7.\n```\n\n\u7ee7\u7eed\u8bf7\u6c42\uff1a\n\n```python\nAriel.request('\u7f8e\u56fd\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f') # >>> '\u534e\u76db\u987f'\n```\n\n\u7531\u4e8e\u8bbe\u7f6e\u4e86 msg_max_count = 6\uff0c\u6b64\u65f6\u5171\u6709 6 \u6761\u6d88\u606f\u8bb0\u5f55\uff1a\n\n| \u6d88\u606f | \u6b63\u5e8f\u7d22\u5f15 | \u9006\u5e8f\u7d22\u5f15 | \u9501\u5b9a\u72b6\u6001 |\n| -------------------- | :------: | :------: | :------: |\n| \u82f1\u56fd\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f | 0 | -6 | \u5df2\u9501\u5b9a |\n| \u4e1c\u4eac | 1 | -5 | - |\n| \u610f\u5927\u5229\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f | 2 | -4 | \u5df2\u9501\u5b9a |\n| \u7f57\u9a6c | 3 | -3 | \u5df2\u9501\u5b9a |\n| \u7f8e\u56fd\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f | 4 | -2 | - |\n| \u534e\u76db\u987f | 5 | -1 | - |\n\n\u7ee7\u7eed\u6267\u884c\uff1a\n\n```python\nAriel.pin_messages(-2) # \u9501\u5b9a'\u7f8e\u56fd\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f'\n\nAriel.request('\u4e16\u754c\u4e0a\u56fd\u571f\u9762\u79ef\u6700\u5927\u7684\u56fd\u5bb6\u662f\u54ea\u4e2a\uff1f') # >>> '\u4fc4\u7f57\u65af'\nAriel.request('\u6cd5\u56fd\u7684\u9996\u90fd\u53eb\u4ec0\u4e48\uff1f') # >>> '\u5df4\u9ece'\nAriel.request('\u9752\u86d9\u7684\u5e7c\u4f53\u53eb\u4ec0\u4e48\uff1f') # >>> '\u874c\u86aa'\nAriel.request('\u4e16\u754c\u4e0a\u6700\u5927\u7684\u6d77\u6d0b\u662f\u4ec0\u4e48\uff1f') # >>> '\u592a\u5e73\u6d0b'\n\nAriel.fetch_messages()\n\n# \u8fd4\u56de:\n# [\n# {'role': 'user', 'content': '\u82f1\u56fd\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f'}, # \u88ab\u9501\u5b9a\u7684\u6d88\u606f\n# {'role': 'user', 'content': '\u610f\u5927\u5229\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f'}, # \u88ab\u9501\u5b9a\u7684\u6d88\u606f\n# {'role': 'assistant', 'content': '\u7f57\u9a6c'}, # \u88ab\u9501\u5b9a\u7684\u6d88\u606f\n# {'role': 'user', 'content': '\u7f8e\u56fd\u7684\u9996\u90fd\u662f\u4ec0\u4e48\uff1f'}, # \u88ab\u9501\u5b9a\u7684\u6d88\u606f\n# {'role': 'user', 'content': '\u4e16\u754c\u4e0a\u6700\u5927\u7684\u6d77\u6d0b\u662f\u4ec0\u4e48\uff1f'},\n# {'role': 'assistant', 'content': '\u592a\u5e73\u6d0b'}\n# ]\n```\n\n\u6ce8\uff1apin_messages \u65b9\u6cd5\u4e5f\u5141\u8bb8\u4f20\u5165\u201c\u5df2\u9501\u5b9a\u7684\u6d88\u606f\u201d\u7684\u7d22\u5f15\uff0c\u8fd9\u4f7f\u5f97\u5f53\u4e0d\u786e\u5b9a\u67d0\u4e9b\u6d88\u606f\u7684\u72b6\u6001\u65f6\uff0c\u53ef\u4ee5\u653e\u5fc3\u5730\u5c06\u5b83\u4eec\u7684\u7d22\u5f15\u4f20\u8fdb\u53bb\u3002\n\n### \u89e3\u9501\u6d88\u606f\n\n\u53ef\u4f7f\u7528 unpin_messages \u65b9\u6cd5\u5c06\u5df2\u9501\u5b9a\u7684\u6d88\u606f\u89e3\u9664\u9501\u5b9a\u3002\n\n```python\nAriel.unpin_messages(0, -2, -1) # \u89e3\u9501\u7d22\u5f15\u4e3a 0\u3001-2\u3001-1 \u7684\u6d88\u606f\n```\n\n\u6ce8\uff1aunpin_messages \u65b9\u6cd5\u4e5f\u5141\u8bb8\u4f20\u5165\u201c\u672a\u9501\u5b9a\u7684\u6d88\u606f\u201d\u7684\u7d22\u5f15\uff0c\u8fd9\u4f7f\u5f97\u5f53\u4e0d\u786e\u5b9a\u67d0\u4e9b\u6d88\u606f\u7684\u72b6\u6001\u65f6\uff0c\u53ef\u4ee5\u653e\u5fc3\u5730\u5c06\u5b83\u4eec\u7684\u7d22\u5f15\u4f20\u8fdb\u53bb\u3002\n\n## \u66f4\u591a\u65b9\u6cd5\n\n1\u3001`openai2.Chat` \u5e95\u5c42\u8c03\u7528\u4e86 `openai.OpenAI`\uff0c\u652f\u6301 `openai.OpenAI` \u7684\u6240\u6709\u53c2\u6570\u3002\n\n2\u3001`openai2.Chat.request` \u4e0e `openai2.Chat.stream_request` \u5e95\u5c42\u8c03\u7528\u4e86 `openai.OpenAI.chat.completions.create`\uff0c\u652f\u6301 `openai.OpenAI.chat.completions.create` \u7684\u6240\u6709\u53c2\u6570\u3002\n\n3\u3001`openai2.Chat.async_request` \u4e0e `openai2.Chat.async_stream_request` \u5e95\u5c42\u8c03\u7528\u4e86 `openai.AsyncOpenAI.chat.completions.create`\uff0c\u652f\u6301 `openai.AsyncOpenAI.chat.completions.create` \u7684\u6240\u6709\u53c2\u6570\u3002\n\n[\u67e5\u770b\u76f8\u5173\u53c2\u6570](https://platform.openai.com/docs/api-reference/chat) \ud83d\udc48\n\n## \u5728\u547d\u4ee4\u884c\u5bf9\u8bdd ([\u67e5\u770b\u6f14\u793a](https://lcctoor.com/openai2/oa_/\u547d\u4ee4\u884c\u5bf9\u8bdd\u6f14\u793a.mp4) \ud83d\udc48)\n\n```cpp\nopenai2 add_apikey sk-T92mZYXHLWKt1234gtPKT3BlbkFJ\nopenai2 chat\n```\n\n\u6307\u4ee4\u96c6\n\n| \u6307\u4ee4 | \u529f\u80fd | \u8bf4\u660e |\n| ---------------------------------- | ---------------------------- | ------------------------ |\n| openai2\u00a0\u00a0add_apikey\u00a0 \u4f60\u7684apikey | \u6dfb\u52a0 1 \u4e2a apikey | \u5982\u9700\u6dfb\u52a0\u591a\u4e2a\uff0c\u53ef\u6267\u884c\u591a\u6b21 |\n| openai2\u00a0 read_apikey | \u67e5\u770b\u6240\u6709 apikey | |\n| openai2\u00a0 clear_apikey | \u6e05\u9664\u6240\u6709 apikey | |\n| openai2\u00a0 chat | \u7ee7\u7eed\u4e0a\u6b21\u7684\u5bf9\u8bdd | |\n| openai2\u00a0 newchat | \u6e05\u7a7a\u5bf9\u8bdd\u8bb0\u5f55, \u7136\u540e\u5f00\u59cb\u65b0\u5bf9\u8bdd | |\n",
"bugtrack_url": null,
"license": null,
"summary": "ChatGPT \u5de5\u5177\u5305\uff0c\u652f\u6301\u591a\u6a21\u6001\u5bf9\u8bdd\uff08gpt-4o\uff09\u3001\u8fde\u7eed\u5bf9\u8bdd\u3001\u6d41\u5f0f\u5bf9\u8bdd\uff08\u9010\u5b57\u663e\u793a\uff09\u3001\u751f\u6210\u56fe\u50cf\uff08DALL\u00b7E\uff09\u3001\u5bf9\u8bdd\u5b58\u6863\u4e0e\u8f7d\u5165\u3001\u5bf9\u8bdd\u56de\u6eda\u3001\u5bf9\u8bdd\u4f2a\u9020\u3001\u8f6e\u8be2 api_key \u6c60\u3001\u7fa4\u804a\u591a\u89d2\u8272\u6a21\u62df\u3001\u5728\u547d\u4ee4\u884c\u5bf9\u8bdd\u3001\u9650\u5236\u5386\u53f2\u6d88\u606f\u6570\u91cf\u3001\u5f02\u6b65\u8bf7\u6c42\u3002",
"version": "1.7.12",
"project_urls": {
"Source": "https://github.com/lcctoor/arts/tree/main/arts/openai2"
},
"split_keywords": [
"openai",
" chatgpt",
" openai2"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "bfb90b523d196bdb51567fd3ea598ba9f867c38b670d07574d5d17d91394cd6e",
"md5": "1cf4f10ea0131f912ecff4e4d2d18c8a",
"sha256": "04bb836b93a008eea128fc922b071789cc56d21ec085c8ef602e7c8fab74d9e9"
},
"downloads": -1,
"filename": "openai2-1.7.12-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "1cf4f10ea0131f912ecff4e4d2d18c8a",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 10446,
"upload_time": "2024-09-14T02:06:41",
"upload_time_iso_8601": "2024-09-14T02:06:41.384607Z",
"url": "https://files.pythonhosted.org/packages/bf/b9/0b523d196bdb51567fd3ea598ba9f867c38b670d07574d5d17d91394cd6e/openai2-1.7.12-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "d821c9d1da0df1275f1dd4e300738679879b7111a75535ed3d061d9edc71990d",
"md5": "bbaff2b90db0c27d64deaab168747850",
"sha256": "4551de8b50ac579937500e3e0e0c6f0bcb79c8950032c3a3269da6a6cc82f1b9"
},
"downloads": -1,
"filename": "openai2-1.7.12.tar.gz",
"has_sig": false,
"md5_digest": "bbaff2b90db0c27d64deaab168747850",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 20893,
"upload_time": "2024-09-14T02:06:44",
"upload_time_iso_8601": "2024-09-14T02:06:44.511049Z",
"url": "https://files.pythonhosted.org/packages/d8/21/c9d1da0df1275f1dd4e300738679879b7111a75535ed3d061d9edc71990d/openai2-1.7.12.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-14 02:06:44",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "lcctoor",
"github_project": "arts",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "openai2"
}