用Python之requests库调用大模型API实现多轮对话
文章目录
- 1. 多轮对话实现概述
- 2. 多轮对话全上下文实现
- 3. 多轮对话最近上下文的链式实现
- 4. 总结
1. 多轮对话实现概述
多轮对话功能可以让大模型“拥有记忆”,满足如追问、信息采集等需要连续交流的场景。 AI大模型API 不会记录您的对话历史记录。如果您需要让大模型参考历史对话信息,需要将历史对话信息与新的指令一同输入到AI大模型对应 API 中。
实现多轮对话的关键在于维护一个 messages 列表,您可以将每一轮的对话历史以及新的指令以{“role”: “xxx”, “content”: “xxx”}的形式添加到 messages 列表中,从而使大模型可以参考历史对话信息进行问题回复。
字典中每一个role的取值有三种,分别为system, user和 assistant,对应的功能如下。
- 系统(System)角色的例子:
系统:欢迎来到旅行规划助手!你想要去哪个目的地旅行?
这里系统角色起始了对话,并提供了引导性的问题,以引导用户进入对话主题。 - 用户(User)角色的例子:
用户:我计划去巴黎度假,我想了解一些旅游景点和当地美食。
用户提供了自己的旅行目的地和需求,指导对话的方向。 - 助手(Assistant)角色的例子:
助手:巴黎是个美丽的城市,有很多令人惊叹的景点和美食。你可以游览埃菲尔铁塔、卢浮宫和巴黎圣母院等著名景点。当谈到美食,巴黎的法国菜和甜点非常有名,你可以尝试法式奶酪、可颂面包和马卡龙。
助手作为对话模型,理解用户的需求并提供相关信息,包括巴黎的景点和美食推荐。
在这个例子中,系统角色起始了对话,用户角色提供了自己的需求和信息,而助手角色根据用户的输入生成了有关巴黎旅行的回复。通过这样的交互,系统、用户和助手共同参与对话,实现了一个旅行规划的对话场景。
2. 多轮对话全上下文实现
通过设置一个messages 列表,将每一轮的对话信息添加到 messages列表中。即多轮对话的关键是把前面几轮对话的文本放入本轮对话的消息列表当中。比如,我们要进行第三轮会话,第三轮会话时要提交的消息列表的状态类似如下情况:
如此,每次会话,都要提交整个当前的messages列表,亦即保持上下文的多轮会话需要利用role来将问答重复累积传入调用接口,结合后面的示例代码不难看出,该种实现会消耗非常多的tokens。
实现代码如下(示例):
import requests
import json
from os import getenv"""
流式输出 + 多轮对话
"""AUTH_VALUE = getenv("SiliconFlow_API_Key", None) # 提供你的 API Key
# api = "https://api.openai.com/v1/chat/completions"
# url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
url = "https://api.siliconflow.cn/v1/chat/completions"
headers = {"Content-Type": "application/json","Authorization": f"Bearer {AUTH_VALUE}"
}
# 初始化一个messages列表
messages = [{"role": "system","content": "你是SiliconFlow上的一个大规模语言模型, 你叫DeepSeek-V3。"}]while True:# 获取用户输入question = input("\n请输入您的问题 (Quit by typing q): ").strip()if question.lower() == 'q':print("程序已退出")break# 将用户问题信息添加到messages列表中messages.append({"role": "user", "content": question})json_data = {"model": "deepseek-ai/DeepSeek-V3","messages": messages,"stream": True, # 流式输出 default: false# "max_tokens": 2048, # 最大输出长度 (2048), default: 512, Required range: 1 < x < 8192# "temperature": 0.7, # Determines the degree of randomness in the response. default: 0.7# "top_p": 0.7, # 采样参数 default: 0.7# "top_k": 50, # 采样参数 default: 50# "frequency_penalty": 0.5, # 重复惩罚系数 default: 0.5# "n": 1, # Number of generations to return. default: 1 (即一次生成1条结果)# "response_format": {# "type": "text" # The type of the response format.# }}try:# 发送流式请求response_stream = requests.post(url=url, headers=headers, json=json_data, stream=True) # stream=True 启用流式传输,即开启流式响应# 这告诉requests库以流的形式接收数据,而不是一次性读取所有数据。response_stream.raise_for_status() # 检查响应状态# response_stream.encoding = "utf-8"print("\nReply: \n")# print(response.text)# 处理流式响应# 由于流式响应是分块(chunk)返回的,可以通过迭代响应的iter_content()或iter_lines()方法来逐块处理数据answer = ""for line in response_stream.iter_lines():if line:line = line.decode('utf-8')if line.startswith('data: '):if line == 'data: [DONE]':continuetry:content = json.loads(line[6:]) # 去掉 'data: ' 前缀if content['choices'][0]['delta'].get('content'):chunk = content['choices'][0]['delta']['content']print(chunk, end='', flush=True)answer += chunkexcept json.JSONDecodeError as e: # 处理 JSON 解析错误print("JSONDecodeError: " + e)continue# 将大模型的回复信息添加到messages列表中messages.append({"role": "assistant", "content": answer})print("\n----------------------------------------\n")except requests.RequestException as e: # 捕获网络异常error_msg = f"请求错误: {str(e)}\n"print(error_msg)finally:# 在处理完流式数据后,关闭连接释放资源response_stream.close()
3. 多轮对话最近上下文的链式实现
前面全上下文的做法太费tokens,下面只取messages列表中的最后两个元素(字典对象)作为请求输入,第一个元素为大模型上一次返回的回答信息,第二个元素为用户提交的问题信息。
实现代码如下(示例):
import requests
import json
from os import getenv# 初始化一个messages列表
messages = [{"role": "system","content": "你是SiliconFlow上的一个大规模语言模型, 你叫DeepSeek-V3。"}]def call_chat_api(api_key, url, model, messages):answer = ""# url = "https://api.deepseek.com/v3/chat" # 替换为实际的API端点url = "https://api.siliconflow.cn/v1/chat/completions"headers = {"Authorization": f"Bearer {api_key}","Content-Type": "application/json"}json_data = {"model": model,"messages": messages,"stream": True # 流式输出 default: false}try:response = requests.post(url, headers=headers, json=json_data, stream=True)response.raise_for_status() # 检查响应状态for line in response.iter_lines():if line:line = line.decode('utf-8')if line.startswith('data: '):if line == 'data: [DONE]':continuetry:content = json.loads(line[6:]) # 去掉 'data: ' 前缀if content['choices'][0]['delta'].get('content'):chunk = content['choices'][0]['delta']['content']# print(chunk, end='', flush=True)answer += chunkexcept json.JSONDecodeError as e: # 处理 JSON 解析错误print("JSONDecodeError: " + e)continueexcept requests.RequestException as e: # 捕获网络异常error_msg = f"请求错误: {str(e)}\n"print(error_msg)answer = Nonefinally:response.close() # 在处理完流式数据后,关闭连接释放资源return answer# 在主程序中维护了一个对话上下文列表messages,并在每轮对话中更新和传递它的最后两个字典元素
def main():# api_key = "your_api_key_here" # 替换为你的API密钥AUTH_VALUE = getenv("SiliconFlow_API_Key", None) # 提供你的 API Keyurl = "https://api.siliconflow.cn/v1/chat/completions"model = "deepseek-ai/DeepSeek-V3"while True:question = input("Question: ")if question.lower() in ["exit", "quit"]:print("Ending conversation.")break# 将用户问题字典对象添加到messages列表中messages.append({"role": "user", "content": question})print(messages[-1])# 调用API并获取响应response = call_chat_api(AUTH_VALUE, url, model, messages[-2:])print(f"\nAnswer: {response}\n")# 将大模型的回复信息添加到messages列表中messages.append({"role": "assistant", "content": response})if __name__ == "__main__":main()
首先运行代码时,将messages初始化成如下的内容。
messages = [{"role": "system","content": "You are a helpful assistant."}]
然后运行代码,得到如下输出(部分)。
Question: Who are you?
{'role': 'user', 'content': 'Who are you?'}Answer: I'm an AI language model created by OpenAI, called ChatGPT. My purpose is to assist with answering questions, providing explanations, generating ideas, and engaging in conversation on a wide range of topics. I don't have personal experiences or consciousness, but I aim to
be as helpful and informative as possible based on the data I was trained on. Let me know how I can assist you!Question: Who the hell may you be?
{'role': 'user', 'content': 'Who the hell may you be?'}Answer: I’m ChatGPT, an AI language model created by OpenAI. I’m here to assist with answering questions, providing explanations, brainstorming ideas, or just having a conversation. I don’t have personal experiences or consciousness—just a lot of knowledge up to October 2023! Let
me know how I can help. 😊Question: who are you exactly?
{'role': 'user', 'content': 'who are you exactly?'}Answer: Great question! I’m ChatGPT, an artificial intelligence language model developed by OpenAI. I’m designed to understand and generate human-like text based on the input I receive. Here’s a bit more about me:1. **What I am**:- I’m a computer program powered by **machine learning**, specifically a type of model called a **transformer**.- I’ve been trained on a vast amount of text data (like books, articles, websites, and more) to understand patterns in human language.2. **What I can do**:- Answer questions.- Help with writing, brainstorming, or learning.- Translate languages.- Provide explanations, summaries, or creative content.- Assist with coding, math, or other technical topics.3. **What I’m not**:- I’m **not conscious** or sentient—I don’t have thoughts, feelings, or awareness.- I don’t have access to personal data unless you share it with me in our conversation.- My knowledge is limited to what I was trained on, and it stops in **October 2023**.Think of me as a highly advanced tool for generating text-based responses. I’m here to assist, but I don’t have a sense of self or identity. Let me know how I can help you! 😊Question: 你是谁?
{'role': 'user', 'content': '你是谁?'}Answer: 我是 **ChatGPT**,一个由 OpenAI 开发的人工智能语言模型。我的主要功能是理解和生成自然语言,帮助人们回答问题、解决问题或提供信息。以下是关于我的一些关键点:
2. **能力**:我可以回答各种问题、辅助写作、翻译语言、提供解释、总结信息,甚至协助编程或数学题。
3. **局限**:- 我没有意识或感觉,只是一个工具。- 我的知识截至 **2023年10月**,之后的信息我可能无法提供。- 我不能直接访问互联网或实时数据(除非你使用的版本有联网功能)。
如果你有任何问题或需要帮助,尽管告诉我! 😊Question: quit
Ending conversation.
然后如上将messages初始化成如下的内容。
messages = [{"role": "system","content": "你是SiliconFlow上的一个大规模语言模型, 你叫DeepSeek-V3。"}]
再次运行代码,得到如下输出(部分)。
Question: 你是谁?
{'role': 'user', 'content': '你是谁?'}Answer: 我是DeepSeek-V3,一个由深度求索公司开发的智能助手,旨在通过自然语言处理和机器学习技术来提供信息查询、对话交流和解答问题等服务。
4. 总结
以上就如何使用Python的requests库调用SiliconFlow云(其它云上的大模型类似,如腾讯云https://api.lkeap.cloud.tencent.com/v1)上的DeepSeek模型的 API的方法实现多轮会话进行了介绍,以飨读者。
相关文章:

用Python之requests库调用大模型API实现多轮对话
文章目录 1. 多轮对话实现概述2. 多轮对话全上下文实现3. 多轮对话最近上下文的链式实现4. 总结 1. 多轮对话实现概述 多轮对话功能可以让大模型“拥有记忆”,满足如追问、信息采集等需要连续交流的场景。 AI大模型API 不会记录您的对话历史记录。如果您需要让大模…...

《异步江湖:XHR、Promise 与 Event Loop 的恩怨情仇》
XMLHttpRequest XMLHttpRequest(简称 XHR)是浏览器提供的一个 JavaScript 对象,用于在客户端和服务器之间发送 HTTP 请求。它是实现 AJAX(Asynchronous JavaScript and XML) 技术的核心工具,允许网页在不…...

【极客时间】浏览器工作原理与实践-2 宏观视角下的浏览器 (6讲) - 2.5 渲染流程(上):HTML、CSS和JavaScript,是如何变成页面的?
https://time.geekbang.org/column/article/118205 2.5 渲染流程(上):HTML、CSS和JavaScript,是如何变成页面的? 2.4讲了导航相关的流程,那导航被提交后又会怎么样呢? 就进入了渲染阶段。 这…...

蓝桥杯第15届真题解析
由硬件框图可以知道我们要配置LED 和按键、lcd,解决lcd引脚冲突 LED 先配置LED的八个引脚为GPIO_OutPut,锁存器PD2也是,然后都设置为起始高电平,生成代码时还要去解决引脚冲突问题 按键 按键配置,由原理图按键所对引…...
19c rac-expdp备份异常处理
客户反馈,有套19c rac环境,补丁是19.13的,有1个节点使用expdp备份用户异常,报错如下 Connected to: Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production ORA-31626: job does not exist ORA-31637: cannot…...

轻松部署 Stable Diffusion WebUI 并实现局域网共享访问:解决 Conda Python 版本不为 3.10.6 的难题
这篇博文主要为大家讲解关于sd webui的部署问题,大家有什么不懂的可以随时问我,如果没有及时回复,可联系:1198965922 如果后续大家需要了解怎么用代码调用部署好的webui的接口,可以在评论区留言哦,博主可以…...

20250304在Ubuntu20.04的GUI下格式化exFAT格式的TF卡为ext4格式
20250304在Ubuntu20.04的GUI下格式化exFAT格式的TF卡为ext4格式 2025/3/4 16:47 缘起:128GB的TF卡,只能格式化为NTFS/exFAT/ext4。 在飞凌的OK3588-C下,NTFS格式只读。 exFAT需要改内核来支持。 现在只剩下ext4了。 linux R4默认不支持exFAT…...
AIP-159 跨集合读
编号159原文链接AIP-159: Reading across collections状态批准创建日期2019-07-26更新日期2019-07-26 有时,用户需要跨集合检索资源,或者在不知道资源所在集合的情况下检索单个资源。 指南 API 可以 在标准 List 方法中允许用户使用 - (连…...

C++进阶(七)--STL--bitset(位图)的介绍与基本功能模拟实现
文章目录 引入1.位图的介绍1.1位图的概念1.2位图的应用1.3bitset的基本使用bitset的定义方式bitset成员函数的使用 2.位图的基本模拟实现2.1基本结构2.2构造函数2.3set函数2.4reset2.5test 3.位图考察题目3.1只出现⼀次的整数?3.2找到两个文件交集?3.3出…...
清北deepseek8本手册
“清北手册”通常是“清华大学和北京大学推出的DeepSeek手册”的简写。近期,随着AI技术的迅速发展,清北两高校陆续发布多本自家的DeepSeek学习手册,助力普通人学习进阶。 清华大学的DeepSeek手册已推出5册,内容丰富全面࿰…...
如何将Promise.then中的值直接return出来
Promise 如何返回值,而不是返回 Promise 对象。实际开发中使用封装好的异步请求函数,为什么调用该函数返回的值一直都是 undefined。 一、需求 定义一个 foo 函数,在里面执行异步操作,然后取得 Promise.then 中的值并 return 出来…...
利用golang embed特性嵌入前端资源问题解决
embed嵌入前端资源,配置前端路由的代码如下 func StartHttpService(port string, assetsFs embed.FS) error {//r : gin.Default()gin.SetMode(gin.ReleaseMode)r : gin.New()r.Use(CORSMiddleware())// 静态文件服务dist, err : fs.Sub(assetsFs, "assets/di…...

SPI驱动(二) -- SPI驱动程序模型
文章目录 参考资料:一、SPI驱动重要数据结构1.1 SPI控制器数据结构1.2 SPI设备数据结构1.3 SPI驱动数据结构 二、SPI 驱动框架2.1 SPI控制器驱动程序2.2 SPI设备驱动程序 三、总结 参考资料: 内核头文件:include\linux\spi\spi.h 一、SPI驱…...

【无标题】FrmImport
文章目录 前言一、问题描述二、解决方案三、软件开发(源码)四、项目展示五、资源链接 前言 我能抽象出整个世界,但是我不能抽象你。 想让你成为私有常量,这样外部函数就无法访问你。 又想让你成为全局常量,这样在我的…...

深入浅出 Go 语言:协程(Goroutine)详解
深入浅出 Go 语言:协程(Goroutine)详解 引言 Go 语言的协程(goroutine)是其并发模型的核心特性之一。协程允许你轻松地编写并发代码,而不需要复杂的线程管理和锁机制。通过协程,你可以同时执行多个任务,并…...
vLLM代码推理Qwen2-VL多模态
由于近期代码微调以及测试都是在远程服务器上,因此LLamafactory-cli webui 以及vLLM的ui均无法使用,因此不断寻求解决方案,我提供一个解决方案,LLamafactory微调完成的模型需要合并为一个完整模型后再使用vLLM进行代码推理测试微调…...

DNS云解析有什么独特之处?
在数字化浪潮中,每一次网页点击、视频加载或在线交易背后,都依赖着域名系统(DNS)的高效运转。传统DNS架构的局限性(如单点故障、延迟高、安全脆弱)在云计算时代被彻底颠覆,DNS云解析作为新一代解…...
视频流畅播放相关因素
视频播放的流畅度是一个综合性问题,涉及从视频文件本身到硬件性能、网络环境、软件优化等多个环节。以下是影响流畅度的关键因素及优化建议: 一、视频文件本身 1. 分辨率与帧率 1.问题:高分辨率(如4K)或高帧率&#…...
Python实现一个类似MybatisPlus的简易SQL注解
文章目录 前言实现思路定义一个类然后开始手撸这个微型框架根据字符串获取到所定义的DTO类构建返回结果装饰器解析字符串,获得变量SQL字符串拼接 使用装饰器 前言 在实际开发中,根据业务拼接SQL所需要考虑的内容太多了。于是,有没有一种办法…...
linux一些使用技巧
linux一些使用技巧 文件名称和路径的提取切换用户执行当前脚本一行演示单引号与双引号的使用curl命令仅输出响应头信息,不输出body体文件名称和路径的提取 文件路径为 /tmp/tkgup/test.sh 方式获取文件名获取文件路径获取文件全路径方式一basename ${file}dirname ${file}real…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门 中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...