基于python实现openai可结合上下文的问答

本文使用 OpenAI GPT(Generative Pre-Training)聊天机器人模型,实现可自动回复提问的聊天功能。

代码解释

首先,我们导入相关的库,例如 openaiPathtime 等。

接下来,为了使模型可以正常工作,我们需要设置 openaiapi_key ,以及一些初始变量,如 text, turns, last_result,用来记录聊天记录。

之后,我们定义了一个函数 chatgpt,目的是为了接收用户输入的问题,并返回 GPT 模型生成的回答。函数中,除了指定使用 davinci-003 模型外,我们还设置了 temperaturemax_tokensfrequency_penaltypresence_penalty 等参数,用来控制结果的随机性和字数,以达到最佳的回答效果。

最后,在 if __name__ == '__main__': 下,我们初始化两个列表,用来存放用户输入的问题和 GPT 模型自动生成的回答,然后在 while 循环中,接收用户输入的问题,并调用 chatgpt 函数,最后将问题和回答分别存储到对应的列表中,最终将内容保存到文件中。

代码使用说明

  • 使用该代码,你需要先申请 OpenAI 的api_key,并将其输入到代码中,然后运行该程序,
  • 输入你的问题,即可获得 GPT 模型的回答;
  • 若输入exit则直接退出当前对话;
  • 程序结束时,会将问答的内容记录到文件中,以便下次查看。

ini配置文件

在目录下创建config.ini文件,内容如下

[openai]

ai_account_key = sk-AsqirFnBSHKvalmEe1AnT3BlbkFJe2rX0xxxxxxxxxxx

对话模式代码

点击查看代码
import openai
from pathlib import Path
import time
import configparser

ANSI_COLOR_GREEN = "\x1b[32m"
ANSI_COLOR_RESET = "\x1b[0m"


# 从ini文件中读取api_key
config = configparser.ConfigParser()
config.read('config.ini')
openai.api_key = config['openai']['ai_account_key']


text = ""  # 设置一个字符串变量
turns = []  # 设置一个列表变量,turn指对话时的话轮
last_result = ""


def chatgpt(question):
    global text
    global turns
    global last_result

    prompt = text + "\nHuman: " + question

    try:
        response = openai.Completion.create(
            model="text-davinci-003",  # 这里我们使用的是davinci-003的模型,准确度更高。
            prompt=prompt,  # 你输入的问题
            temperature=0.9,  # 控制结果的随机性,如果希望结果更有创意可以尝试 0.9,或者希望有固定结果可以尝试 0.0
            max_tokens=2048,  # 这里限制的是回答的长度,你可以可以限制字数,如:写一个300字作文等。
            top_p=1,
            # [控制字符的重复度] -2.0 ~ 2.0 之间的数字,正值会根据新 tokens 在文本中的现有频率对其进行惩罚,从而降低模型逐字重复同一行的可能性
            frequency_penalty=0,
            # [控制主题的重复度] -2.0 ~ 2.0 之间的数字,正值会根据到目前为止是否出现在文本中来惩罚新 tokens,从而增加模型谈论新主题的可能性
            presence_penalty=0
        )

        result = response["choices"][0]["text"].strip()
        last_result = result
        turns += [question] + [result]  # 只有这样迭代才能连续提问理解上下文

        if len(turns) <= 10:  # 为了防止超过字数限制程序会爆掉,所以提交的话轮语境为10次。
            text = " ".join(turns)
        else:
            text = " ".join(turns[-10:])

        return result
    except Exception as exc:  # 捕获异常后打印出来
        print(exc)


if __name__ == '__main__':

    # 将问题和回复记录下来,待结束后保存到文件中
    question_list = []
    answer_list = []
    while True:
        question = input(ANSI_COLOR_GREEN +
                         "\n请输入问题,若输入exit退出\n" + ANSI_COLOR_RESET)
        question_list.append(question)
        if question == "exit":
            break
        answer = chatgpt(question)
        answer_list.append(answer)
        print("AI: " + answer)
    # 保存到文件中
    timestamp = time.strftime("%Y%m%d-%H%M-%S", time.localtime())
    file_name = 'output/chat ' + timestamp + '.md'
    f = Path(file_name)
    f.parent.mkdir(parents=True, exist_ok=True)
    with open(file_name, "w", encoding="utf-8") as f:
        for q, a in zip(question_list, answer_list):
            f.write(f"question: {q}\nanswer: {a}\n\n")
    print(ANSI_COLOR_GREEN + "对话内容已保存到文件中: " + file_name + ANSI_COLOR_RESET)


单问答模式代码

点击查看代码
import openai
from pathlib import Path
import time
import configparser


ANSI_COLOR_GREEN    = "\x1b[32m"
ANSI_COLOR_RESET    = "\x1b[0m"



def get_ai_answer(prompt, save=True):
    # 去除字符串前后的空白符
    prompt = prompt.strip()
    # 发起请求
    if len(prompt) != 0:
        print(f'已发起请求,问题描述{len(prompt)}个长度,请稍等...')
        # 从ini文件中读取api_key
        config = configparser.ConfigParser()
        config.read('config.ini')
        openai.api_key = config['openai']['ai_account_key']
        # Get my answer
        response = openai.Completion.create(
            prompt=prompt,
            model="text-davinci-003",
            temperature=0.9,
            max_tokens=2048,  #返回结果的长度
            top_p=1,
            frequency_penalty=0.0,
            presence_penalty=0.0)

        # Print my answer
        # print(response)
        answer = response["choices"][0]["text"].strip()
        print(answer)

        # 将内容写到以时间戳为名的md文件
        if save:
            timestamp = time.strftime("%Y%m%d-%H%M-%S", time.localtime())
            file_name = 'output/' + timestamp + '.md'
            f = Path(file_name)
            f.parent.mkdir(parents=True, exist_ok=True)
            text = f'# Q\n{prompt}\n# A\n{answer}\n'
            f.write_text(text, encoding='utf-8')
            print(ANSI_COLOR_GREEN  +"对话内容已保存到文件中: " + file_name + ANSI_COLOR_RESET)
        return answer


