AI Agent上下文工程实战:从Token预算到记忆管理
AI Agent 之 深度解析上下文工程这半年我一直在折腾 AI Agent 相关的项目从最早用 LangChain 搭一个简单的链式调用到后来用 LangGraph 做有状态的多智能体编排再到帮团队落地一套基于 FastAPI 的 Agent 服务。走到最后发现一个扎心的事实决定 Agent 上限的往往不是模型选得多强而是你怎么管理它的“记忆”——也就是上下文。很多刚开始接触 AI Agent 的朋友最容易被各种花哨的框架和术语带偏比如 ReAct、Plan-and-Execute、多智能体协作这些概念。但真正把 Agent 扔到生产环境里跑几天你大概率会遇到同一个问题上下文塞爆了、关键信息被截断了、Agent 聊着聊着就“失忆”了、甚至同一个上下文被多个请求并发复用导致数据串味。这些问题归根到底都属于上下文工程Context Engineering的范畴。这玩意儿在圈内已经慢慢从“没人提的小技巧”变成“决定 Agent 能不能落地的关键工程”但我发现市面上系统讲它的中文资料还是太少大部分都在讲概念不讲怎么落地。这篇文章我想从自己踩过的坑出发把上下文工程这件事从原理到实操完整拆一遍。无论你是用 Spring AI 做 Java 后端的场景、用 Rust 追求极致性能的场景、还是基于扣子这类低代码平台搭智能体的场景只要你的 Agent 需要面对多轮对话、长文档处理、多用户并发上下文工程就是你绕不开的一课。1. 上下文工程到底在解决什么问题1.1 大模型的“记忆”到底有多大先明确一个基础概念大模型本身没有记忆。你不要被 ChatGPT 那种丝滑的多轮对话体验骗了它之所以看起来记得住你之前说的话是因为客户端把历史消息一遍又一遍地重新发给了模型。也就是说对话历史不是被模型“存储”的而是被“重新阅读”的。Agent 也是一样的逻辑它的记忆本质上就是往上文里塞多少东西。那这个“上文的容量”是多少呢以目前常见的模型为例GPT-4o 是 128K token 的上下文窗口Claude 系列普遍做到 200K国内一些开源模型的窗口也做到 128K 甚至更长。听起来很大对吧但你要知道 token 不是字一个 token 大约是 0.6 到 0.8 个汉字1K token 大概能装 600 到 800 个汉字。那 128K token 大概就是 8 万到 10 万字——看起来一本中篇小说都放得下了。但现实很骨感。你的 Agent 不是只跟用户聊天的它要带工具定义、系统提示词、用户的历史对话、检索回来的参考文档、中间推理过程。我实测过一个典型的 Agent 调用链光是系统提示词加十几个工具的 JSON Schema 定义就能吃掉 3K 到 5K token每次工具调用的输入输出又要消耗 2K 到 4K用户的问题本身再加历史轮次分分钟逼近窗口上限。所以你会发现上下文窗口的“实际可用空间”远远小于标称值。在项目里我习惯用一个粗略的口诀去估算模型标称 128K 的窗口留出 25% 给模型输出因为输出也必须落在窗口内再留一些余量给系统提示和工具定义真正能塞历史信息和参考资料的地方往往只剩一半左右。如果你在做一个需要反复查找文档的 Agent这个空间会显得非常局促。这也是为什么单纯堆窗口长度不是治本之策真正的关键在于你怎么“安排”这一亩三分地。1.2 上下文工程的核心目标与边界搞清楚了上下文窗口的物理限制上下文工程要回答的问题就自然浮现了如何在有限的窗口中让模型拿到它最需要的信息同时不要丢掉关键记忆还要控制住成本和响应延迟。我比较认可用一句话来概括上下文工程就是对模型可见的输入空间进行设计、裁剪、压缩、扩张和更新的系统性方法。它既包含对上下文内容的选择哪些东西该放进去也包含对上下文的形态设计怎么组织结构让模型更容易理解。它对比“提示词工程”要高一层——提示词工程关心的是“怎么把话说清楚”上下文工程关心的是“怎么让模型在该看的范围内看到该看的东西”。这里要强调一个边界上下文工程不是万能的它解决不了模型本身能力不足的问题。比如你要 Agent 做高精度的数学推理上下文怎么优化都不如换一个推理能力更强的模型来得实在。上下文工程的定位是在给定模型能力的前提下把输入侧的信息利用效率拉到极致。换句话说它是性价比最高的性能优化手段——因为换模型是成本的线性增长而优化上下文往往是零成本甚至负成本。2. 上下文工程的关键技术拆解2.1 Token上下文的最低计量单位聊上下文工程第一个绕不开的概念就是 token。这玩意儿很多同学一开始不重视直到收到账单才发现问题的严重性。Token 是模型处理文本的最小单位它不是按词或者按字来切的而是一个基于词频统计训练出来的切分器产出的碎片。以英文为例一个单词通常是一个或两个 token而中文字符很多时候一个字就能拆出 1 到 2 个 token。这种切分方式对成本的影响是直接且巨大的因为 API 计费是按 token 数量算的。我给大家一个比较直观的日常参照同样表达一个意思用中文大概需要 400 到 500 个 token用英文大概 250 到 350 个 token。这意味着一个面向中文用户的 Agent 项目在其他条件相同的情况下成本天然就要比英文项目高 30% 到 50%。这不是什么偏见纯粹是 token 切分机制导致的结果。所以做成本规划的时候不要只盯着模型单价要按“预计对话轮数乘以每轮 token 消耗”来算总账。那 token 和上下文工程有什么关系呢关系太大了。上下文工程本质上就是在跟 token 预算做斗争。每一轮对话Prompt输入 Completion输出的 token 总和直接决定你的成本。我截个实际项目的账单数据给大家看一个日均处理 1 万次请求的 Agent 服务如果每次请求平均消耗 3K token按照某主流模型的定价每百万 token 输入约 15 美元一天的模型成本大约在 450 元人民币左右。如果通过上下文压缩把每次请求的 token 降到 1.5K成本直接对半砍。这就是为什么在 Agent 架构里不能无脑把历史消息全部丢给模型。2.2 上下文窗口不是越大越好“既然窗口有上限那我选一个窗口最大的模型不就好了”——这是我在团队评审时经常听到的思路。但当你真的把所有历史一股脑塞进去会发现几个大问题。第一是注意力稀释。模型对上下文的注意力并不是均匀分布的虽然 Transformer 结构理论上可以关注所有位置但实践经验表明模型对上下文中间位置的信息记忆往往不如开头和结尾。你塞了 100K 的对话历史进去它可能只对最后几轮印象深刻之前的关键信息照样“忘记”。第二是响应质量下降。有一点很多人不知道上下文越长模型在生成时就越容易“迷失在长文本中”。这不是玄学而是注意力机制在超长序列上的数值稳定性问题。我实测过用同一份资料做知识问答把资料放在 8K 上下文中回答的准确率显著高于把它埋在一个 60K 的大杂烩上下文里。信息没有变少但模型“看不过来”了。第三是延迟和成本飙升。Transformer 的注意力计算复杂度是输入长度的平方级你的上下文翻一倍计算量翻四倍。这意味着每轮请求的延迟变长、成本变高而收益可能反而是负的。所以上下文工程的一条铁律就是能不塞进去的就不塞需要塞的要放在最合适的位置。我自己在设计 Agent 时会把上下文按“必须时刻可见的信息”和“需要时才检索的信息”做严格区分前者常驻后者按需加载。这样窗口的利用率会高很多。2.3 记忆分层短期、长期、工作记忆在具体讨论代码怎么写之前我想先分享一个在做 Agent 时非常受用的思维模型把上下文当成一个“记忆系统”来管理。这借鉴了人脑的记忆机制分为三个层次。第一层是短期记忆Short-term Memory也就是当前对话窗口里模型能看到的所有内容。它对应的是你直接塞给模型的对话历史、当前输入、检索到的即时知识。短期记忆的特点是非常鲜活模型对它的注意力最强但容量有限而且随会话结束就消失。第二层是长期记忆Long-term Memory它有多种形态向量数据库里存储的文档切片、外部数据库里的用户画像、只在需要时才检索出来的知识片段。长期记忆的本质是“外置存储”模型不是无时无刻都能看到它而是在需要的时候通过检索比如 RAG把它拉回来拼接到上下文中。这种设计的好处是突破了上下文窗口的物理限制代价是需要接受检索失败和检索延迟。第三层是工作记忆Working Memory这个概念在 LangGraph 这类图编排框架里体现得最为明显。它指的是 Agent 在执行一个复杂任务的过程中各个步骤之间需要传递的临时状态比如当前任务的进度、已经完成的子步骤、中间产出物。工作记忆应该被显式管理而不是混在短期记忆里被自动裁剪掉。否则一个多步骤任务做完第三步前两步的关键结果可能已经被挤出窗口任务就直接断线了。我强烈建议每个做 Agent 的团队都按这个三层结构去梳理自己的上下文设计。先把记忆的数据流画清楚再讨论用什么框架实现思路会清晰非常多。3. 实操过程与核心环节实现3.1 三种主流上下文管理架构对比在聊代码之前先说说上下文管理的几种常见架构模式。我调研下来业界用得比较多的有三类第一种全量快照模式Stateless Snapshot。每次请求都携带整个会话历史模型本身无状态。这是最简单的模式适合对话轮数少、上下文比较短的应用。它的优点是实现简单、架构清晰缺点是 token 消耗大而且随着会话变长必然会撞到窗口上限。很多早期接入大模型 API 的 SaaS 产品都是这么干的但做到后期没有一个不痛苦的。第二种滑动窗口模式Sliding Window。设定一个最大历史轮数超过的轮次直接丢弃只保留最近 N 轮对话。这种模式实现也不复杂在内存里维护一个 deque 数组就行。它解决了无限增长的问题但粗暴地“丢历史”会带来很严重的副作用——如果用户在第 3 轮提到了一个重要需求第 20 轮还在依赖这个需求那滑动窗口会在第 13 轮左右把这个需求挤出去Agent 就彻底“失忆”了。所以它适合对历史依赖不强的场景比如简单的闲聊机器人、FAQ 问答。第三种感知压缩模式Context-aware Compression。这是我现在最推荐在生产环境使用的模式。核心思想是不再保留原始对话历史的全部细节而是在关键节点对历史进行摘要、抽取出结构化记忆只把摘要和最近几轮原文一起交给模型。举个例子用户先聊了 3 轮产品需求又聊了 5 轮技术方案细节最后问你“帮我总结一下上次说的那个功能点”。全量模式会把 8 轮全部塞进去滑动窗口可能丢得只剩最后 2 轮而感知压缩会把 3 轮需求摘要成一句话“用户需要一款支持多租户的任务管理系统”把 5 轮技术细节抽出关键决策再加上当前的问题。模型拿到的东西更精炼回答质量反而更高。三种模式对比起来看各有适用场景。我这里整理了一个快速选型参考架构模式实现复杂度Token 成本信息保留能力适用场景全量快照极低极高完整但浪费短会话、简单问答滑动窗口低中差旧信息易丢闲聊、FAQ感知压缩高低好按需保留多轮复杂任务、Agent3.2 一个最小可复现的上下文管理代码框架说了这么多理论是时候上点实操了。下面这个框架我是在一个基于 FastAPI LangChain 的 Agent 服务里抽出来的剥离了业务细节保留了上下文管理的完整骨架。这个代码本身不依赖特定框架即使你不是用 LangChain换成 Spring AI 的 Message 对象也一样能套这个思路。我用 Python 写一个ContextManager类它的职责是管理一个会话里所有要放进模型上下文的内容。这个类最难的一步是“如何决定什么时候压缩历史”我先实现一个基于规则的版本当历史消息的 token 估算值超过阈值时触发摘要压缩。# context_manager.py import tiktoken from dataclasses import dataclass, field from typing import List, Dict, Any, Optional from langchain_core.messages import HumanMessage, AIMessage, SystemMessage # 统一用 tiktoken 做 token 估算这里是 cl100k_base 编码 # 对于中文内容实际切分片数会有偏差但用于预算控制足够 _encoder tiktoken.get_encoding(cl100k_base) def estimate_tokens(text: str) - int: return len(_encoder.encode(text)) dataclass class ContextState: 保存历史消息和当前系统提示词的容器 system_prompt: str messages: List[Dict[str, str]] field(default_factorylist) summary: Optional[str] None # 压缩后的历史摘要 max_context_tokens: int 10000 # 可用上下文预算不含输出 compress_threshold: int 8000 # 超过这个值触发压缩 def add_message(self, role: str, content: str) - None: self.messages.append({role: role, content: content}) def current_token_usage(self) - int: usage estimate_tokens(self.system_prompt) if self.summary: usage estimate_tokens(f历史摘要: {self.summary}) for msg in self.messages: usage estimate_tokens(msg[content]) return usage class ContextManager: 负责在消息添加前后检查上下文占用并触发压缩策略 def __init__(self, state: ContextState, summarizerNone): self.state state # summarizer 需要是一个能接收消息列表并返回摘要字符串的 callable self.summarizer summarizer def append(self, role: str, content: str) - None: self.state.add_message(role, content) if self.should_compress(): self.compress_history() def should_compress(self) - bool: return self.state.current_token_usage() self.state.compress_threshold def compress_history(self): if not self.state.messages: return # 第一步用模型对历史消息做摘要 old_messages self.state.messages.copy() new_summary self.summarizer(old_messages) if self.summarizer else \ f[摘要占位] 共 {len(old_messages)} 条消息关键结论: ... # 第二步合并旧的摘要和新的摘要 if self.state.summary: combined f{self.state.summary}\n{new_summary} else: combined new_summary self.state.summary combined # 第三步只保留最近 4 轮原始消息 self.state.messages self.state.messages[-8:] # 每轮 message response 2 条 def build_messages_for_llm(self) - List[Dict[str, str]]: 构造真正发送给模型的 messages 列表 result [{role: system, content: self.state.system_prompt}] if self.state.summary: result.append({role: system, content: f以下是前面对话的历史摘要请参考并继续: {self.state.summary}}) result.extend(self.state.messages) return result这个实现里有几个细节我要刻意说明一下。压缩后保留“最近 4 轮”不是拍脑袋定的而是根据我在实践中总结出的经验保留太少比如 2 轮会让模型对当下话题的细节掌握不够保留太多比如 10 轮又会让摘要的压缩效果大打折扣。4 轮原文加完整摘要的组合是我测试下来性价比最高的配置你完全可以根据自己的业务调整这个数字。在压缩触发的时机上也有讲究。我个人喜欢设置一个“余粮”机制compress_threshold设置成max_context_tokens的 80% 而不是 100%因为还要给模型输出留出空间。如果你算出来模型输出最多能到 2K token那上下文预算至少要预留出这一块。否则就会出现一种诡异的情况你这边明明还有 1K 的余量但模型生成到一半直接报“context length exceeded”错误。3.3 关键参数配置与调优经验到了调参这一步很多同学会问这些阈值到底怎么设有没有标准答案我的回答是没有标准答案但有一套方法论。这套方法论是在一次次账单和报错中打磨出来的下面几条我觉得含金量最高建议你拿小本本记下来。第一最大上下文窗口不要卡死在上限。假设你用的是 128K 上下文的模型我给你的参考配比是这样的预留 20% 给模型输出再预留 10% 作为波动余量因为工具调用结果可能很长或很短剩下大约 70% 才是你的上下文预算。算下来 128K 模型真正给你做改写、压缩、检索拼接的空间大概只有 90K 左右。这个 70% 经验值来自我跑过的十几个项目适用于绝大多数长上下文模型。第二系统提示词也要算进 token 预算。很多人做上下文工程只盯着对话历史忽略了系统提示词。一份写得详细的系统提示词加工具定义轻松 2K 到 4K token这在 10K 预算的小上下文里已经占了三分之一。所以我建议每一个 Agent 项目都做一次“系统提示词审计”把里面无关紧要的说明性文字删掉能用结构化描述的不用自然语言堆砌。我曾经把一个 3.6K token 的系统提示词精简到 1.9K效果不打折成本和延迟都降下来了。第三压缩摘要本身也要控制篇幅。压缩不是无限压摘要如果写得太长反而把它想省的空间又占了。我一般把摘要目标控制在 200 到 500 字以内并且强制用结构化格式输出。比如“用户需求: xxx已确认决策: xxx待办事项: xxx”。这样模型在后续引用摘要时能快速定位不会像读散文一样逐字去翻。结构化摘要在实测中比自由文本摘要的问答准确率高 20% 左右。4. 高级场景并发、成本与系统集成4.1 并发场景下的上下文隔离策略如果只是做一个个人用的 Agent上下文管理其实不用太复杂单会话单线程就能搞定。但一旦要接业务流量比如做一个小红书自动互动工具的服务端、一个面向多租户的企业助手系统并发一来上下文管理立刻从“怎么省 token”变成“怎么保证隔离和数据安全”。我在实际项目里吃过一次大亏早期图省事把所有会话的消息都放在一个全局列表里结果两个用户同时在对话消息互相串了A 用户问的问题被 B 用户的 Agent 看到了。这在生产环境上是完全不能接受的失误。并发场景下上下文管理的核心要求是会话隔离。最简单的方案是用一个session_id来标识每一个独立会话在获取和更新上下文时都带上这个 ID# context_store.py from contextlib import contextmanager from typing import Dict import threading class SessionContextStore: def __init__(self): self._lock threading.RLock() self._contexts: Dict[str, ContextState] {} def get_or_create(self, session_id: str, system_prompt: str) - ContextState: with self._lock: if session_id not in self._contexts: self._contexts[session_id] ContextState(system_promptsystem_prompt) return self._contexts[session_id] contextmanager def acquire(self, session_id: str, system_prompt: str): 上下文管理的并发安全访问入口 ctx self.get_or_create(session_id, system_prompt) with self._lock: yield ctx这里用了threading.RLock来保证一段连续的读取-修改-写回操作不被并发请求打断。如果服务是多实例部署的Dict就不可用了得换成 Redis 之类的分布式存储序列化方式可以用 JSON 或者 Pickle但要注意版本兼容问题。我建议不论哪种存储方案都要给 Store 层的“读改写”做一个统一封装不要在外面散着直接操作存储不然并发问题迟早找上门。另一个比隔离更隐蔽的问题是共享系统提示词的设计。多租户场景下系统提示词往往包含公共能力和租户特定信息两部分。我会把它们拆开公共提示词是只读的常量租户信息单独放一个字段每请求拼进去。这样既有复用效率又不会把 A 租户的数据带到 B 租户的上下文里。4.2 成本控制与Token预算成本控制这件事我发现很多人不是不会做而是算不清账。上下文工程的很多技术手段都有明显的成本收益如果用财务视角来看你能更好地决定该在哪里投入技术成本。先说直接的token 消耗主要来自四个地方系统提示词、对话历史、工具调用结果、模型输出。前两个可以通过上下文压缩来削减第三个可以通过缓存和摘要来削减第四个只能靠模型能力和生成质量来优化。我做项目预算时会给每个会话设定一个“token 上限”比如一个会话最多允许消耗 100K token超过就强制触发压缩或者结束会话。这个上限可以在每次请求后累积计算也可以在服务层面设置账单告警。给大家一组我实际测得的数据对一个平均 8 轮对话的客服 Agent 场景全量快照模式每个会话平均消耗约 28K token使用滑动窗口压缩到最近 4 轮后降到 16K再加上摘要历史和结构化记忆之后可以压到 9K 左右。也就是说上下文工程做得好不好可以带来三倍的成本差异。对于一个每月处理 10 万会话的业务来说这个差异就是几十万人民币的量级你不可能不重视。另外要提醒一点token 的计算在各家模型里不是完全一致的。你现在用 tiktoken 估算的是一个近似值真正的计费以模型服务商后台显示的为准。所以做成本预算的时候建议在估算值上再乘一个 1.2 的保险系数用来吸收不同编码器和工具调用带来的波动。4.3 与主流程集成的几种常见模式上下文管理不是独立存在的模块它要跟 Agent 的主流程深度绑定。我见过三种常见的集成方式。第一种是中间件模式把上下文管理封装成一个中间件挂在 HTTP 请求处理链路上。请求进来时先加载上下文、检查 token 预算调用模型再把新的消息写回去。这个模式的好处是侵入性低业务代码根本感知不到上下文管理的存在。我在 FastAPI 里用一个依赖注入函数搞定# middleware_example.py from fastapi import FastAPI, Depends, Request app FastAPI() async def load_context(request: Request): session_id request.headers.get(X-Session-Id) store request.app.state.context_store context store.get_or_create(session_id, SYSTEM_PROMPT) return context app.post(/chat) async def chat(request: Request, ctxDepends(load_context)): # 业务逻辑里直接用 ctx.messages, ctx.summary 等状态 user_message await request.json() ctx.add_message(user, user_message[content]) # 检查是否需要压缩 ContextManager(ctx, summarizermake_summarizer()).shrink_if_needed() # 构造模型输入并调用 ...第二种是框架内模式直接使用 LangGraph 这类支持状态管理的编排框架把上下文状态放在图的 State 里。这种方式特别适合多步骤 Agent 任务。LangGraph 的优势在于它天然支持状态在节点间传递节点 A 产生的结果可以显式地写入 State节点 B 在下一轮从 State 读取解决了我前面提到的“工作记忆”问题。第三种是数据流模式适合知识密集型 Agent。这种模式下上下文管理不是一个独立的服务而是穿插在检索、重写、生成整个数据链路里。核心思路是用户问题进来 - 先做 query 改写结合摘要和当前问题 - 检索 - 重排 - 按 token 预算截断检索结果 - 拼装上下文 - 生成回答。这种模式在 RAG 场景里效果最惊艳因为它能把“检索到什么”和“给模型看什么”之间做一个精细的收窄控制。我个人最常用的是第一种加第三种的组合中间件负责会话级的状态管理数据流模式负责单次请求内的上下文精装修。5. 常见问题与排查技巧实录5.1 上下文冲突与“角色错乱”跑 Agent 时间长了你会发现一些特别诡异的现象。最典型的一种是Agent 聊着聊着突然用错误的角色说话或者引用了一段当前会话里根本不存在的信息。这种问题九成是上下文管理没有做好导致的。有一次我排查一个客户工单 Agent用户在前一轮问“帮我查订单号 A100 的物流状态”Agent 回复了详情。过了一小时用户又问“那退款进度呢”Agent 居然能答出和订单 A100 完全对不上的退款信息。我查了半天最后发现问题出在滑动窗口把原始订单消息挤出去了但摘要里只写了“用户查询物流状态”没有保留订单号。模型看到上一条消息是“那退款进度呢”根据摘要里的“物流状态”发挥就编了一个答案。这个案例给我的教训是摘要压缩不能只保留“语义概括”关键实体必须原样保留。我现在在实现 summarizer 的时候会专门抽取出用户提到的实体关键词订单号、日期、金额、产品名等拼在摘要的末尾。由于这些实体是之后轮次有可能引用的关键锚点我会给它们更高的保留优先级。5.2 截断丢信息输出撞上窗口上限第二个高频问题是截断。这个问题的表现是模型生成到一半就中断或者后端报错。很多人第一反应是“模型上下文窗口不够”然后无脑把窗口调大或者把系统提示词改短。但如果你真的查过日志会发现很多时候问题不是“输入太长”而是“输出太长”。这种情况在 Agent 工具调用场景尤为突出。Agent 有时会生成一大段文本再调用工具这段文本加上后续工具的返回结果会一次性超过模型剩余的输出预算。我在排查时养成了一个习惯把每次请求的输入 token 数、输出 token 数、窗口上限三条信息打印在日志里。通过对比这三个数能快速定位是输入侧的问题还是输出侧的问题。如果是输出侧的问题解决思路不是扩窗口而是约束生成长度。你可以告诉模型“你的回答请控制在 300 字以内”也可以在代码层面做校验模型生成超过预算时截断并自动触发一轮“续写”或者“摘要”。遇到用 Rust 做高性能 Agent 服务的同学还会提到流式输出对这个问题有天然的缓解作用——因为流式输出不需要一次性把整个响应算完可以在接近预算时提前发出控制信号。5.3 检索不到正确内容上下文优化的边界问题最后聊聊最让人头疼的检索问题。RAG 是很多 Agent 项目的基础能力但上下文工程和 RAG 的关系经常被搞混。你做了一个完美的压缩策略也做了合理的窗口预算但 Agent 回答问题时还是拿不到正确的内容那问题可能根本不在上下文工程而在检索环节。我遇到过太多这样的案例向量检索在语义搜索上表现很好但父文档层级控制不好导致检索回来的片段跟问题对不上或者文档切分固定按 500 个字符一刀切把关键信息切到了两个 chunk 里。这类问题的典型特征是你把这几个 chunk 搭给一个大模型看是能答对的但给 Agent 用时就答不对——因为 Agent 的上下文已经被前面几轮对话占满了检索模块只能在很小的空间里塞内容。我的建议是做 Agent 时不要把检索和上下文管理割裂开。它们应该是一个整体检索模块负责“找内容”上下文管理器负责“决定放什么内容进窗口”。在实作中系统提示词里有一条很重要告诉模型哪些上下文是辅助信息哪些是核心依据。这听上去像是个提示词工程的小技巧但它实际上改变了模型对上下文的注意力分配。检索回来的参考材料如果跟当前问题相关度不高宁可舍弃也不要硬塞进去因为那不只会浪费 token还会污染模型的注意力。结尾一点私货与后续方向写了这么多最后分享一点纯个人实操体会。我做上下文工程这段时间最大的感受是这个方向的门槛不高但天花板很高。任何一个懂 prompt 的人都能快速上手做一套简单的摘要压缩但真要在生产环境里做到“省 token、不减效果、扛得住并发”需要非常精细的打磨。不要迷信某一个框架或者某篇文章的现成方案你以为的“最佳实践”换一个业务场景可能就是巨坑。如果非要给后来者一条建议我会说从你的应用日志开始把每一轮请求的 token 消耗、上下文内容、模型回答质量都记录下来坚持观察一周。你很快会发现上下文里的“垃圾信息”和“关键信息”分布得有多不均匀也会发现自己设计的阈值在真实流量面前是多么不靠谱。数据不会骗人上下文工程本来就是一项需要持续观测和调优的工程而不是一次性配置完就不管的事。这个方向后面还能怎么扩展我目前正在折腾的是给上下文加一层“长期记忆反馈”当 Agent 发现自己回答问题时反复需要翻看某条摘要它会自动把这部分信息往“长期值得保留”的位置提升。这相当于让上下文管理具备了一定的自我进化能力。等这轮实验跑出稳定效果我再写一篇文章跟大家汇报。

