从技能到记忆:构建动态上下文系统的工程思维与实践 📅 2026/8/15 3:17:56 1. 从“技能”到“记忆”一个工程思维的范式转换我们每天都在和各种各样的“技能”打交道。在软件开发领域一个函数、一个API、一个微服务都可以被看作是一个“技能”。它们被设计出来完成某个特定的、边界清晰的任务。比如一个“发送邮件”的技能你调用它给它收件人、标题和正文它就能把邮件发出去。这个模型简单、直接也符合我们长期以来构建软件的逻辑模块化、高内聚、低耦合。但不知道你有没有遇到过这样的场景你正在和一个智能客服聊天你问“我的订单发货了吗”它准确地告诉了你物流状态。然后你紧接着问“那大概什么时候能到”它却回答“抱歉我不太明白您的问题”。那一刻你感觉到的不是“技能”的缺失而是“记忆”的断裂。它明明刚刚处理了你的订单查询却瞬间“忘记”了上下文。这就是典型的“技能”思维下的产物——每一次交互都是孤立的、瞬时的。“当 Skill 放大一万倍它就变成了 Memory”。这句话听起来有点哲学但背后是一个极其务实的工程洞察。它描述的不是量的简单堆积而是一种质的跃迁。当一个“技能”系统变得足够复杂、足够庞大以至于它需要处理的不再是孤立的请求而是跨越时间、跨越会话、甚至跨越不同数据源的连续状态时它的核心矛盾就从“如何执行”转变为了“如何记住”。这里的“记住”不是指缓存一个结果那么简单而是指系统能够主动地、动态地构建、维护和运用一个关于用户、任务和环境的“上下文”。这背后是从“渐进式披露”到“动态上下文”的工程演进。渐进式披露是一种优秀的产品设计原则它像一位耐心的向导只在用户需要的时候才展示下一步的选项或信息避免一次性信息过载。但在复杂的人机协作中仅仅“披露”已经不够了。系统需要能够理解用户当前处于一个多步骤任务的哪个阶段记得之前已经披露过什么、用户选择了什么、生成了什么中间结果并基于这个不断演进的“记忆”来决定下一步该“披露”什么甚至主动预测和准备。这个持续演进的、有状态的、可被推理的“记忆体”就是动态上下文。所以我们今天要聊的不是某个具体的算法或框架而是一种构建下一代智能交互系统的底层工程思维。它关乎如何将无数个细小的“技能”原子通过“记忆”的粘合剂组装成一个能进行连续思考与协作的有机体。这对于构建复杂的对话机器人、智能工作流助手、甚至是具备长期学习能力的AI体都至关重要。2. 拆解核心概念技能、记忆与上下文工程在深入工程实践之前我们必须先统一语言厘清这几个核心概念在本语境下的具体含义。这绝非咬文嚼字而是因为不同的理解会直接导致架构设计的天壤之别。2.1 Skill被封装的动作与知识单元首先什么是Skill在我们的定义里Skill 是一个具备明确输入、输出和执行逻辑的原子化能力单元。它有几个关键特征无状态性一个理想的 Skill 本身不携带会话状态。你调用一个“查询天气”的 Skill它只需要地点和时间参数而不关心是谁在问、这是今天第几次问。它的输出仅依赖于本次输入的参数。功能特异性每个 Skill 解决一个非常具体的问题。比如“计算汇率”、“生成摘要”、“调用某API创建工单”。它的边界清晰职责单一。可组合性Skill 是乐高积木。更复杂的能力可以通过编排Orchestration多个 Skill 来实现。例如“规划旅行”这个宏观任务可能由“查询航班”、“预订酒店”、“生成日程”等多个 Skill 协作完成。在传统的微服务或函数即服务架构中每个服务或函数都可以被视为一个 Skill。这种模式的优势在于易于开发、测试、部署和扩展。但它的局限性也显而易见Skill 之间是孤立的。它们不知道彼此的存在更不知道在一个更长的用户旅程中自己处于什么位置。2.2 Memory跨越时间的状态持久与关联那么Memory又是什么它不是硬盘存储也不是数据库里的一行记录。在这里Memory 指的是系统为了维持连续性交互而主动维护的、结构化的状态信息。它是 Skill 执行历史、用户意图、会话实体和外部环境信息的综合体。Memory 的核心价值在于建立“关联”。例如会话关联用户说“把它发给我邮箱”。这里的“它”指什么Memory 需要记录上一个 Skill 的输出比如生成的一份报告才能正确解析“它”的指代。意图关联用户先问“A项目的进度”接着问“B项目呢”。Memory 需要记住用户关心的核心是“项目进度”并将“A项目”这个实体切换为“B项目”从而理解这是一个对比或连续的查询意图。偏好关联用户多次要求“用简洁的语言总结”。Memory 可以将“简洁”作为该用户的输出偏好记录下来在后续所有文本生成类 Skill 中自动应用此偏好。当我们将一个复杂的任务分解成多个 Skill 调用时Memory 就是贯穿这些调用的“故事线”。它确保了每一次交互都不是从头开始而是在已有的认知基础上进行叠加和演进。2.3 动态上下文记忆的实时计算与供给有了 Memory 作为存储我们还需要一个机制来实时地、动态地决定在当前这个具体时刻执行当前这个具体 Skill需要哪些具体的 Memory这个机制就是动态上下文构建。上下文不是把所有的 Memory 都塞给 Skill。那样做会导致信息过载干扰 Skill 的核心逻辑甚至可能引发安全问题例如泄露其他会话的隐私信息。动态上下文构建是一个智能的筛选、加工和组装过程。这个过程通常涉及检索基于当前的用户查询、正在执行的 Skill 类型从 Memory 存储中检索出最相关的片段。这很像向量数据库的相似性搜索但查询条件更复杂可能结合了关键词、时间衰减、实体类型等。压缩/摘要当相关记忆片段过多时系统需要将其压缩成一段精炼的摘要。例如将过去一小时内关于某个 bug 的十轮讨论总结成“问题已定位到模块X正在尝试方案Y”。结构化将检索和压缩后的信息按照当前 Skill 所需的输入格式进行组装。例如一个“编写代码”的 Skill其上下文可能需要被结构化为{“相关代码片段”: “...” “任务要求”: “...” “已尝试方案”: “...”}。所以动态上下文是 Memory 面向当前任务的一个“实时视图”或“工作集”。它架起了庞大的、历史的 Memory 仓库与当下的、具体的 Skill 执行之间的桥梁。从“渐进式披露”的角度看动态上下文就是系统在每一步根据当前已披露的信息和用户状态计算出的“下一步最应该披露什么”的决策依据。3. 工程演进路径从静态配置到动态感知理解了概念我们来看这条演进路径在工程上具体是如何实现的。它不是一个开关而是一个循序渐进的过程每个阶段都解决了前一阶段的核心痛点。3.1 阶段一基于规则的渐进式披露这是最基础的形态常见于早期的多步表单、向导式界面或简单的对话机器人。实现方式工程师预先定义好一个状态机或决策树。每个节点代表一个步骤节点的跳转条件基于用户上一步的输入。记忆形态“记忆”以会话临时变量或数据库里一条记录的状态字段形式存在。例如state“已收集姓名” next_step“询问年龄”。上下文构建上下文是静态的、预定义的。系统只知道当前处于“步骤2”因此显示“步骤2”的问题。示例客服机器人问“您需要咨询订单、物流还是售后” 用户说“订单”。机器人进入“订单”子流程接着问“请提供订单号。” 这里的上下文就是流程节点ID。痛点极度僵化。无法处理用户跳步比如用户直接说“订单号是123456”、无法关联跨流程信息、任何流程修改都需要重新编码和部署。3.2 阶段二基于会话缓存的短期记忆为了应对用户跳步和指代系统引入了短期会话缓存。实现方式系统会在一个会话窗口内例如同一个对话的最近10轮缓存所有用户输入和系统输出的关键信息特别是识别出的实体如产品名、订单号、日期等。记忆形态内存中的键值对结构例如session_entities: {“product”: “手机” “order_id”: “123456”}。通常会话结束即清除。上下文构建在执行当前 Skill 前系统会从会话缓存中提取所有实体作为补充上下文注入。例如即使用户只说“发货了吗”系统也能从缓存中找到order_id“123456”从而调用“查询物流”Skill。示例用户“帮我查一下iPhone 15的价格。” - 系统缓存product“iPhone 15”。用户接着问“有优惠吗” - 系统将product“iPhone 15”作为上下文调用“查询优惠”Skill。痛点记忆是短暂的、扁平的只有键值对。无法进行复杂的关联推理比如“像上次那样处理”也无法跨会话持久化用户偏好。缓存策略缓存什么、缓存多久需要精心设计否则容易积累垃圾信息。3.3 阶段三向量化长期记忆与检索这是当前AI应用的热点。为了实现“像人一样记住之前聊过什么”系统需要长期、可语义检索的记忆。实现方式引入向量数据库。将每一轮有意义的对话、用户上传的文档、任务执行的结果等通过嵌入模型转换为向量并存储起来。同时存储原始的文本片段和元数据时间、会话ID、实体标签等。记忆形态存储在向量数据库中的“记忆片段”。每个片段包含向量、文本和元数据。上下文构建当新的用户查询到来时系统用同样的嵌入模型将查询转换为向量在向量数据库中进行相似性搜索找出最相关的N个“记忆片段”。将这些片段的文本拼接起来作为历史上下文与大语言模型的最新查询一起构成完整的提示词。示例一周前用户曾讨论过“如何用Python实现一个简单的Web爬虫”。今天用户问“我记得上次那个爬虫怎么加上代理IP” 系统通过向量检索能找到一周前关于“Python爬虫”的记忆片段并将其作为上下文提供给LLMLLM就能给出具有连续性的回答。痛点检索可能不精确产生“幻觉”或引入无关信息。单纯的语义相似度无法捕捉复杂的时间逻辑、因果关系或任务步骤依赖关系。例如对于“完成上一步之后该做什么”这种问题向量检索可能失效。3.4 阶段四图结构记忆与推理网络这是面向未来的高阶形态旨在模拟人类大脑中知识相互关联的网络结构。实现方式使用图数据库来构建记忆。图中的节点可以是实体用户、产品、任务、事件某次对话、某个Skill执行、概念“简洁”、“重要”。边代表节点之间的关系如“属于”、“导致”、“发生于”、“具有属性”。记忆形态一个不断增长的知识图谱。例如[用户A] -[执行过]- [任务生成报告X] -[使用了]- [Skill数据查询] -[于]- [时间T]。[报告X] -[关于]- [项目Y]。上下文构建当需要构建上下文时系统从当前查询解析出的实体或事件节点出发在图上游走沿着特定的关系边如“前一步”、“后续影响”、“相关讨论”收集关联节点信息。这样构建的上下文不仅包含内容还包含了内容之间的逻辑关系。示例用户“把昨天会上讨论的那个方案摘要发给我。” 系统会1. 识别实体“昨天”、“会”、“方案”。2. 在图中找到“昨天”对应的日期节点找到该日期发生的“会议”事件节点。3. 沿着“会议-讨论了-方案”的边找到“方案”节点。4. 再找到与该方案节点关联的“文档”或“讨论摘要”节点。最终将这些关联节点的信息结构化后作为上下文。优势与挑战它能处理极其复杂的、依赖关系和逻辑链很长的记忆检索。但工程复杂度极高需要强大的实体识别、关系抽取能力以及精心设计的图查询逻辑。维护一个持续更新的、一致的知识图谱本身就是巨大挑战。在实际工程中我们往往采用混合模式。例如用向量数据库存储非结构化的对话记忆便于语义检索用关系型数据库或键值存储维护结构化的会话状态和用户偏好对于核心业务实体之间的关系则用图数据库来管理。动态上下文构建引擎需要协调这些不同的存储进行联合查询与信息融合。4. 实战架构设计构建一个动态上下文系统理论说再多不如看一个简化但完整的设计方案。假设我们要为一个“智能研发助手”构建动态上下文系统它需要帮助程序员管理任务、查询文档、排查问题。4.1 系统组件与数据流整个系统可以划分为以下几个核心组件数据流如下图所示我们用文字描述交互入口接收用户请求自然语言或结构化命令。意图识别与实体抽取模块解析用户请求识别意图如“查询错误”、“执行命令”和实体如错误码“ERR_404”、文件名“api.go”。记忆存储器向量记忆库存储所有对话历史、代码片段讨论、错误解决方案的向量化片段。结构化状态库存储当前会话的活跃任务栈、已确认的实体、用户偏好如默认分支、常用环境。知识图谱存储项目实体关系如“服务A 调用 服务B”、“文件F 属于 模块M”、“开发者D 负责 任务T”。上下文组装引擎这是大脑。它根据当前意图、实体和会话状态向各个记忆存储器发起查询。向向量记忆库查询“过去24小时内与‘ERR_404’和‘api.go’相关的讨论”。向结构化状态库查询“当前活跃任务是什么用户是否刚切换了分支”向知识图谱查询“api.go 文件属于哪个服务这个服务最近有哪些部署”然后引擎对这些检索结果进行去重、排序、压缩。例如将10条相似的错误讨论合并成一条摘要“团队在过去3小时对ERR_404的共识是它与网关超时有关。”技能编排器根据意图选择合适的 Skill如“搜索日志”、“运行测试”、“调用Git API”并将组装好的动态上下文作为参数注入。Skill 执行层各个原子化技能被执行它们接收清晰的指令和丰富的上下文但无需关心上下文从何而来。记忆写入器将本次交互中有价值的信息用户query、系统response、Skill执行结果、产生的新实体写回记忆存储器完成记忆的闭环。4.2 核心挑战与应对策略在实现上述架构时你会遇到几个核心挑战挑战一上下文相关性衰减与噪声控制不是所有历史记忆都对当前任务有帮助。过时的、无关的记忆就是噪声。策略引入时间衰减因子和相关性评分。在向量检索时将时间戳作为一个加权维度越近的记忆权重越高。对于知识图谱查询可以限定遍历的跳数。同时可以设置一个相关性阈值过滤掉分数太低的记忆片段。挑战二记忆的冲突与一致性如果两个记忆片段内容冲突怎么办比如关于同一个API的用法向量库里既有旧的文档又有新的讨论。策略实现记忆源优先级和版本管理。定义数据源的权威性等级例如官方最新文档 团队共识讨论 个人历史记录。在上下文组装时对于同一实体优先采用高优先级、时间更新的记忆。对于关键配置甚至可以引入显式的版本标签。挑战三隐私与安全边界记忆可能包含敏感信息代码、密钥、用户数据。不能把所有人的记忆都混在一起也不能让上下文无限制地包含所有信息。策略实施严格的记忆隔离与访问控制。记忆必须打上“所属会话”、“所属项目”、“所属用户”的标签。上下文组装引擎在检索时必须附加当前会话/用户的权限作为过滤条件。对于特别敏感的信息可以采用“记忆标记”而非“记忆内容”的方式例如在上下文中只提示“关于数据库密码您曾在昨天修改过”而不是直接给出密码。挑战四性能与成本向量检索、图谱查询、LLM生成都是计算密集型或IO密集型的操作。实时构建复杂上下文可能带来延迟和成本问题。策略采用分层缓存与异步更新策略。对高频、热点的记忆查询结果进行缓存。记忆的写入可以采用异步队列避免阻塞主请求链路。对于复杂的图谱关系可以预先计算和物化一些常用的视图。5. 踩坑实录从理论到实践的五个深水区设计图画起来很美但真正动手实现坑是一个接一个。分享几个我们趟过的雷区希望能帮你省下几百个调试的小时。5.1 坑一向量检索的“似是而非”我们最初认为只要把对话历史扔进向量库就能完美解决“记住之前说过什么”的问题。结果发现LLM 经常给出包含“幻觉”的答案。根因排查仔细分析提示词发现问题出在检索结果上。当用户问“我们刚才说的那个方案”向量检索可能会返回语义相似但完全无关的“方案”比如上周另一个项目的方案。因为“方案”这个词太普遍了。解决方案我们改进了记忆片段的元数据标注。除了存储文本和向量我们强制为每个片段打上多个标签session_id,timestamp,main_entity主要实体如项目名、错误码,intent_category意图分类。在检索时我们采用混合检索策略先使用关键词从当前查询中提取的实体在元数据中做硬过滤缩小范围再在这个范围内做向量相似度排序。这大大提升了检索的精确度。5.2 坑二无限增长的上下文与性能悬崖为了让模型“知道得更多”我们不断把更多记忆塞进上下文。很快我们发现响应时间变长API调用费用飙升更糟糕的是模型的理解能力开始下降因为它无法从海量文本中抓住重点。根因排查LLM 的上下文窗口有极限如128K但更重要的是其有效注意力是有限的。过多的无关信息会造成“信息淹没”导致模型表现反而变差。解决方案我们引入了动态上下文压缩与摘要链。不是把所有相关记忆都直接拼接。我们设计了一个两步流程检索获取所有相关记忆片段。压缩如果片段总长度超过阈值比如2000词就调用一个“总结” Skill让它用另一段提示词“请将以下关于[主题]的讨论浓缩成一段不超过300字的背景摘要保留核心结论和待解决问题。” 然后将这个摘要而非原始文本放入最终上下文。这样既保留了关键信息又控制了上下文长度。5.3 坑三技能编排中的上下文污染我们有一个“执行Shell命令”的 Skill。有一次用户在和助手讨论一段危险的rm -rf /代码片段纯讨论紧接着让助手“清理一下临时文件”。结果助手在上下文中看到了之前的讨论片段竟然真的尝试执行rm -rf /幸好有安全限制。根因排查上下文组装引擎无差别地将所有相关历史都注入给了 Skill而 Skill 没有能力区分“讨论的代码”和“要执行的指令”。解决方案我们为每个 Skill 定义了上下文契约。在 Skill 的注册元信息中明确声明它需要什么类型的上下文。例如“执行命令” Skill需要{“明确的用户指令”: “string”}可选{“安全确认”: “bool”}。禁止传入{“历史对话中的代码示例”: “string”}。“代码解释” Skill需要{“待解释的代码块”: “string”}可选{“相关错误信息”: “string”}。 上下文组装引擎会根据当前要调用的 Skill 的类型严格按契约过滤和格式化记忆内容从根本上避免了污染。5.4 坑四记忆的“僵尸化”与更新滞后用户明明已经更新了配置但系统还在基于旧的记忆给出建议导致操作失败。根因排查记忆一旦写入就被视为静态事实。我们没有建立记忆与真实世界状态的同步机制。解决方案我们为记忆引入了有效期和刷新触发器。对于某些类型的记忆如“服务部署状态”我们设置一个较短的TTL。更重要的是我们建立了一个“事件监听”机制。当监控到关键事件发生时如代码提交、配置更新、服务重启主动触发相关记忆的失效或更新。例如当GitHub有新的提交到main分支系统会自动使所有包含旧版本代码片段的记忆片段失效或为其打上“已过时”标签。5.5 坑五评估体系缺失优化无从下手系统上线后我们感觉时好时坏但说不清到底哪里好、哪里坏更不知道优化该从何处着手。根因排查缺乏量化的、针对“记忆与上下文”效果的评估指标。我们只有整体的任务成功率无法归因。解决方案我们建立了三层评估体系检索层评估对于每次上下文组装记录检索出的记忆片段ID并事后由人工或规则标注其“相关性”相关/部分相关/不相关。计算检索准确率。上下文层评估对组装后的完整上下文进行抽样评估其“信息密度”是否冗余和“逻辑连贯性”是否有助于理解当前问题。业务层评估定义关键场景的“连续对话任务完成率”。例如“在3轮对话内成功解决一个复杂bug”作为一个任务统计其成功率。通过A/B测试对比不同上下文策略如是否启用摘要、不同检索策略对该成功率的影响。这些坑让我们明白构建动态上下文系统不仅仅是一个算法问题更是一个复杂的系统工程问题涉及数据管理、安全、性能、评估等方方面面。走到这里你会发现“Skill放大一万倍变成Memory”不是一个瞬间的魔法而是一个持续迭代的工程旅程。它始于对孤立功能点的封装成长于对状态和关联性的管理成熟于对复杂上下文的动态构建与推理。这套思维范式正在让我们的软件从执行命令的工具逐渐演变为能够持续协作的伙伴。它的核心价值不在于记住了多少数据而在于通过记忆让每一次交互都站在了之前所有交互的肩膀上从而变得更有深度、更个性化、更富有成效。这或许就是智能交互进化的下一个里程碑。