当前位置: 首页 > news >正文

AI Agent的多轮对话:提升用户体验的关键技巧

在前面的文章中,我们讨论了 AI Agent 的各个核心系统。今天,我想聊聊如何实现一个好用的多轮对话系统。说实话,这个话题我琢磨了很久,因为它直接影响到用户体验。

从一个槽点说起

还记得我最开始做对话系统时的一个典型场景:

用户:帮我查一下订单状态
助手:好的,请提供订单号。
用户:A12345
助手:抱歉,我需要您提供订单号才能查询。
用户:...我刚才不是说了吗?

这种对话体验显然很糟糕。问题出在哪里?主要是 AI Agent 没有正确理解和维护对话上下文。后来我总结了几个关键点:

  1. 要理解用户意图
  2. 要记住上下文信息
  3. 要有状态管理机制
  4. 要能处理各种异常情况

对话系统的设计

经过多次迭代,我设计了一个相对完善的对话系统:

from typing import List, Dict, Any, Optional
from enum import Enum
from datetime import datetime
from pydantic import BaseModel
import asyncioclass DialogueState(Enum):IDLE = "idle"WAITING_INPUT = "waiting_input"PROCESSING = "processing"ERROR = "error"COMPLETED = "completed"class DialogueContext(BaseModel):session_id: struser_id: strcurrent_state: DialogueStatecurrent_intent: Optional[str]slots: Dict[str, Any]history: List[Dict[str, Any]]created_at: datetimeupdated_at: datetimeclass DialogueSystem:def __init__(self,llm,tool_registry,memory_system):self.llm = llmself.tool_registry = tool_registryself.memory_system = memory_systemself.sessions: Dict[str, DialogueContext] = {}async def process_message(self,session_id: str,user_id: str,message: str) -> str:# 1. 获取或创建会话上下文context = self._get_or_create_context(session_id,user_id)try:# 2. 更新状态context.current_state = DialogueState.PROCESSING# 3. 理解用户意图intent = await self._understand_intent(message,context)# 4. 更新上下文context.current_intent = intent.namecontext.slots.update(intent.slots)# 5. 执行对应的处理流程response = await self._handle_intent(intent,context)# 6. 记录对话历史self._update_history(context,message,response)return responseexcept Exception as e:context.current_state = DialogueState.ERRORreturn f"抱歉,处理您的请求时出现错误:{str(e)}"finally:# 保存上下文self._save_context(context)async def _understand_intent(self,message: str,context: DialogueContext) -> Intent:# 结合上下文理解用户意图response = await self.llm.understand_intent(message=message,history=context.history[-5:],  # 最近5轮对话current_intent=context.current_intent,slots=context.slots)return Intent(name=response.intent,confidence=response.confidence,slots=response.slots)async def _handle_intent(self,intent: Intent,context: DialogueContext) -> str:# 检查是否有未填充的必要槽位missing_slots = self._get_missing_slots(intent)if missing_slots:# 返回槽位询问context.current_state = DialogueState.WAITING_INPUTreturn self._generate_slot_question(missing_slots[0])# 所有槽位都已填充,执行操作result = await self._execute_intent(intent,context)context.current_state = DialogueState.COMPLETEDreturn resultdef _get_or_create_context(self,session_id: str,user_id: str) -> DialogueContext:if session_id in self.sessions:return self.sessions[session_id]# 创建新会话context = DialogueContext(session_id=session_id,user_id=user_id,current_state=DialogueState.IDLE,current_intent=None,slots={},history=[],created_at=datetime.now(),updated_at=datetime.now())self.sessions[session_id] = contextreturn context

使用示例:

# 初始化对话系统
dialogue = DialogueSystem(llm=ChatGPT(),tool_registry=tool_registry,memory_system=memory_system
)# 处理用户消息
async def chat():responses = []# 第一轮:查询订单response = await dialogue.process_message(session_id="123",user_id="user_1",message="帮我查一下订单状态")responses.append(response)# 输出:好的,请提供订单号。# 第二轮:提供订单号response = await dialogue.process_message(session_id="123",user_id="user_1",message="A12345")responses.append(response)# 输出:您的订单 A12345 正在配送中,预计明天送达。# 第三轮:追问细节response = await dialogue.process_message(session_id="123",user_id="user_1",message="具体什么时候到?")responses.append(response)# 输出:根据物流信息,预计明天上午10:00-12:00送达。return responses# 运行对话
responses = await chat()
for r in responses:print(r)