相关新闻

轻量级AI资讯流水线:规则驱动的垂直领域信息提纯系统

轻量级AI资讯流水线:规则驱动的垂直领域信息提纯系统

1. 项目概述:这不是一份“资讯”,而是一套可复用的AI驱动资讯流水线 你手上这份标题——「2026.09.29」科技AI资讯日报|HackerNews精选 全球热点速递——表面看是张日期平台名功能描述的“日报封面”,但真正值钱的,是…

2026/10/7 13:47:46 阅读更多 →
Python扑克牌游戏实战:UI、AI与裁判三模块架构设计

Python扑克牌游戏实战:UI、AI与裁判三模块架构设计

简介:这份资源是面向Python初学者与游戏开发爱好者的《升级》扑克牌游戏完整实现,采用Python编写,涵盖UI界面、AI玩家与裁判监督三大模块,适合想通过实战理解桌面应用架构与游戏规则编程的读者。压缩包共67个文件,以58…

2026/10/7 13:47:45 阅读更多 →
多Agent并行编排实战:用Orca ADE管理AI代理工作流

多Agent并行编排实战:用Orca ADE管理AI代理工作流

做多Agent项目的朋友应该都有这种体验:三个Agent协作时还能靠Python脚本硬撑,一旦变成六个、八个,甚至需要按任务量动态扩容,事情就完全失控了。每个Agent各自维护一份上下文,互相不知道对方改了什么;一个子…

