尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

AI 应用缓存设计:上下文、结果与一致性

AI 应用缓存设计:上下文、结果与一致性 一个常见场景是这样的你做了一个企业知识库问答应用。用户每问一次服务端都要读取会话历史、拼 prompt、查向量库、调用模型、做引用校验再把答案和来源写回数据库。功能上线后接口耗时明显变长Redis CPU 看起来还很低但模型调用费用先涨起来了。更麻烦的是知识库刚更新用户偶尔还能看到旧答案会话历史很长时模型又开始答非所问。这类问题不能靠一句“加缓存”解决。AI 应用里的缓存至少有三类对象上下文缓存服务于 prompt 构造检索缓存服务于重复向量检索结果缓存服务于重复生成。三者的命中率、失效方式、一致性要求和故障影响都不一样。本文的核心结论是Redis 适合承担高频、短生命周期、可重算、边界清楚的数据强一致、可审计、可恢复的数据仍应放在数据库、对象存储或专门的业务系统里。缓存设计的关键不是多放几个 key而是把 key、TTL、版本号、权限范围和回源路径设计清楚。先定义缓存对象而不是先写 Redis key很多 AI 应用一开始会把所有中间数据都塞进 Redis会话历史、用户画像、检索结果、模型输出、流式响应片段、工具调用结果、权限信息。短期看开发快长期会暴露两个问题。第一数据语义不清。一个 key 里到底是可丢弃的临时上下文还是用户可追溯的历史记录如果 Redis 数据丢了系统能不能恢复如果不能恢复Redis 就不应该是唯一存储。第二失效策略互相污染。结果缓存希望尽量复用TTL 可以相对长上下文缓存更接近会话状态TTL 通常较短还需要按轮次、token 数和用户行为主动裁剪。把它们混在一起会导致“该留的被删该删的还在”。可以先用下面这张表划清边界缓存对象典型输入处理动作输出推荐存储一致性要求会话短上下文tenant、user、session、最近 N 轮消息裁剪、排序、拼接prompt 片段Redis DB 落盘Redis 可过期DB 保底会话摘要历史消息、摘要版本增量总结summary textDB 为主Redis 加速需要可回放检索结果query、scope、kb_version向量检索、重排doc ids、scoresRedis 短缓存知识库发布后失效模型结果规范化问题、prompt 版本、模型参数LLM 生成、审核answer、citationsRedis 可选取决于业务容忍度工具调用结果tool、参数、租户、权限API 调用、格式化JSON 结果Redis 短缓存外部状态变化需谨慎权限范围user、role、org、resource鉴权计算scope_hash权限系统为准不应只依赖缓存判断标准很简单如果数据丢失后可以通过数据库、向量库或模型重新计算并且重新计算成本明显高于 Redis 读取成本它适合缓存如果数据丢失会影响审计、计费、用户历史或权限判断它不能只放 Redis。下面的流程图表达的是缓存分层而不是要求系统一定拆成这么多服务。Redis 不是数据库和向量库的替代品它拦在高频链路上减少重复拼装、重复检索和重复生成。上下文缓存缓存可拼 prompt 的材料上下文缓存最容易被误用。很多实现会把完整 messages 数组按 session_id 放进 Redis每轮请求取出、追加、再写回。小流量时能跑活跃用户变多后会遇到三个失败模式value 越来越大网络传输变慢并发请求互相覆盖prompt 超出 token 限制后模型输出质量下降。更稳妥的做法是把上下文拆成三段最近消息、长期摘要、外部检索材料。最近消息适合放 Redis List 或 HashTTL 跟会话活跃时间绑定例如 30 分钟到 2 小时。长期摘要建议落数据库Redis 只缓存当前摘要版本。外部检索材料不要混入会话历史而是在每次请求里按 query、权限范围和知识库版本单独检索或读取检索缓存。一个可落地的 key 设计如下ctx:recent:{tenant}:{user}:{session} # 最近 N 条消息ctx:summary:{tenant}:{user}:{session}:v{ver} # 当前摘要ctx:lock:{tenant}:{user}:{session} # 并发写锁写入时不要无限追加。每条消息应保留 role、content、created_at、trace_id 等必要字段并在写入后裁剪。并发场景下可以用短 TTL 锁或单线程队列串行化同一 session 的追加动作。function append_message(req, message): key ctx:recent: req.tenant : req.user : req.session lock_key ctx:lock: req.tenant : req.user : req.session if not redis.set(lock_key, req.trace_id, nxtrue, ex3): return retry_later() try: redis.rpush(key, json_encode(message)) redis.ltrim(key, -12, -1) redis.expire(key, 3600) finally: release_lock_if_owner(lock_key, req.trace_id)构造 prompt 时输入是用户新问题、最近消息、摘要和检索材料处理动作是裁剪、去重、按角色排序、估算 token输出才是模型可消费的 messages。Redis miss 时应从数据库回源最近历史或摘要摘要不存在时降级为最近消息消息格式损坏时丢弃该条并记录日志不要让一次脏缓存阻断整次问答。Prompt 部分预算建议超出时动作失败模式系统指令固定保留不裁剪版本化管理prompt 版本混乱会话摘要10%-20%重新摘要或压缩摘要摘要过期、事实残留最近消息20%-30%从旧到新裁剪历史过长、角色错乱检索材料40%-60%减少文档数或段落长度引用无关、召回过多当前问题必须保留不裁剪用户意图丢失上下文缓存的观测信号也应具体平均 value 大小、prompt token 分布、Redis miss 后 DB 回源耗时、摘要生成次数、上下文裁剪次数、消息解析失败次数。如果线上出现“答非所问”不要先归因于模型要先看本次请求实际拼进去的上下文。结果缓存缓存边界一致的结果而不是字面相同的问题结果缓存的收益最直接。同一个租户反复问“报销流程是什么”如果知识库版本、权限范围、系统 prompt、模型参数都没变就没有必要每次都查向量库和调用模型。但结果缓存不能只用原始问题做 key。用户问“报销流程是什么”和“公司报销怎么走”可能语义相近却不是字面相同同一句问题在不同租户、不同权限、不同知识库版本下答案也可能不同。缓存键必须包含影响答案的边界。推荐把检索缓存和结果缓存分开retrieval:{tenant}:{scope}:{kb_version}:{query_hash}result:exact:{tenant}:{scope}:{kb_version}:{prompt_version}:{model}:{request_hash}request_hash 不应直接 hash 原始输入而应基于规范化后的请求材料生成。规范化可以包括去掉首尾空白、统一大小写、规范标点、稳定排序 JSON 字段但不要擅自做语义改写否则可能把不同问题合并成同一个 key。function build_result_key(req): payload { tenant: req.tenant_id, scope: req.permission_scope_hash, kb_version: req.kb_version, prompt_version: req.system_prompt_version, model: req.model_name, temperature: req.temperature, tools: sort(req.enabled_tools), question: normalize(req.question) } return result:exact: sha256(stable_json(payload))这里有一个工程取舍temperature 较高、回答带随机性时结果缓存会让输出更固定。对客服 FAQ、政策解释、内部知识库问答这是优点对创意写作、头脑风暴、多样化推荐这可能是缺点。结果缓存不应是全局开关应该按场景配置。场景是否建议结果缓存TTL 建议判断标准企业知识库 FAQ建议10 分钟到数小时答案依赖知识库版本工单分类、意图识别建议数小时到一天输出结构稳定结构化抽取可考虑数分钟到数小时输入重复率高长文生成谨慎几分钟上下文差异大代码生成谨慎短 TTL依赖仓库、版本、上下文实时数据查询通常不建议秒级或不用新鲜度优先结果缓存还要处理流式响应。务实方案是只在完整生成成功后写入缓存不缓存半截流。流式过程中可以把 token 推给客户端但只有模型调用正常结束、引用来源完整、敏感信息检查通过后才把最终 answer 写入 Redis。一次请求的缓存生命周期可以这样理解这个流程里的关键点是结果缓存命中时可以跳过向量库和 LLM未命中时仍然要完整执行检索、生成、审核和写缓存。缓存不是改变业务流程而是复用已经确认可复用的输出。一致性取舍优先用版本号少做大范围删 keyAI 应用缓存一致性最常见的问题是知识库更新后仍然命中旧答案。很多团队第一反应是“更新时删除相关 Redis key”。这在小系统里可行但知识库、权限、prompt、模型参数都能影响答案时精确删除会越来越难。更可靠的策略是把版本号纳入缓存键。比如每个租户维护一个 kb_version知识库发布成功后递增构造检索缓存和结果缓存时都带上该版本。旧缓存不需要立即删除等待 TTL 自然过期即可。kb:version:{tenant} 42retrieval:{tenant}:{scope}:kb42:{query_hash}result:exact:{tenant}:{scope}:kb42:{prompt_hash}这种方案的输入是当前请求和版本号处理是按版本构造 key输出是与知识库版本绑定的缓存结果。失败模式也很明确版本号没有及时更新会继续命中旧结果版本号更新过于频繁会导致命中率下降。对应的观测信号包括版本发布事件、版本读取失败次数、不同版本 key 的命中率、旧版本 key 的内存占用。权限也应进入缓存边界。不要把完整 user_id 简单塞进所有缓存键这会降低共享命中率也不要忽略权限否则会越权返回。更好的方式是计算 permission_scope_hash把用户实际可见的知识库集合、部门范围、角色集合编码进去。两个用户权限集合一致时可以共享检索缓存权限不同则不会误命中。一致性还涉及数据库和 Redis 的写入顺序。对会话历史这类需要留痕的数据建议先写数据库再写 RedisRedis 写失败时可以降级只影响下次读取性能。对结果缓存这类可重算数据可以在业务成功后异步写 Redis失败只记录指标不影响主流程。数据类型写入顺序Redis 失败影响推荐处理用户消息DB 成功后写 Redis下次回源变慢记录错误允许降级会话摘要DB 为准Redis 缓存摘要摘要读取变慢回源 DB 并回填检索结果检索成功后写 Redis增加向量库压力短期可接受关注 miss模型结果审核成功后写 Redis增加模型调用成本异步重试或放弃权限信息权限系统为准可能越权或拒绝访问强一致场景不要只依赖缓存一句话判断影响正确性和权限的状态以权威存储为准影响成本和延迟的中间结果可以让 Redis 加速。接入路径先检索再上下文最后结果如果现有 AI 应用还没有缓存不建议一次性把所有层都接入。可以按风险从低到高推进。第一步先缓存检索结果。它的输入和输出比较清楚输入是 query、租户、权限范围、知识库版本输出是文档片段 id、score、rerank 后顺序。检索缓存不会直接绕过模型生成即使命中错误也通常还能在生成阶段被引用检查和回答约束发现。function retrieve_with_cache(req): key build_retrieval_key(req) cached redis.get(key) if cached: metrics.inc(retrieval_cache_hit) return json_decode(cached) docs vector_search(req.query, req.scope, req.kb_version) reranked rerank(req.query, docs) redis.setex(key, 600, json_encode(reranked)) metrics.inc(retrieval_cache_miss) return reranked第二步接入上下文短缓存。重点不是提高命中率而是降低数据库回源和 prompt 组装成本。这里要先确保消息落库可靠再让 Redis 做最近 N 轮的加速层。上线时重点观察 Redis miss 率、DB 回源耗时、prompt token 分布和上下文裁剪次数。第三步再考虑结果缓存。结果缓存收益最大但也最容易引入旧答案和错误复用。建议先从低风险场景开始比如 FAQ、分类、结构化抽取。缓存 value 里不要只放 answer至少要放生成所需的关键元信息{ answer:...,citations:[doc_12,doc_98],model:model_name,system_prompt_version:prompt_v3,kb_version:42,created_at:1710000000,quality_flags:[safe_checked,citation_checked]}第四步补齐缓存旁路和灰度配置。可以按租户、场景、接口或用户比例打开缓存。出现异常时配置开关应能立即绕过结果缓存但不影响数据库、检索和模型主链路。cache.enable_contexttruecache.enable_retrievaltruecache.enable_resultfalsecache.result.allow_scenesfaq,intent_classificationcache.result.default_ttl_seconds900cache.result.bypass_on_redis_errortrue这些配置解决的是上线控制面问题。没有开关的缓存一旦污染就只能临时改代码或清 Redis有开关的缓存才有灰度、回滚和对比实验的空间。排查时看 key、版本、value 和回源缓存问题难排往往是因为日志只记录了“命中”或“未命中”没有记录为什么命中。AI 应用至少要把 key 生成因素写入结构化日志但不要记录完整用户隐私文本可以记录 hash、版本号和场景名。信号用途异常表现cache_layer区分 context、retrieval、result不知道是哪层缓存导致问题cache_hit判断命中状态命中率突然归零或异常升高key_hash追踪同类请求无法复现用户问题kb_version检查知识库一致性更新后仍命中旧版本prompt_version检查提示词变更影响改 prompt 后旧结果仍返回scope_hash检查权限边界不同权限用户命中同一结果value_bytes观察上下文膨胀Redis 网络耗时上升fallback_reason记录降级原因Redis 故障时无从定位排查旧答案时先确认请求里的 kb_version 是否最新再确认 result key 是否包含该版本然后看缓存 value 的 created_at 和 citations最后检查知识库发布流程是不是只更新了向量库却没有递增版本号。排查回答质量下降时不要先清缓存。先打印本次 prompt 的组成摘要系统指令版本、摘要长度、最近消息条数、检索文档数量、最终 token 估算。很多所谓“模型变差”实际是上下文缓存里混入了过期摘要、错误角色消息或过多无关检索片段。排查成本突然升高时先看结果缓存命中率和检索缓存命中率。如果命中率下降常见原因是 key 中加入了高基数字段例如 request_id、timestamp、完整 user_id或者 prompt 版本每次发布都自动变化导致历史缓存全部失效。症状常见原因处理动作知识库更新后仍返回旧答案key 未包含 kb_version发布流程递增版本缓存键带版本不同用户看到不该看的引用key 未包含 scope_hash权限范围参与 key 生成Redis 内存增长过快TTL 过长或 value 过大分层 TTL限制上下文长度命中率突然下降key 加入高基数字段移除 request_id、timestamp 等字段流式回答命中半截内容生成中就写缓存完整生成和审核后再写入线上清理缓存也要谨慎。不要在生产环境用阻塞式全量扫描命令清大前缀更推荐按租户、场景、版本缩小范围使用渐进式扫描或直接通过版本号绕开旧 key让旧数据自然过期。上线前把这几件事确认完第一个误区是把 TTL 当成一致性方案。TTL 只能保证数据最终过期不能保证业务更新后立即不再使用旧数据。知识库、权限、prompt 这类会改变答案含义的因素应进入版本或 scope而不是只靠短 TTL。第二个误区是缓存所有模型回答。带有强用户上下文、实时数据、外部工具调用和高随机性的回答不一定适合结果缓存。能缓存的前提是输入边界可枚举输出可以复用失败后不会造成权限或合规问题。第三个误区是忽略缓存污染后的恢复路径。缓存 value 一旦写入错误答案如果没有版本号、开关和按前缀定位能力就很难快速止损。即使不频繁清 key也要保留按租户、场景和版本定位问题的能力。上线前可以用下面这张表过一遍检查项判断标准权威存储明确Redis 丢数据后关键业务数据能从 DB 或其他系统恢复key 包含边界tenant、scope、kb_version、prompt_version、model 参数按需进入 keyTTL 分层上下文、检索、结果缓存分别设置不共用一个默认值写入时机正确结果缓存只在生成完整、审核通过后写入可灰度开关能按场景、租户或接口关闭结果缓存日志可复现记录 key_hash、版本号、命中状态、fallback_reason指标可告警miss 激增、value 过大、Redis 错误率、模型调用量异常有告警降级路径清楚Redis 不可用时系统能回源或跳过缓存继续服务权限边界可验证不同 scope 的请求不会命中同一个结果缓存Redis 在 AI 应用里的价值不是把所有东西都变快而是把重复、昂贵、边界清楚的计算尽量复用。上下文缓存关注 prompt 构造的稳定性检索缓存关注向量库压力结果缓存关注模型调用成本和延迟一致性设计关注版本、权限和可回滚。如果你正在改一个已有系统建议从检索缓存开始小范围加 kb_version 和 scope_hash再整理上下文缓存限制最近消息长度并补齐摘要回源最后只对低风险场景开放结果缓存。这样做不一定最激进但能让缓存收益、回答正确性和线上可控性保持在同一个工程框架里。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
返回列表