关键实现细节

1. 意图理解

class IntentRecognizer:def __init__(self, llm):self.llm = llmasync def recognize(self,message: str,context: Dict[str, Any]) -> Intent:# 1. 准备提示词prompt = self._prepare_prompt(message,context)# 2. 调用 LLMresponse = await self.llm.generate(prompt)# 3. 解析结果intent = self._parse_response(response)# 4. 验证意图self._validate_intent(intent)return intentdef _prepare_prompt(self,message: str,context: Dict[str, Any]) -> str:return f"""请分析以下对话内容,识别用户意图:历史对话:{self._format_history(context.get('history', []))}当前状态:- 意图:{context.get('current_intent')}- 已知信息:{json.dumps(context.get('slots', {}), indent=2)}用户消息:{message}请返回:1. 意图名称2. 置信度3. 识别出的槽位信息"""

2. 状态管理

class StateManager:def __init__(self):self.state_handlers = {DialogueState.IDLE: self._handle_idle,DialogueState.WAITING_INPUT: self._handle_waiting,DialogueState.PROCESSING: self._handle_processing,DialogueState.ERROR: self._handle_error,DialogueState.COMPLETED: self._handle_completed}async def handle_state(self,context: DialogueContext,message: str) -> str:# 获取当前状态的处理器handler = self.state_handlers.get(context.current_state)if not handler:raise ValueError(f"未知状态:{context.current_state}")# 执行状态处理return await handler(context, message)async def _handle_waiting(self,context: DialogueContext,message: str) -> str:# 检查是否填充了等待的槽位slot_name = context.waiting_for_slotif self._is_valid_slot_value(slot_name,message):# 更新槽位context.slots[slot_name] = message# 继续处理return await self._continue_processing(context)else:# 重新询问return f"抱歉,这似乎不是有效的{slot_name},请重新输入。"

3. 上下文管理

class ContextManager:def __init__(self, memory_system):self.memory = memory_systemself.max_history = 10async def update_context(self,context: DialogueContext,message: str,response: str):# 1. 更新对话历史context.history.append({"role": "user","content": message,"timestamp": datetime.now()})context.history.append({"role": "assistant","content": response,"timestamp": datetime.now()})# 2. 限制历史长度if len(context.history) > self.max_history * 2:# 保存旧对话到长期记忆old_messages = context.history[:-self.max_history * 2]await self._save_to_memory(context.session_id,old_messages)# 保留最近的对话context.history = context.history[-self.max_history * 2:]# 3. 更新时间戳context.updated_at = datetime.now()async def _save_to_memory(self,session_id: str,messages: List[Dict]):# 将对话保存到长期记忆await self.memory.remember(content=self._format_messages(messages),metadata={"type": "dialogue","session_id": session_id,"timestamp": datetime.now()})

优化技巧

在实践中,我总结了一些提升用户体验的技巧:

1. 主动确认

class ConfirmationManager:def __init__(self, threshold: float = 0.8):self.threshold = thresholddef need_confirm(self,intent: Intent,context: DialogueContext) -> bool:# 检查是否需要确认if intent.confidence < self.threshold:return Trueif self._is_critical_operation(intent):return Truereturn Falsedef generate_confirmation(self,intent: Intent,context: DialogueContext) -> str:return f"""请确认您是否要{intent.description}?- 操作:{intent.name}- 参数:{json.dumps(intent.slots, indent=2)}回复"是"或"否"。"""

2. 错误恢复

class ErrorRecovery:async def recover(self,error: Exception,context: DialogueContext) -> str:# 分析错误analysis = await self._analyze_error(error)if analysis.can_retry:# 自动重试return await self._retry_operation(context)elif analysis.need_clarification:# 请求用户澄清return self._generate_clarification_question(analysis)else:# 友好的错误提示return self._generate_error_message(analysis)

3. 上下文压缩