if __name__ == '__main__':
    prompt = '''
你今年几岁了
    '''
    get_ai_answer(prompt)


gitee在线版

此外,我用html写了一个可直接对话的openai gpt3在线版,用该页面需要提前自备openai的apikey。

项目源码https://gitee.com/x223222981/chat-gpt.js

gpt-3.5-turbo模型

2023年3月OpenAI允许第三方开发者通过API将ChatGPT集成到其APP和服务中,OpenAI表示,全新API基于“gpt-3.5-turbo”模型,其基础是支持ChatGPT的GPT 3.5模型,取代了此前的“text-davinci-003.”
下面使用python通过api的方式调用AI聊天。

使用之前需将openai库升级到最新版本,否则旧版本的api不支持gpt-3.5-turbo模型,
这里我使用的是0.27.0

pip install --upgrade openai
点击查看代码
import openai
import configparser


# 从ini文件中读取api_key
config = configparser.ConfigParser()
config.read('config.ini')
openai.api_key = config['openai']['ai_account_key']

# Function to send a message to the OpenAI chatbot model and return its response
# 发送消息给OpenAI的聊天机器人模型,并返回它的回复
def send_message(message_log):
    # Use OpenAI's ChatCompletion API to get the chatbot's response
    # 使用OpenAI的ChatCompletion API来获取聊天机器人的回复
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",  # The name of the OpenAI chatbot model to use
        # 这个模型是网页版OpenAI chatbot的模型
        # The conversation history up to this point, as a list of dictionaries
        # 将目前为止的对话历史记录,作为字典的列表
        messages=message_log,
        # The maximum number of tokens (words or subwords) in the generated response
        # 最大的生成回复的token数 最大4095(单词或子单词)
        max_tokens=4095,
        # The stopping sequence for the generated response, if any (not used here)
        # 停止生成回复的序列,如果有的话(这里没有使用)
        stop=None,
        # The "creativity" of the generated response (higher temperature = more creative)
        # 生成回复的“创造性”(参数越高,创造性越强)
        temperature=0.9,
    )

    # Find the first response from the chatbot that has text in it (some responses may not have text)
    # 从聊天机器人的回复中,找到第一个有文本的回复(有些回复可能没有文本)
    for choice in response.choices:
        if "text" in choice:
            return choice.text

    # If no response with text is found, return the first response's content (which may be empty)
    # 如果没有找到有文本的回复,返回第一个回复的内容(可能为空)
    return response.choices[0].message.content


# Main function that runs the chatbot
def main():
    # Initialize the conversation history with a message from the chatbot
    # 用聊天机器人的消息来初始化对话历史记录
    message_log = [
        {"role": "system", "content": "You are a helpful assistant."}
    ]

    # Set a flag to keep track of whether this is the first request in the conversation
    # 设置一个标志来跟踪这是否是对话中的第一个请求
    first_request = True

    # Start a loop that runs until the user types "quit"
    # 开始一个循环,直到用户输入“quit”为止
    while True:
        if first_request:
            # If this is the first request, get the user's input and add it to the conversation history
            # 如果这是第一个请求,获取用户的输入,并将其添加到对话历史记录中
            user_input = input("You: ")
            message_log.append({"role": "user", "content": user_input})

            # Add a message from the chatbot to the conversation history
            # 添加来自聊天机器人的消息到对话历史记录中
            message_log.append(
                {"role": "assistant", "content": "You are a helpful assistant."})

            # Send the conversation history to the chatbot and get its response
            # 发送对话历史记录给聊天机器人,并获取它的回复
            response = send_message(message_log)

            # Add the chatbot's response to the conversation history and print it to the console
            # 添加聊天机器人的回复到对话历史记录中,并将其打印到控制台
            message_log.append({"role": "assistant", "content": response})
            print(f"AI assistant: {response}")

            # Set the flag to False so that this branch is not executed again
            # 设置标志为False,以便不再执行此分支
            first_request = False
        else:
            # If this is not the first request, get the user's input and add it to the conversation history
            # 如果这不是第一个请求,获取用户的输入,并将其添加到对话历史记录中
            user_input = input("You: ")

            # If the user types "quit", end the loop and print a goodbye message
            # 如果用户输入“quit”,结束循环并打印再见消息
            if user_input.lower() == "quit":
                print("Goodbye!")
                break

            message_log.append({"role": "user", "content": user_input})

            # Send the conversation history to the chatbot and get its response
            # 发送对话历史记录给聊天机器人,并获取它的回复
            response = send_message(message_log)

            # Add the chatbot's response to the conversation history and print it to the console
            # 添加聊天机器人的回复到对话历史记录中,并将其打印到控制台
            message_log.append({"role": "assistant", "content": response})
            print(f"AI assistant: {response}")


# Call the main function if this file is executed directly (not imported as a module)
if __name__ == "__main__":
    main()



2023年3月5日更新(新版)模型gpt-3.5-turbo在线地址:ChatGPT3.5-turbo (gitee.io)

posted @ 2023-02-15 21:54  Dapenson  阅读(3119)  评论(1编辑  收藏  举报