GPTCache:大模型应用语义缓存实战,提速降本利器

news2026/5/6 1:05:31
1. 项目概述当大模型应用需要“缓存”时如果你正在开发基于大语言模型LLM的应用比如一个智能客服、一个文档总结工具或者一个代码生成助手那么“响应速度”和“API调用成本”一定是让你头疼的两座大山。每次用户提问应用都要将问题原文发送给像 OpenAI GPT、Anthropic Claude 这样的云端模型等待其“思考”并生成答案。这个过程慢则几秒快则几百毫秒对于追求即时交互体验的应用来说简直是不可接受的延迟。更别提每次调用都要真金白银地付费当用户量上来重复或相似的问题反复调用成本就像开了闸的水龙头。这就是zilliztech/GPTCache这个项目要解决的核心痛点。简单说GPTCache 是一个专为大语言模型应用设计的智能语义缓存层。它的目标不是替代大模型而是成为大模型前面的一个“智能助理”把那些重复的、相似的、或者已经计算过的答案直接从本地或近端的缓存中取出来快速返回给用户。这听起来像是给数据库加缓存比如 Redis但难点在于用户的自然语言提问千变万化同一个意思可能有十几种不同的问法。传统的基于关键词精确匹配的缓存比如把问题字符串当 Key在这里完全失效。GPTCache 的聪明之处在于它引入了“语义相似度”的概念。它会把用户的问题Query通过一个嵌入模型Embedding Model转换成一段高维向量Vector然后在一个向量数据库Vector Database里寻找与历史缓存问题向量最相似的那些记录。如果相似度超过你设定的阈值它就不再劳烦后方昂贵的大模型而是直接返回之前缓存好的答案。这样一来对于高频、相似的问题响应速度可以从秒级降到毫秒级同时成本也能大幅下降。我最早在内部项目中引入 GPTCache 时对于一个问答知识库场景直接将重复问题的响应时间降低了 95% 以上月度 API 费用节省了接近 40%效果非常直观。2. 核心架构与设计哲学2.1 为什么是“语义缓存”而非“键值缓存”要理解 GPTCache 的设计首先要明白传统缓存的局限性。对于一个标准的缓存系统如 Redis、Memcached它的工作模式是Key-Value存储。你需要一个精确的、唯一的 Key 来索引对应的 Value。在 LLM 场景下如果我们把用户的原始问题字符串经过简单哈希后作为 Key那么只有字面完全一致的问题才能命中缓存。例如“北京今天的天气怎么样”和“今天北京天气如何”虽然语义相同但字符串不同哈希值天差地别缓存就会失效。这完全无法应对自然语言的灵活性和多样性。GPTCache 的核心创新在于将“精确匹配”转变为“模糊的语义匹配”。它借鉴了现代搜索和推荐系统的思路将文本映射到向量空间。在这个空间里语义相近的文本其向量表示在几何上也彼此接近。因此缓存命中与否不再取决于字符串是否一致而是取决于两个问题向量之间的“距离”如余弦相似度是否足够小。这个设计带来了几个关键优势高命中率即使问题表述不同只要核心意图一致就能触发缓存极大提升了缓存的利用率。应对模糊查询用户提问常常带有错别字、缩写或口语化表达语义缓存在一定程度上能容忍这些噪声。支持泛化对于一些事实性、答案固定的问题如“公司的退货政策是什么”无论用户怎么问都能快速返回标准答案。2.2 GPTCache 的核心工作流程GPTCache 的运作可以简化为一个清晰的管道Pipeline我习惯把它分为三个阶段前处理、相似度检索与决策、后处理。第一阶段前处理与向量化当一个新的用户查询到来时它不会直接被拿去检索。GPTCache 首先会对其进行预处理。这一步是可配置的但通常包括清洗去除多余空格、特殊字符。归一化比如将所有文本转为小写根据场景决定。关键信息提取/重写对于一些复杂查询可以调用一个小模型或规则提取出问题的核心实体或意图生成一个更规范的查询文本用于向量化。这能进一步提升语义匹配的准确性。预处理后的文本会被送入一个嵌入模型转换为向量。这里的选择非常关键。你可以使用 OpenAI 的text-embedding-ada-002也可以使用开源的all-MiniLM-L6-v2或bge系列模型。GPTCache 的模块化设计允许你灵活替换。对于延迟敏感的场景一个本地运行的轻量级嵌入模型是更好的选择。第二阶段相似度检索与缓存决策生成的查询向量会被送入向量数据库进行相似度搜索。GPTCache 原生支持 Milvus其母公司 Zilliz 的产品同时也集成了 Redis、SQLite通过vectorlite扩展等多种后端甚至支持纯内存的FAISS。这一步会找出与当前查询向量最相似的 K 个历史缓存向量。接下来进入缓存决策环节这是 GPTCache 的“大脑”。它需要判断最相似的那个历史缓存是否“足够相似”到可以代表当前查询这个判断标准由一个相似度评估器来执行。最简单的评估器就是设置一个全局的相似度阈值例如 0.8。如果最高相似度得分超过阈值则判定为缓存命中。但实际情况更复杂。有些场景下不同类别的问题对相似度的容忍度不同。因此GPTCache 支持更复杂的评估器例如引入一个分类模型先判断问题类型再应用不同的阈值。甚至你可以接入一个大模型如 GPT-3.5-Turbo作为“裁判”让它来判断两个问题是否等价。这虽然会增加一点开销但在对准确性要求极高的场景下非常有用。如果决策为“命中”系统将直接返回对应的缓存答案流程结束。如果“未命中”则进入第三阶段。第三阶段调用大模型与缓存回填对于未命中的查询GPTCache 会将其原样或经过轻微处理后转发给背后真正的大语言模型如 OpenAI API。拿到大模型的回复后在返回给用户之前GPTCache 会执行“缓存回填”操作将本次的查询向量, 回复对存储到向量数据库中以备未来之需。这里有一个精妙的细节缓存什么不仅仅是答案文本本身。GPTCache 允许你关联存储额外的元数据Metadata例如本次查询的 Token 消耗、模型名称、生成时间、甚至是一些业务标签。这些元数据在后续的缓存管理、分析和清理策略中会非常有用。2.3 模块化设计像搭积木一样构建你的缓存GPTCache 不是一个黑盒它最大的优点之一是高度模块化。整个流程中的几乎每一个组件都是可插拔的嵌入函数负责文本转向量。你可以换用任何支持encode接口的模型。向量存储负责存、取、搜向量。从本地的 SQLitevectorlite 到分布式的 Milvus 集群按需选择。相似度评估器负责决定是否命中。从简单的阈值法到复杂的模型评估。大模型适配器负责与后端的 LLM API 交互。官方已支持 OpenAI、Azure OpenAI、Anthropic、Cohere 等你也可以自己扩展。缓存管理器负责缓存的淘汰策略LRU、FIFO等、过期时间设置、以及基于元数据的清理。这种设计意味着你可以根据你的应用规模、性能要求、成本预算组装出一个最适合你的缓存系统。对于一个快速验证原型你可以用all-MiniLMSQLite阈值评估器五分钟就能跑起来。对于生产级的高并发应用你可以采用bge-largeMilvus 集群基于大模型的评估器。3. 从零开始搭建你的第一个语义缓存理论说了这么多我们来点实际的。下面我将带你一步步搭建一个最简单的 GPTCache用于缓存 OpenAI ChatGPT 的回复。我们将使用轻量级组件确保你在个人电脑上也能顺利运行。3.1 环境准备与依赖安装首先确保你的 Python 环境是 3.8 及以上版本。创建一个新的虚拟环境是一个好习惯。python -m venv gptcache-env source gptcache-env/bin/activate # Linux/Mac # 或 gptcache-env\Scripts\activate # Windows然后安装 GPTCache 的核心库以及我们将用到的组件。为了最小化初始配置我们使用轻量级的嵌入模型和向量存储。pip install gptcache pip install sentence-transformers # 用于本地嵌入模型 pip install openai # 用于调用真正的 OpenAI APIsentence-transformers库提供了高质量的开源嵌入模型我们选用all-MiniLM-L6-v2它在速度和效果上取得了很好的平衡且无需 GPU 也能快速运行。3.2 基础配置与初始化接下来我们写一个 Python 脚本初始化 GPTCache 的核心组件。from gptcache import Cache from gptcache.embedding import SentenceEmbedding from gptcache.adapter import openai from gptcache.manager import get_data_manager, CacheBase, VectorBase from gptcache.similarity_evaluation.distance import SearchDistanceEvaluation import openai as original_openai # 1. 初始化嵌入模型使用 SentenceTransformer 的 all-MiniLM-L6-v2 embedding_model SentenceEmbedding(modelall-MiniLM-L6-v2) # 2. 初始化向量存储和缓存数据管理器 # 我们使用 SQLite 作为缓存元数据的存储CacheBase使用基于 SQLite 的 vectorlite 作为向量存储VectorBase # 它们会被封装在一个 DataManager 中 data_manager get_data_manager(cache_baseCacheBase(sqlite), vector_baseVectorBase(vectorlite, dimensionembedding_model.dimension)) # 3. 初始化相似度评估器这里使用“搜索距离评估”本质上是设定一个相似度阈值 # 我们设定余弦相似度大于 0.8 才认为是相同问题 evaluation SearchDistanceEvaluation(max_distance0.2, positiveFalse) # 注意这里的 max_distance 是距离不是相似度。余弦距离 1 - 余弦相似度。 # 所以 max_distance0.2 对应最小相似度 0.8。 # 4. 构建并初始化缓存 cache Cache() cache.init( embedding_funcembedding_model.to_embeddings, data_managerdata_manager, similarity_evaluationevaluation, )注意VectorBase(vectorlite)需要在你的系统上安装vectorlite扩展。对于快速测试你也可以使用纯内存的VectorBase(faiss, dimension...)但重启后缓存会丢失。生产环境建议使用更稳定的后端如 Redis 或 Milvus。3.3 与大模型适配器集成现在我们需要把初始化好的缓存与 OpenAI 的接口“嫁接”起来。GPTCache 的adapter模块提供了非常优雅的方式。# 设置你的真实 OpenAI API Key请替换成你自己的 original_openai.api_key sk-your-real-openai-api-key-here # 使用 GPTCache 包装 OpenAI 的 ChatCompletion.create 方法 # 此后通过 cached_chat_completion.create 发起的调用都会先走缓存逻辑。 cached_chat_completion openai.ChatCompletion.create # 为了对比我们保留一个原始的、不走缓存的客户端 raw_openai_client original_openai.ChatCompletion3.4 进行第一次缓存查询与测试让我们写一个测试函数来直观感受缓存的效果。import time def ask_with_cache(question): 使用缓存的提问函数 start_time time.time() response cached_chat_completion( modelgpt-3.5-turbo, messages[{role: user, content: question}], cache_objcache # 关键传入我们配置好的缓存对象 ) latency (time.time() - start_time) * 1000 # 毫秒 answer response.choices[0].message.content return answer, latency, response._gptcache_id # 内部缓存ID用于调试 def ask_without_cache(question): 不使用缓存的提问函数 start_time time.time() response raw_openai_client.create( modelgpt-3.5-turbo, messages[{role: user, content: question}] ) latency (time.time() - start_time) * 1000 answer response.choices[0].message.content return answer, latency # 测试问题 questions [ 解释一下量子计算的基本原理。, 量子计算的基本原理是什么, # 语义相同表述不同 Python 中如何读取一个 CSV 文件, 用 Python 读取 CSV 文件的方法。, # 语义相同表述不同 太阳系最大的行星是哪个, ] print(首次运行填充缓存:) for i, q in enumerate(questions): answer, latency, cache_id ask_with_cache(q) print(f Q{i1}: {q[:30]}...) print(f 耗时: {latency:.0f}ms, 缓存ID: {cache_id}) # 首次调用cache_id 应为 None 或新生成的ID表示未命中 print(\n--- 等待2秒模拟用户间隔 ---\n) time.sleep(2) print(第二次运行应命中缓存:) for i, q in enumerate(questions): answer, latency, cache_id ask_with_cache(q) print(f Q{i1}: {q[:30]}...) print(f 耗时: {latency:.0f}ms, 缓存ID: {cache_id}) # 对于问题2和4即使文本不同但因为语义相似度高应该会命中问题1和3的缓存耗时极短。 # 问题5是新的会再次调用大模型。运行这段代码你会看到明显的对比。首次调用每个问题都需要网络往返 OpenAI耗时在 1-3 秒左右。第二次运行时对于语义相似的问题如 Q1 和 Q2第二个问题的响应时间会骤降到几十毫秒甚至几毫秒这就是缓存命中的威力。同时你的 OpenAI 账户账单上第二次调用 Q2 和 Q4 时不会产生新的 API 调用费用。4. 高级配置与生产级考量一个基础的缓存系统跑起来后我们需要考虑它在真实生产环境中面临的问题准确性、性能、资源管理和可观测性。4.1 优化语义匹配准确性超越简单阈值默认的全局相似度阈值如 0.8可能“一刀切”。对于事实性问题如“中国的首都是哪”阈值可以设得很高0.95确保答案绝对准确。对于创意性或开放性问題如“写一首关于春天的诗”阈值可以设低一些0.7因为相似的问题期待相似的风格但不必完全一致。GPTCache 允许你定义更复杂的相似度评估器。例如你可以实现一个两级评估器第一级快速向量相似度筛选阈值 0.7。第二级对通过第一级筛选的候选用一个小型文本分类模型或规则引擎判断问题是否属于“事实性”、“编程”、“创意”等类别再应用类别特定的精细阈值。更激进但也更准确的方法是引入LLM 作为评估器。虽然这会增加少量延迟和成本但对于关键业务可以确保缓存命中结果的可靠性。from gptcache.similarity_evaluation import ExactMatchEvaluation, SimilarityEvaluation class HybridEvaluation(SimilarityEvaluation): def __init__(self, embedding_threshold0.8): self.embedding_threshold embedding_threshold self.exact_matcher ExactMatchEvaluation() def evaluation(self, src_dict, cache_dict, **kwargs): # 先尝试精确匹配字符串完全一致成本最低 exact_score self.exact_matcher.evaluation(src_dict, cache_dict, **kwargs) if exact_score 0.9: # 假设精确匹配分数很高 return exact_score # 精确匹配失败再计算语义相似度 embedding_score self.vector_similarity(src_dict[embedding], cache_dict[embedding]) if embedding_score self.embedding_threshold: return embedding_score # 语义相似度也不够返回低分 # 语义相似度足够高可以进一步用更重的方法校验此处简化 # 例如可以比较问题中的核心实体是否一致 return min(1.0, embedding_score 0.05) # 给予小幅加分表示通过校验4.2 性能调优与资源管理向量索引的选择对于百万级以下的缓存条目使用HNSWHierarchical Navigable Small World索引通常能在速度和精度间取得最佳平衡。GPTCache 在集成 Milvus 或 FAISS 时可以指定索引类型。对于海量数据可能需要考虑IVF系列索引进行量化压缩。缓存淘汰策略缓存不能无限增长。GPTCache 的CacheManager支持常见的淘汰策略。LRU (Least Recently Used)淘汰最久未使用的。这是最通用有效的策略。LFU (Least Frequently Used)淘汰使用频率最低的。适合热点数据非常集中的场景。基于大小的淘汰当缓存条目数或总大小超过限制时淘汰旧的或低价值的数据。你可以根据业务特点组合策略。例如为每条缓存记录附加一个“价值分”可根据命中次数、节省的成本计算实现一个基于价值的淘汰策略。分版本缓存当你的后端大模型升级时例如从gpt-3.5-turbo-0125升级到gpt-3.5-turbo-0301旧缓存可能不再适用。GPTCache 允许你在存储时添加元数据如model_version: 0125。在检索时可以要求必须匹配该元数据字段从而自动隔离不同版本的缓存避免返回过时或不兼容的答案。4.3 可观测性与监控一个运行中的缓存系统必须是透明的。你需要知道缓存命中率这是衡量缓存效益的核心指标。GPTCache 的回调函数或日志可以帮你统计。平均响应时间节省区分缓存命中和未命中的延迟。成本节省估算根据命中次数和每次调用的平均 Token 消耗估算节省的 API 费用。我建议在初始化缓存时就集成日志和指标收集。import logging from gptcache.processor.post import temperature_softmax logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) class MetricsCollector: def __init__(self): self.hits 0 self.misses 0 def before_cache_hit(self, *args, **kwargs): self.hits 1 logger.info(fCache HIT! Total hits: {self.hits}) def before_cache_miss(self, *args, **kwargs): self.misses 1 logger.info(fCache MISS. Total misses: {self.misses}) property def hit_rate(self): total self.hits self.misses return self.hits / total if total 0 else 0 collector MetricsCollector() # 在 cache.init 中通过 hook 注册回调 cache.init( embedding_funcembedding_model.to_embeddings, data_managerdata_manager, similarity_evaluationevaluation, post_process_messages_func[temperature_softmax], # 一个后处理例子温度调整 # 注册命中/未命中回调 before_cache_hit_funccollector.before_cache_hit, before_cache_miss_funccollector.before_cache_miss, )运行一段时间后你就可以通过collector.hit_rate获取命中率并输出到你的监控系统如 Prometheus。5. 实战避坑指南与进阶技巧在实际项目中摸爬滚打后我积累了一些在官方文档里不一定找得到的经验和教训。5.1 常见问题与排查清单问题现象可能原因排查步骤与解决方案缓存命中率极低1. 相似度阈值设置过高。2. 嵌入模型不适合当前领域。3. 问题预处理不当噪声过多。4. 向量数据库索引未构建或类型不佳。1. 逐步调低阈值观察命中率变化找到一个平衡点。2. 尝试领域相关的嵌入模型如针对代码的codebert针对科学文献的specter。3. 加强查询清洗和归一化例如移除停用词、进行词干提取。4. 检查向量索引是否创建成功对于大规模数据确保使用了合适的索引如 HNSW。缓存返回了错误答案1. 语义相似但意图不同的查询被错误匹配如“苹果公司” vs “吃苹果”。2. 缓存答案已过时信息更新。3. 评估器逻辑有缺陷。1. 引入更严格的评估器如结合关键词匹配或轻量级意图分类。2. 为缓存条目设置 TTL生存时间或建立基于数据源的缓存失效机制。3. 在评估器中加入对否定词、疑问词等关键语义元素的检查。缓存系统延迟反而增加1. 向量搜索在数据量大时变慢。2. 嵌入模型本身推理慢。3. 复杂的评估器开销大。1. 优化向量索引参数如 HNSW 的ef_construction和M或考虑分片。2. 换用更轻量的嵌入模型或对嵌入进行量化。3. 将复杂评估器改为异步执行或仅对高相似度候选进行。内存或磁盘占用增长过快1. 缓存条目无限制增长。2. 存储的答案或元数据过大。1. 启用并合理配置 LRU 等淘汰策略。2. 压缩存储的答案文本或只存储答案的指纹/摘要但需权衡重构成本。3. 定期清理过期或低价值的缓存条目。5.2 提升效能的独家技巧技巧一分层缓存策略不要把所有鸡蛋放在一个篮子里。我通常实施一个两层缓存策略L1 缓存内存精确匹配使用一个简单的{hash(query): answer}字典用于存储完全相同的查询。因为字符串哈希和内存查找的速度远快于向量搜索。这能拦截掉大量的完全重复请求。L2 缓存向量数据库语义匹配即 GPTCache 主流程用于处理语义相似的查询。 查询到来时先查 L1命中则直接返回未命中再走 L2 的向量语义检索流程。这个简单的组合能显著提升整体性能。技巧二动态相似度阈值固定的阈值可能不是最优的。我们可以根据查询长度和问题类型动态调整阈值。例如对于短查询如“你好”其语义空间模糊应使用更高的阈值以避免误匹配。对于长查询如包含具体技术细节的段落其向量表示更独特可以适当降低阈值。可以在预处理阶段估算查询的信息密度或长度从而动态选择阈值。技巧三缓存“答案模板”而非完整答案对于一些格式化强的场景比如生成 SQL 查询、创建特定格式的 JSON答案的结构是固定的只有参数不同。我们可以缓存“答案模板”和“参数提取规则”。当相似查询命中时系统从新查询中提取参数并填入缓存的模板中生成最终答案。这极大地提高了缓存的泛化能力。例如对于“查询张三的订单”和“查找李四的订单”可以命中同一个模板SELECT * FROM orders WHERE customer_name {name}。技巧四谨慎处理流式响应目前GPTCache 对 OpenAI 的流式响应streaming支持需要特别注意。缓存完整的流式响应并在命中时重新“流式”吐出在实现上有些挑战。一个务实的做法是对于明确可能被高频重复查询、且答案较短的内容在应用层将其转为非流式调用并缓存对于真正的长文本生成或对话流则绕过缓存。你需要根据业务场景做出权衡。5.3 与现有技术栈的集成GPTCache 可以很容易地集成到你的现有服务中作为独立服务你可以将 GPTCache 封装成一个 gRPC 或 HTTP 服务你的应用客户端将所有查询先发送到这个缓存服务。这种方式解耦性好便于独立升级和扩容。作为应用内嵌库如上文示例直接在应用进程中初始化缓存。这种方式延迟最低适合对延迟极度敏感的场景。与 LangChain/LlamaIndex 集成如果你在使用这些流行的 LLM 应用框架GPTCache 也提供了相应的集成接口通常只需几行代码就能为你的 Chain 或 Index 添加缓存能力大幅降低链式调用的总延迟和成本。在我经历的一个生产项目中我们将 GPTCache 以独立服务的形式部署前方用 Nginx 做负载均衡后方连接 Milvus 集群和 OpenAI API。通过细致的监控和调优该系统平稳支撑了日均百万级的查询平均响应时间从 1.2 秒降低到 150 毫秒月度成本节省了 35% 以上。这个过程并非一蹴而就需要持续观察指标、调整参数、优化嵌入模型。但投入是值得的它为你构建高性能、低成本的 LLM 应用提供了一个坚实而智能的基础设施层。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2577710.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…