class ContextCompressor:def compress_history(self,history: List[Dict],max_tokens: int) -> List[Dict]:# 1. 计算当前token数current_tokens = self._count_tokens(history)if current_tokens <= max_tokens:return history# 2. 提取关键信息key_messages = self._extract_key_messages(history)# 3. 压缩对话compressed = self._compress_messages(key_messages,max_tokens)return compresseddef _extract_key_messages(self,history: List[Dict]) -> List[Dict]:# 提取重要的对话轮次key_turns = []for i, msg in enumerate(history):if self._is_key_message(msg, history, i):key_turns.append(msg)return key_turns

实践心得

在实现和优化对话系统的过程中,我总结了几点经验:

  1. 以用户体验为中心

    • 理解用户真实意图
    • 保持对话的连贯性
    • 给出清晰的反馈
  2. 要有容错机制

    • 优雅处理异常
    • 支持意图澄清
    • 允许用户更正
  3. 注意性能优化

    • 合理管理上下文
    • 及时清理无用信息
    • 异步处理耗时操作

写在最后

一个好的对话系统应该像一个专业的客服,既要理解用户需求,又要高效地解决问题。它不仅要"能听懂",还要"会说话"。

在下一篇文章中,我会讲解如何实现 AI Agent 的安全机制。如果你对对话系统的设计有什么想法,欢迎在评论区交流。

相关文章:

AI Agent的多轮对话:提升用户体验的关键技巧

在前面的文章中&#xff0c;我们讨论了 AI Agent 的各个核心系统。今天&#xff0c;我想聊聊如何实现一个好用的多轮对话系统。说实话&#xff0c;这个话题我琢磨了很久&#xff0c;因为它直接影响到用户体验。 从一个槽点说起 还记得我最开始做对话系统时的一个典型场景&…...

在docker上部署nacos

一、首先下载nacos的docker镜像 docker pull nacos:2.5.0 二、然后下载nacos的安装包&#xff0c;这里是为了拿到他的配置文件。下载完解压缩后&#xff0c;以备后用 https://download.nacos.io/nacos-server/nacos-server-2.5.0.zip?spm5238cd80.6a33be36.0.0.2eb81e5d7mQ…...

ComfyUI实现老照片修复——AI修复老照片(ComfyUI-ReActor / ReSwapper)解决天坑问题及加速pip下载

AI修复老照片&#xff0c;试试吧&#xff0c;不一定好~~哈哈 2023年4月曾用过ComfyUI&#xff0c;当时就感慨这个工具和虚幻的蓝图很像&#xff0c;以后肯定是专业人玩的。 2024年我写代码去了&#xff0c;AI做图没太关注&#xff0c;没想到&#xff0c;现在ComfyUI真的变成了工…...

Win11画图工具没了怎么重新安装

有些朋友想要简单地把图片另存为其他格式&#xff0c;或是进行一些编辑&#xff0c;但是发现自己的Win11系统里面没有画图工具&#xff0c;这可能是因为用户安装的是精简版的Win11系统&#xff0c;解决方法自然是重新安装一下画图工具&#xff0c;具体应该怎么做呢&#xff1f;…...

Git Bash 配置 zsh

博客食用更佳 博客链接 安装 zsh 安装 Zsh 安装 Oh-my-zsh github仓库 sh -c "$(curl -fsSL https://install.ohmyz.sh/)"让 zsh 成为 git bash 默认终端 vi ~/.bashrc写入&#xff1a; if [ -t 1 ]; thenexec zsh fisource ~/.bashrc再重启即可。 更换主题 …...

《STL基础之hashtable》

【hashtable导读】STL为大家提供了丰富的容器&#xff0c;hashtable也是值得大家学习和掌握的基础容器&#xff0c;而且面试官经常会把它和hashmap混在一起&#xff0c;让同学们做下区分。因此关于hashtable的一些特性&#xff0c;比如&#xff1a;底层的数据结构、插入、查找元…...

Vue3组件重构实战:从Geeker-Admin拆解DataTable的最佳实践

一、前言 背景与动机 在当前的开发实践中&#xff0c;我们选择了开源项目 Geeker-Admin 作为前端框架的二次开发基础。其内置的 ProTable.vue 组件虽然提供了一定程度的开箱即用性&#xff0c;但在实际业务场景中逐渐暴露出设计上的局限性&#xff0c;尤其是其将 搜索条件表单…...

