用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

代码

  1. 官方文档:https://platform.openai.com/docs/api-reference/chat/create

  2. API地址:https://api.openai.com/v1/chat/completions

# 导入必要的库
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实现,毕竟这样适应的场景更多嘛。