用Python来实现,咱先用官方的openai库来实现
效果
说明
我这里用的openai的库版本是0.28.0,你可以通过命令安装pip install openai==0.28.0
代码
import openai
# 设置你的 API 密钥
openai.api_key = ''
# 修改 API 的 base URL
openai.api_base = ''
# 定义聊天功能,保持上下文
def chat_with_gpt(messages):
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=messages, # 传递整个对话历史
max_tokens=150, # 控制返回的最大字符数
temperature=0.7 # 调整回答的创造性
)
return response['choices'][0]['message']['content']
if __name__ == "__main__":
print("开始与 GPT-4o mini 互动,输入 'exit' 退出")
# 初始化对话历史
messages = [{"role": "system", "content": "You are a helpful assistant."}]
while True:
user_input = input("你: ")
if user_input.lower() == "exit":
break
# 将用户输入加入对话历史
messages.append({"role": "user", "content": user_input})
# 获取 GPT 的回复
response = chat_with_gpt(messages)
print(f"GPT: {response}")
# 将 GPT 的回复加入对话历史
messages.append({"role": "assistant", "content": response})
首先我们来理解一下参数哈
model 用来指定模型名称的
messages 用来传递整个对话上下文的,也就是说聊天历史
max_tokens 控制GPT回复时最大的字符数,按理说是限定token数,我对token的数还不是很理解,后面补一补尽量弄懂它
temperature 看起来这个值是来指定GPT自我发挥的概率的~越大自由发挥越大?暂时不是很理解,那我们问一下claude
也就是说,temperature(温度)这个值最大是2,越大GPT输出就越多样化类似于”头脑风暴“一样,而0.7看起来是一个比较稳定且居中的值~太深奥的原理我就先不挖了~
拆解一下数据格式吧!
下面是我刚刚和它的一些对话,我把messages
数组打印了出来,这里会有一个问题,我说我要”三步速成“我居然还打错字了!打成散步速成了,笑死,但是问题不在这里,而是在它的回答,说话到一半就没了,我还以为怎么了呢,想了一下,我觉得max_tokens
给的太少了,只给了150,这样还是不够直观,我改下代码重新跑一下
OK我把max_tokens
改到了1000,然后重新跑了,把对话贴在下面了
开始与 GPT-4o mini 互动,输入 'exit' 退出
你: 你好呀GPT
messages===>: [{'role': 'system', 'content': 'You are a helpful assistant.'}, {'role': 'user', 'content': '你好呀GPT'}]
response===>: {
"id": "chatcmpl-89D1bsACi3mm1eQofzau41ubWFyFZ",
"object": "chat.completion",
"created": 1728824619,
"model": "gpt-4o-mini",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "\u4f60\u597d\uff01\u6709\u4ec0\u4e48\u6211\u53ef\u4ee5\u5e2e\u52a9\u4f60\u7684\u5417\uff1f"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 16,
"completion_tokens": 9,
"total_tokens": 25
}
}
GPT: 你好!有什么我可以帮助你的吗?
你: 我想吃蛋炒饭了
messages===>: [{'role': 'system', 'content': 'You are a helpful assistant.'}, {'role': 'user', 'content': '你好呀GPT'}, {'role': 'assistant', 'content': '
你好!有什么我可以帮助你的吗?'}, {'role': 'user', 'content': '我想吃蛋炒饭了'}]
response===>: {
"id": "chatcmpl-89Df1Uj2e3vTtgyx3RBtl1dCVIMpf",
"object": "chat.completion",
"created": 1728824635,
"model": "gpt-4o-mini",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "\u86cb\u7092\u996d\u662f\u4e00\u9053\u7b80\u5355\u53c8\u7f8e\u5473\u7684\u5bb6\u5e38\u83dc\uff01\u4f60\u9700\u8981\u7684\u6750\u6599\u5f88\u7b80\u5355\uff0c\u901a\u5e38\u5305\u62ec\uff1a\n\n- \u7c73\u996d\uff08\u6700\u597d\u662f\u9694\u591c\u996d\uff09\n- \u9e21\u86cb\n- \u9752\u8471\uff08\u53ef\u9009\uff09\n- \u80e1\u841d\u535c\uff08\u53ef\u9009\uff0c\u5207\u4e01\uff09\n- \u8c4c\u8c46\uff08\u53ef\u9009\uff09\n- \u76d0\n- \u9171\u6cb9\n- \u80e1\u6912\u7c89\n- \u98df\u7528\u6cb9\n\n### \u505a\u6cd5\uff1a\n\n1. **\u51c6\u5907\u6750\u6599**\uff1a\u5982\u679c\u4f7f\u7528\u65b0\u9c9c\u7c73\u996d\uff0c\u6700\u597d\u5148\u667e\u51c9\u3002\u9e21\u86cb\u6253\u6563\uff0c\u9752\u8471\u5207\u788e\u3002\n\n2. **\u7092\u9e21\u86cb**\uff1a\u5728\u9505\u4e2d\u52a0\u4e00\u4e9b\u6cb9\uff0c\u52a0\u70ed\u540e\u5012\u5165\u6253\u6563\u7684\u9e21\u86cb\uff0c\u8fc5\u901f\u7092\u5300\uff0c\u7092\u81f3\u521a\u521a\u719f\u900f\u540e\u76db\u51fa\u5907\u7528\u3002\n\n3. **\u7092\u7c73\u996d**\uff1a\u5728\u9505\u4e2d\u518d\u52a0\u4e00\u4e9b\u6cb9\uff0c\u653e\u5165\u7c73\u996d\uff0c\u5feb\u901f\u7ffb\u7092\uff0c\u786e\u4fdd\u7c73\u996d\u9897\u7c92\u5206\u5f00\u3002\n\n4. **\u52a0\u5165\u852c\u83dc**\uff1a\u5982\u679c\u4f60\u6709\u80e1\u841d\u535c\u4e01\u548c\u8c4c\u8c46\uff0c\u53ef\u4ee5\u5728\u8fd9\u65f6\u52a0\u5165\uff0c\u7ffb\u7092\u5747\u5300\u3002\n\n5. **\u8c03\u5473**\uff1a\u52a0\u5165\u76d0\u3001\u9171\u6cb9\u548c\u80e1\u6912\u7c89\uff0c\u7ee7\u7eed\u7ffb\u7092\uff0c\u786e\u4fdd\u5747\u5300\u5165\u5473\u3002\n\n6. **\u52a0\u5165\u9e21\u86cb**\uff1a\u6700\u540e\uff0c\u628a\u4e4b\u524d\u7092\u597d\u7684\u9e21\u86cb\u548c\u9752\u8471\u52a0\u5165\u9505\u4e2d\uff0c\u7ffb\u7092\u5747\u5300\u540e\u5373\u53ef\u51fa\u9505\u3002\n\n### \u5c0f\u8d34\u58eb\uff1a\n- \u4f7f\u7528\u9694\u591c\u996d\u53e3\u611f\u66f4\u4f73\uff0c\u56e0\u4e3a\u6c34\u5206\u66f4\u5c11\uff0c\u7092\u51fa\u6765\u7684\u7c73\u996d\u4e0d\u5bb9\u6613\u7c98\u5728\u4e00\u8d77\u3002\n- \u53ef\u4ee5\u6839\u636e\u81ea\u5df1\u7684\u53e3\u5473\u52a0\u5165\u5176\u4ed6\u914d\u6599\uff0c\u6bd4\u5982\u706b\u817f\u3001\u867e\u4ec1\u7b49\u3002\n\n\u5e0c\u671b\u4f60\u80fd\u505a\u51fa\u7f8e\u5473\u7684\u86cb\u7092\u996d\uff01\u5982\u679c\u8fd8\u6709\u5176\u4ed6\u95ee\u9898\u6216\u9700\u8981\u66f4\u591a\u7684\u98df\u8c31\uff0c\u968f\u65f6\u544a\u8bc9\u6211\uff01"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 32,
"completion_tokens": 371,
"total_tokens": 403
}
}
GPT: 蛋炒饭是一道简单又美味的家常菜!你需要的材料很简单,通常包括:
- 米饭(最好是隔夜饭)
- 鸡蛋
- 青葱(可选)
- 胡萝卜(可选,切丁)
- 豌豆(可选)
- 盐
- 酱油
- 胡椒粉
- 食用油
### 做法:
1. **准备材料**:如果使用新鲜米饭,最好先晾凉。鸡蛋打散,青葱切碎。
2. **炒鸡蛋**:在锅中加一些油,加热后倒入打散的鸡蛋,迅速炒匀,炒至刚刚熟透后盛出备用。
3. **炒米饭**:在锅中再加一些油,放入米饭,快速翻炒,确保米饭颗粒分开。
4. **加入蔬菜**:如果你有胡萝卜丁和豌豆,可以在这时加入,翻炒均匀。
5. **调味**:加入盐、酱油和胡椒粉,继续翻炒,确保均匀入味。
6. **加入鸡蛋**:最后,把之前炒好的鸡蛋和青葱加入锅中,翻炒均匀后即可出锅。
### 小贴士:
- 使用隔夜饭口感更佳,因为水分更少,炒出来的米饭不容易粘在一起。
- 可以根据自己的口味加入其他配料,比如火腿、虾仁等。
希望你能做出美味的蛋炒饭!如果还有其他问题或需要更多的食谱,随时告诉我!
你: 能不能三步速成?
messages===>: [{'role': 'system', 'content': 'You are a helpful assistant.'}, {'role': 'user', 'content': '你好呀GPT'}, {'role': 'assistant', 'content': '
你好!有什么我可以帮助你的吗?'}, {'role': 'user', 'content': '我想吃蛋炒饭了'}, {'role': 'assistant', 'content': '蛋炒饭是一道简单又美味的家常菜!你需要的
材料很简单,通常包括:\n\n- 米饭(最好是隔夜饭)\n- 鸡蛋\n- 青葱(可选)\n- 胡萝卜(可选,切丁)\n- 豌豆(可选)\n- 盐\n- 酱油\n- 胡椒粉\n- 食用油\n\n### 做
法:\n\n1. **准备材料**:如果使用新鲜米饭,最好先晾凉。鸡蛋打散,青葱切碎。\n\n2. **炒鸡蛋**:在锅中加一些油,加热后倒入打散的鸡蛋,迅速炒匀,炒至刚刚熟透后
盛出备用。\n\n3. **炒米饭**:在锅中再加一些油,放入米饭,快速翻炒,确保米饭颗粒分开。\n\n4. **加入蔬菜**:如果你有胡萝卜丁和豌豆,可以在这时加入,翻炒均匀。
\n\n5. **调味**:加入盐、酱油和胡椒粉,继续翻炒,确保均匀入味。\n\n6. **加入鸡蛋**:最后,把之前炒好的鸡蛋和青葱加入锅中,翻炒均匀后即可出锅。\n\n### 小贴士
:\n- 使用隔夜饭口感更佳,因为水分更少,炒出来的米饭不容易粘在一起。\n- 可以根据自己的口味加入其他配料,比如火腿、虾仁等。\n\n希望你能做出美味的蛋炒饭!如果
还有其他问题或需要更多的食谱,随时告诉我!'}, {'role': 'user', 'content': '能不能三步速成?'}]
response===>: {
"id": "chatcmpl-89DtS4zNLK17vAcolF9XgRObfX3f3",
"object": "chat.completion",
"created": 1728824669,
"model": "gpt-4o-mini",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "\u5f53\u7136\u53ef\u4ee5\uff01\u4ee5\u4e0b\u662f\u4e09\u6b65\u901f\u6210\u86cb\u7092\u996d\u7684\u7b80\u5355\u505a\u6cd5\uff1a\n\n### \u4e09\u6b65\u901f\u6210\u86cb\u7092\u996d\n\n1. **\u51c6\u5907\u7c73\u996d\u548c\u9e21\u86cb**\uff1a\u7528\u9694\u591c\u7c73\u996d\uff08\u6216\u521a\u716e\u597d\u7684\u7c73\u996d\uff0c\u667e\u51c9\u540e\uff09\u51c6\u5907\u597d2\u7897\uff0c\u6253\u65632\u4e2a\u9e21\u86cb\u5907\u7528\u3002\n\n2. **\u7092\u9e21\u86cb\u548c\u7c73\u996d**\uff1a\u5728\u9505\u4e2d\u52a0\u70ed\u4e00\u4e9b\u6cb9\uff0c\u5148\u5012\u5165\u9e21\u86cb\u7092\u719f\uff0c\u7136\u540e\u52a0\u5165\u7c73\u996d\uff0c\u5feb\u901f\u7ffb\u7092\u5747\u5300\u3002\n\n3. **\u8c03\u5473\u548c\u51fa\u9505**\uff1a\u52a0\u5165\u76d0\u548c\u9171\u6cb9\u8c03\u5473\uff0c\u7092\u5300\u540e\u5373\u53ef\u51fa\u9505\uff0c\u6700\u540e\u6492\u4e0a\u8471\u82b1\uff08\u53ef\u9009\uff09\u3002\n\n\u8fd9\u6837\u5c31\u5b8c\u6210\u4e86\uff01\u7b80\u5355\u5feb\u901f\u53c8\u7f8e\u5473\uff01\u5e0c\u671b\u4f60\u559c\u6b22\uff01"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 410,
"completion_tokens": 160,
"total_tokens": 570
}
}
GPT: 当然可以!以下是三步速成蛋炒饭的简单做法:
### 三步速成蛋炒饭
1. **准备米饭和鸡蛋**:用隔夜米饭(或刚煮好的米饭,晾凉后)准备好2碗,打散2个鸡蛋备用。
2. **炒鸡蛋和米饭**:在锅中加热一些油,先倒入鸡蛋炒熟,然后加入米饭,快速翻炒均匀。
3. **调味和出锅**:加入盐和酱油调味,炒匀后即可出锅,最后撒上葱花(可选)。
这样就完成了!简单快速又美味!希望你喜欢!
你:
首先来看看response(我让Claude打个注释)
{
// 唯一标识符,用于识别这次对话完成的响应
"id": "chatcmpl-89D1bsACi3mm1eQofzau41ubWFyFZ",
// 表示这是一个聊天完成(chat completion)对象
"object": "chat.completion",
// 创建时间戳(Unix时间戳,单位为秒)
"created": 1728824619,
// 使用的模型名称
"model": "gpt-4o-mini",
// 包含生成的回复选项的数组
"choices": [
{
// 选项的索引,这里只有一个选项,所以是0
"index": 0,
// 生成的消息
"message": {
// 消息的角色,这里是AI助手
"role": "assistant",
// 生成的实际内容
"content": "你好!有什么我可以帮助你的吗?"
},
// 表示为什么生成停止,"stop"通常意味着正常完成
"finish_reason": "stop"
}
],
// 使用情况统计
"usage": {
// 提示(输入)使用的令牌数
"prompt_tokens": 16,
// 完成(输出)使用的令牌数
"completion_tokens": 9,
// 总共使用的令牌数(输入+输出)
"total_tokens": 25
}
}
看起来这个注释很全了,可以从response
里面看到的信息还蛮多的,甚至usage
里还统计了整个上下文消耗了多少tokens
,不过我这直接print
出来的好像是被编码了?Unicode
编码了,但是在代码中直接用取出来话就不是编码的,那就先不管这个了
我们再来看看messsages这个数组
[
{
'role': 'system',
'content': 'You are a helpful assistant.'
},
{
'role': 'user',
'content': '你好呀GPT'
},
{
'role': 'assistant',
'content': '你好!有什么我可以帮助你的吗?'
},
{
'role': 'user',
'content': '我想吃蛋炒饭了'
},
{
'role': 'assistant',
'content': (
'蛋炒饭是一道简单又美味的家常菜!你需要的材料很简单,通常包括:\n\n'
'- 米饭(最好是隔夜饭)\n'
'- 鸡蛋\n'
'- 青葱(可选)\n'
'- 胡萝卜(可选,切丁)\n'
'- 豌豆(可选)\n'
'- 盐\n'
'- 酱油\n'
'- 胡椒粉\n'
'- 食用油\n\n'
'### 做法:\n\n'
'1. **准备材料**:如果使用新鲜米饭,最好先晾凉。鸡蛋打散,青葱切碎。\n\n'
'2. **炒鸡蛋**:在锅中加一些油,加热后倒入打散的鸡蛋,迅速炒匀,炒至刚刚熟透后盛出备用。\n\n'
'3. **炒米饭**:在锅中再加一些油,放入米饭,快速翻炒,确保米饭颗粒分开。\n\n'
'4. **加入蔬菜**:如果你有胡萝卜丁和豌豆,可以在这时加入,翻炒均匀。\n\n'
'5. **调味**:加入盐、酱油和胡椒粉,继续翻炒,确保均匀入味。\n\n'
'6. **加入鸡蛋**:最后,把之前炒好的鸡蛋和青葱加入锅中,翻炒均匀后即可出锅。\n\n'
'### 小贴士:\n'
'- 使用隔夜饭口感更佳,因为水分更少,炒出来的米饭不容易粘在一起。\n'
'- 可以根据自己的口味加入其他配料,比如火腿、虾仁等。\n\n'
'希望你能做出美味的蛋炒饭!如果还有其他问题或需要更多的食谱,随时告诉我!'
)
},
{
'role': 'user',
'content': '能不能三步速成?'
}
]
我们从代码中就可以看到,每次用户输入东西的时候都会往数组中append
,GPT也一样,每次回复后都会往数组中append,这样就构建了一个对话上下文,那就是每对话一次,注意是每对话一次都会带整个上下文,也就是说prompt_tokens(输入token)
会随着对话的越多而增多,说的通俗易懂一点,就是你对话的越多消耗的钱就越多,因为每次都是带整个上下文去触发对话的,不带的话GPT就不会记得你们聊过什么~
总结
也算是搞懂了基本参数,和响应结构,还有上下文的组成了,那接下来我有个疑问,我们平常在网页上使用GPT的时候,或者是一些大模型的时候,好像不是这么交互的,它们会一个一个字的输出回复,这种形式好像是叫”流输出“?我想研究下这个,我重新开篇文章写吧,算是记下来了,那参数,数据结构搞明白了,接下来我们不用openai库来实现一下?就单纯自己来请求来处理,试试看
尝试不使用官方库实现一样的效果,通过官方的API
代码
# 导入必要的库
import requests # 用于发送 HTTP 请求
import json # 用于处理 JSON 数据
# 设置 API 密钥和基础 URL
API_KEY = 'sk-XXXXXXXXXX' # 你的 API 密钥
API_BASE = 'https://api.openai.com/v1' # API 的基础 URL
# 定义聊天功能,保持上下文
def chat_with_gpt(messages):
# 设置 HTTP 请求头
headers = {
'Content-Type': 'application/json', # 指定内容类型为 JSON
'Authorization': f'Bearer {API_KEY}' # 设置身份验证
}
# 准备请求数据
data = {
'model': 'gpt-4o-mini', # 指定使用的模型
'messages': messages, # 传递对话历史
'max_tokens': 1000, # 限制返回的最大字符数
'temperature': 0.7 # 控制输出的随机性(0-1之间,越高越随机)
}
# 发送 POST 请求到 API
response = requests.post(f'{API_BASE}/chat/completions', headers=headers, json=data)
# 检查响应状态
if response.status_code == 200: # 如果请求成功
result = response.json() # 将响应转换为 JSON 格式
print("messages===>:", messages) # 打印发送的消息
print("response===>:", result) # 打印收到的完整响应
return result['choices'][0]['message']['content'] # 返回 AI 的回复内容
else: # 如果请求失败
print(f"Error: {response.status_code}") # 打印错误状态码
print(response.text) # 打印错误信息
return None # 返回 None 表示请求失败
# 主程序
if __name__ == "__main__":
print("开始与 GPT-4o mini 互动,输入 'exit' 退出")
# 初始化对话历史
messages = [{"role": "system", "content": "You are a helpful assistant."}]
# 开始对话循环
while True:
user_input = input("你: ") # 获取用户输入
if user_input.lower() == "exit": # 如果用户输入 "exit",退出循环
break
# 将用户输入加入对话历史
messages.append({"role": "user", "content": user_input})
# 获取 GPT 的回复
response = chat_with_gpt(messages)
if response: # 如果成功获取到回复
print(f"GPT: {response}") # 打印 AI 的回复
# 将 GPT 的回复加入对话历史
messages.append({"role": "assistant", "content": response})
else: # 如果未能获取到回复
print("无法获取 GPT 的回复,请检查您的网络连接或 API 密钥。")
效果
开始与 GPT-4o mini 互动,输入 'exit' 退出
你: 你好呀
messages===>: [{'role': 'system', 'content': 'You are a helpful assistant.'}, {'role': 'user', 'content': '你好呀'}]
response===>: {'id': 'chatcmpl-89D77IFsjo4JUaljAmOOYwiIacw9G', 'object': 'chat.completion', 'created': 1728887367, 'model':
'gpt-4o-mini', 'choices': [{'index': 0, 'message': {'role': 'assistant', 'content': '你好!有什么我可以帮助你的吗?'}, 'finish_reason': 'stop'}], 'usage': {'prompt_tokens': 15, 'completion_tokens': 9, 'total_tokens': 24}}
GPT: 你好!有什么我可以帮助你的吗?
你: 你可以做什么?
messages===>: [{'role': 'system', 'content': 'You are a helpful assistant.'}, {'role': 'user', 'content': '你好呀'}, {'role': 'assistant', 'content': '你好!有什么我可以帮助你的吗?'}, {'role': 'user', 'content': '你可以做什么?'}]
response===>: {'id': 'chatcmpl-89D6bPIpnqWm3QYoBG7lBEYNT3PZ9', 'object': 'chat.completion', 'created': 1728887431, 'model':
'gpt-4o-mini', 'choices': [{'index': 0, 'message': {'role': 'assistant', 'content': '我可以帮助你解答问题、提供信息、给出建议
、进行对话、撰写文本、翻译语言、帮助学习新知识等等。你有什么具体的需求吗?'}, 'finish_reason': 'stop'}], 'usage': {'prompt_tokens': 29, 'completion_tokens': 41, 'total_tokens': 70}}
GPT: 我可以帮助你解答问题、提供信息、给出建议、进行对话、撰写文本、翻译语言、帮助学习新知识等等。你有什么具体的需求吗?
你:
总结
从官方文档来看,不仅提供了对话的API,还有其它功能的比如语音呀、图片生成呀、上传文件呀,我们用库的时候调用的是ChatCompletion
,API请求地址是/chat/completions
那就很明显能看出来了,官方的库就是对api请求的封装,害也不是什么新鲜事,就是写出来而已,这很正常,基本上sdk能实现的都能通过请求api实现,毕竟这样适应的场景更多嘛。