小智 AI 聊天机器人

小智 AI 聊天机器人 &#xff08;XiaoZhi AI Chatbot&#xff09; &#x1f449;参考源项目复现 &#x1f449; ESP32SenseVoiceQwen72B打造你的AI聊天伴侣&#xff01;【bilibili】 &#x1f449; 手工打造你的 AI 女友&#xff0c;新手入门教程【bilibili】 项目目的 本…...

关于圆周率的新认知

从自然对数底 的泰勒展开&#xff0c; 可以得出 的展开式&#xff0c; 它可以被认为是&#xff0c;以 0 为周期的单位 1 &#xff0c;以 1 为周期的单位 1 &#xff0c;以 2 为周期的单位 1 等所有自然数为周期的单位 1 分阶段合成&#xff08;体现为阶乘的倒数&#xff09;之…...

【趋势】《2024—2026金融科技十大趋势预测》一览

本白皮书基于新华三在金融行业的前沿实践和IDC的全球研究成果,深入分析了金融科技领域的十大关键趋势,旨在为金融机构提供前瞻性的战略指导和业务创新的参考。 导言 当前,在地缘政治冲突加剧、商业经济市场环境高度不确定、数字化业务加速发展的背景下,金融行业处于深度变…...

vim 中粘贴内容时提示: -- (insert) VISUAL --

目录 问题现象&#xff1a;解决方法&#xff1a;问题原因&#xff1a; 问题现象&#xff1a; 使用 vim 打开一个文本文件&#xff0c;切换到编辑模式后&#xff0c;复制内容进行粘贴时有以下提示&#xff1a; 解决方法&#xff1a; 在命令行模式下禁用鼠标支持 :set mouse …...

CAPL高级应用

CAPL高级应用 目录 CAPL高级应用1. 引言2. 多线程编程2.1 多线程编程简介2.2 多线程编程实现3. 数据库操作3.1 数据库操作简介3.2 数据库操作实现4. 网络通信4.1 网络通信简介4.2 网络通信实现5. 案例说明5.1 案例1:多线程编程实现5.2 案例2:数据库操作实现5.3 案例3:网络通…...

基于微信小程序的网上订餐管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…...

python的设计模式

设计模式是解决软件设计中常见问题的可重用解决方案。Python 作为一种灵活且强大的编程语言&#xff0c;支持多种设计模式的实现。以下是 Python 中常见的几种设计模式及其示例&#xff1a; 1. 单例模式&#xff08;Singleton Pattern&#xff09; 确保一个类只有一个实例&…...

EventBus事件总线的使用以及优缺点

EventBus EventBus &#xff08;事件总线&#xff09;是一种组件通信方法&#xff0c;基于发布/订阅模式&#xff0c;能够实现业务代码解耦&#xff0c;提高开发效率 发布/订阅模式 发布/订阅模式是一种设计模式&#xff0c;当一个对象的状态发生变化时&#xff0c;所有依赖…...

C++解决走迷宫问题:DFS、BFS算法应用

文章目录 思路:DFSBFSBFS和DFS的特点BFS 与 DFS 的区别BFS 的优点BFS 时间复杂度深度优先搜索(DFS)的优点深度优先搜索(DFS)的时间复杂度解释:空间复杂度总结:例如下面的迷宫: // 迷宫的表示:0表示可以走,1表示障碍 vector<vector<int>> maze = {{0, 0,…...

2025春招 SpringCloud 面试题汇总

大家好&#xff0c;我是 V 哥。SpringCloud 在面试中属于重灾区&#xff0c;不仅是基础概念、组件细节&#xff0c;还有高级特性、性能优化&#xff0c;关键是项目实践经验的解决方案&#xff0c;都是需要掌握的内容&#xff0c;正所谓打有准备的仗&#xff0c;秒杀面试官&…...

PostGIS笔记:PostgreSQL 数据库与用户 基础操作

数据库基础操作包括数据模型的实现、添加数据、查询数据、视图应用、创建日志规则等。我这里是在Ubuntu系统学习的数据库管理。Windows平台与Linux平台在命令上几乎无差异&#xff0c;只是说在 Windows 上虽然也能运行良好&#xff0c;但在性能、稳定性、功能扩展等方面&#x…...