2026/10/7 13:46:45 阅读更多 →

最新新闻

VS Code 下载与常用插件:用 TaoToken 统一 Key 打通 AI 编程链路

VS Code 下载与常用插件:用 TaoToken 统一 Key 打通 AI 编程链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:21:14 阅读更多 →
AI自动化办公工具技术选型指南:从API调用到智能体交付的实践对比(TaoToken统一Key接入篇)

AI自动化办公工具技术选型指南:从API调用到智能体交付的实践对比(TaoToken统一Key接入篇)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:21:14 阅读更多 →
每日安全情报报告 · 2026-04-21:用 TaoToken 统一 Key 打通多源威胁情报聚合

每日安全情报报告 · 2026-04-21:用 TaoToken 统一 Key 打通多源威胁情报聚合

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:21:14 阅读更多 →
车规 PCBA 湿敏器件 MSD 管理实战:从来料到回流焊的全流程管控

车规 PCBA 湿敏器件 MSD 管理实战:从来料到回流焊的全流程管控

1. 引言 做车规 PCBA,MSD(湿敏器件 Moisture Sensitive Device)管理不能只盯仓储。湿敏器件从来料到回流焊,每个环节都可能影响最终可靠性。受潮器件过回流焊,可能出现爆米花、分层、虚焊、空洞等缺陷。下面按实战流程…

2026/10/7 14:21:14 阅读更多 →
使用公司Git提交代码时报错 [remote rejected] main -> main (pre-receive hook declined) error:从 pre-receive hook 到

使用公司Git提交代码时报错 [remote rejected] main -> main (pre-receive hook declined) error:从 pre-receive hook 到

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 14:21:14 阅读更多 →
ARM交叉编译踩坑:-march=armv8.2-a+dotprod+fp16参数详解与避坑指南

ARM交叉编译踩坑:-march=armv8.2-a+dotprod+fp16参数详解与避坑指南

1. 从一次编译报错说起:为什么-march参数值得单独写一篇踩坑记录如果你正在做 ARM 平台的交叉编译,尤其是给带 NPU 或者 DSP 的嵌入式板子编译推理框架、图像处理库,那你大概率在某个时刻写过类似-marcharmv8.2-adotprodfp16这样的编译选项。…

2026/10/7 14:20:14 阅读更多 →

日新闻

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:01:58 阅读更多 →
用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:02:00 阅读更多 →
芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:02:00 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 7:15:40 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 5:29:09 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 9:29:10 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 8:21:32 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 11:43:46 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 13:34:55 阅读更多 →