Selenium配合Cookies实现网页免登录

文章目录 前言1 方案一&#xff1a;使用Chrome用户数据目录2 方案二&#xff1a;手动获取并保存Cookies&#xff0c;后续使用保存的Cookies3 注意事项 前言 在进行使用Selenium进行爬虫、网页自动化操作时&#xff0c;登录往往是一个必须解决的问题&#xff0c;但是Selenium每次…...

HarmonyOS简介:HarmonyOS核心技术理念

核心理念 一次开发、多端部署可分可合、自由流转统一生态、原生智能 一次开发、多端部署 可分可合 自由流转 自由流转可分为跨端迁移和多端协同两种情况 统一生态 支持业界主流跨平台开发框架&#xff0c;通过多层次的开放能力提供统一接入标准&#xff0c;实现三方框架快速…...

Unity URP 获取/设置 Light-Indirect Multiplier

Unity URP 获取/设置 Light-Indirect Multiplier 他喵的代码的字段名称叫&#xff1a;bounceIntensity ~~~~~~...

计算机网络 (60)蜂窝移动通信网

一、定义与原理 蜂窝移动通信网是指将一个服务区分为若干蜂窝状相邻小区并采用频率空间复用技术的移动通信网。其原理在于&#xff0c;将移动通信服务区划分成许多以正六边形为基本几何图形的覆盖区域&#xff0c;称为蜂窝小区。每个小区设置一个基站&#xff0c;负责本小区内移…...

解决.NET程序通过网盘传到Linux和macOS不能运行的问题

问题描述&#xff1a;.net程序用U盘传到虚拟机macOS和Linux可以正常运行&#xff0c;但是网盘传过去就不行。 解决方法&#xff1a; 这是文件权限的问题。当你通过U盘将文件传输到虚拟机的macOS和Linux系统时&#xff0c;文件的权限和所有权可能得到了保留或正确设置。但如果…...

LeetCode | 不同路径

一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f; 示例 1…...

渗透测试技法之口令安全

一、口令安全威胁 口令泄露途径 代码与文件存储不当&#xff1a;在软件开发和系统维护过程中&#xff0c;开发者可能会将口令以明文形式存储在代码文件、配置文件或注释中。例如&#xff0c;在开源代码托管平台 GitHub 上&#xff0c;一些开发者由于疏忽&#xff0c;将包含数据…...

【C语言】main函数解析

一、前言 在学习编程的过程中&#xff0c;我们很早就接触到了main函数。在Linux系统中&#xff0c;当你运行一个可执行文件&#xff08;例如 ./a.out&#xff09;时&#xff0c;如果需要传入参数&#xff0c;就需要了解main函数的用法。本文将详细解析main函数的参数&#xff…...

Vue3笔记——(二)

015 生命周期 组件的生命周期&#xff1a; 【时刻】 【调用特定的函数】 vue2生命周期 创建 beforeCreate、 created 挂载 beforeMounte、mounted 更新 beforeUpdate、updated 销毁 beforeDestroy、destroyed 生命周期、生命周期函数、生命周期钩子 vue3生命周期 创建 setup 挂…...

linux文件I/O

open 用于打开一个文件并返回一个文件描述符。文件描述符是一个整数&#xff0c;它在后续的文件操作中用于标识文件。 原型&#xff1a; int open(const char *pathname, int flags, mode_t mode);pathname&#xff1a;要打开的文件的路径flags&#xff1a;指定文件打开方式…...

利用双指针一次遍历实现”找到“并”删除“单链表倒数第K个节点(力扣题目为例)

Problem: 19. 删除链表的倒数第 N 个结点 文章目录 题目描述思路复杂度Code 题目描述 思路 1.欲找到倒数第k个节点&#xff0c;即是找到正数的第n-k1、其中n为单链表中节点的个数个节点。 2.为实现只遍历一次单链表&#xff0c;我们先可以使一个指针p1指向链表头部再让其先走k步…...

MySQL 8 不开通 CLONE 插件,建立主从关系

文章目录 前言一、主库操作二、从库操作三、主库操作四、测试总结 前言 MySQL 版本&#xff1a;8.0.36 MySQL 8 通过 CLONE 插件&#xff0c;搭建主从数据库详情参考链接文章 主库不开通 CLONE 插件&#xff0c;如何建立主从关系呢&#xff1f;本文简单介绍一下 一、主库操作…...

活动回顾和预告|微软开发者社区 Code Without Barriers 上海站首场活动成功举办!

Code Without Barriers 上海活动回顾 Code Without Barriers&#xff1a;AI & DATA 深入探索人工智能与数据如何变革行业 2025年1月16日&#xff0c;微软开发者社区 Code Without Barriers &#xff08;CWB&#xff09;携手 She Rewires 她原力在大中华区的首场活动“AI &…...

Direct Preference Optimization (DPO): 一种无需强化学习的语言模型偏好优化方法

论文地址&#xff1a;https://arxiv.org/pdf/2305.18290 1. 背景与挑战 近年来&#xff0c;大规模无监督语言模型&#xff08;LM&#xff09;在知识获取和推理能力方面取得了显著进展&#xff0c;但如何精确控制其行为仍是一个难题。 现有的方法通常通过**强化学习从人类反馈&…...

搜狐Android开发(安卓)面试题及参考答案

ViewModel 的作用及原理是什么? ViewModel 是 Android 架构组件中的一部分,主要作用是在 MVVM 架构中充当数据与视图之间的桥梁。它负责为视图准备数据,并处理与数据相关的业务逻辑,让视图(Activity、Fragment 等)专注于展示数据和与用户交互。比如在一个新闻应用中,Vie…...

蓝牙的一些基础知识(TODO)

前阵工作中遇到的。 iOS 和 iPadOS 支持的蓝牙描述文件 - 官方 Apple 支持 (中国) 在树莓派上定制蓝牙 Profile 通常需要修改或创建自定义的 Bluetooth 服务 (Profile) 来实现特定的功能&#xff0c;例如定制 Audio Sink、HID&#xff08;Human Interface Device&#xff09;、…...

Redis实战(黑马点评)——涉及session、redis存储验证码,双拦截器处理请求

项目整体介绍 数据库表介绍 基于session的短信验证码登录与注册 controller层 // 获取验证码PostMapping("code")public Result sendCode(RequestParam("phone") String phone, HttpSession session) {return userService.sendCode(phone, session);}// 获…...

WPF常见面试题解答

以下是WPF&#xff08;Windows Presentation Foundation&#xff09;面试中常见的问题及解答&#xff0c;涵盖基础概念、高级功能和实际应用&#xff0c;帮助你更好地准备面试&#xff1a; 基础概念 什么是WPF&#xff1f; WPF是微软开发的用于构建桌面应用程序的UI框架&#x…...

Nginx前端后端共用一个域名如何配置

在 Nginx 中配置前端和后端共用一个域名的情况&#xff0c;通常是通过路径或子路径将请求转发到不同的服务。以下是一个示例配置&#xff0c;假设&#xff1a; 前端静态文件在 /var/www/frontend/。 后端 API 服务运行在 http://127.0.0.1:5000。 域名是 example.com&#xff…...

DeepSeek-R1-Distill-Qwen-1.5B:最佳小型LLM?

DeepSeek掀起了生成式AI领域的风暴。 首先推出DeepSeek-v3,现在推出DeepSeek-R1,这两款模型都打破了所有基准,并且完全开源。 但今天我们不是在讨论这两款超级模型,而是讨论DeepSeek-R1的一个蒸馏版本——DeepSeek-R1-Distill-Qwen-1.5B,它可能是今天被低估的版本,虽然…...

wampserver + phpstrom 调试配置

step 1 点击任务栏wampserver图标->php->php.ini[apache module] 在文件最后面,确保这些值被定义且跟以下的一样 xdebug.mode debug xdebug.start_with_request yes xdebug.client_port 9003 xdebug.client_host 127.0.0.1step 2 按如下配置 step3 下断点,运行即…...

MySQL分表自动化创建的实现方案(存储过程、事件调度器)

《MySQL 新年度自动分表创建项目方案》 一、项目目的 在数据库应用场景中&#xff0c;随着数据量的不断增长&#xff0c;单表存储数据可能会面临性能瓶颈&#xff0c;例如查询、插入、更新等操作的效率会逐渐降低。分表是一种有效的优化策略&#xff0c;它将数据分散存储在多…...

RabbitMQ 架构分析

文章目录 前言一、RabbitMQ架构分析1、Broker2、Vhost3、Producer4、Messages5、Connections6、Channel7、Exchange7、Queue8、Consumer 二、消息路由机制1、Direct Exchange2、Topic Exchange3、Fanout Exchange4、Headers Exchange5、notice5.1、备用交换机&#xff08;Alter…...

Spring Boot 无缝集成SpringAI的函数调用模块

这是一个 完整的 Spring AI 函数调用实例&#xff0c;涵盖从函数定义、注册到实际调用的全流程&#xff0c;以「天气查询」功能为例&#xff0c;结合代码详细说明&#xff1a; 1. 环境准备 1.1 添加依赖 <!-- Spring AI OpenAI --> <dependency><groupId>o…...

如何跨互联网adb连接到远程手机-蓝牙电话集中维护

如何跨互联网adb连接到远程手机-蓝牙电话集中维护 --ADB连接专题 一、前言 随便找一个手机&#xff0c;安装一个App并简单设置一下&#xff0c;就可以跨互联网的ADB连接到这个手机&#xff0c;从而远程操控这个手机做各种操作。你敢相信吗&#xff1f;而这正是本篇想要描述的…...

MySQL--》深度解析InnoDB引擎的存储与事务机制

目录 InnoDB架构 事务原理 MVCC InnoDB架构 从MySQL5.5版本开始默认使用InnoDB存储引擎&#xff0c;它擅长进行事务处理&#xff0c;具有崩溃恢复的特性&#xff0c;在日常开发中使用非常广泛&#xff0c;其逻辑存储结构图如下所示&#xff0c; 下面是InnoDB架构图&#xf…...

python:taichi 模拟一维波场

在 Taichi 中模拟一维波场&#xff0c;通常是利用 Taichi 编程语言的特性来对一维空间中的波动现象进行数值模拟&#xff0c;以下是相关介绍&#xff1a; 原理基础 波动方程&#xff1a;一维波动方程的一般形式为 &#xff0c;其中 u(x,t) 表示在位置x 和时间t 处的波的状态&…...

力扣【347. 前 K 个高频元素】Java题解(堆)

TopK问题&#xff0c;我们直接上堆。 首先遍历一次然后把各个数字的出现频率存放在哈希表中便于后面堆的操作。 因为是出现频率前 k 高&#xff0c;所以用小顶堆&#xff0c;当我们遍历的频率值大于堆顶值时就可以替换堆顶。 代码&#xff1a; class Solution {public int[] …...

仿12306项目选座购票业务逻辑

12306项目选座购票业务逻辑 文章目录 12306项目选座购票业务逻辑项目分享选座逻辑购票逻辑更新余票逻辑用户选座功能服务器售票功能0. 业务数据校验1. 保存确认订单表&#xff0c;状态初始化2. 查出余票记录&#xff0c;需要得到真是的库存3. 扣减余票数量&#xff0c;并判断余…...

2024年面对不确定性

24年处在了十字路口&#xff0c;面对工作、家庭、生活的责任&#xff0c;一切变得不确定了&#xff0c;量子力学给了我们新的认识世界的角度&#xff0c;不确定性才是这个世界的底色&#xff0c;我们怎么选择&#xff1f; 不停的思考 霍金在大设计书中给出了深刻的哲学思想&a…...

Nginx的负载均衡

一、概述 Nginx负载均衡是一种通过将客户端请求分发到多个后端服务器的技术&#xff0c;旨在提高系统的吞吐量、可用性和容错性。 二、Nginx负载均衡工作原理 Nginx作为反向代理服务器&#xff0c;接收客户端的请求&#xff0c;并根据配置的负载均衡算法将请求转发到后端服务…...

vue3组件el-table报错

传给table标签的data不是数组就会报错&#xff0c; 摁着商品管理代码找了半天也没发现哪里错了&#xff0c;而且关闭报错表格数据能正常显示&#xff0c; 。。。 最后发现我还有个订单管理页面&#xff0c;这里面的data初始化成ref( )了&#xff0c;把这个组件注释掉&#xf…...