重生AI Agent应用开发工程师之上下文管理与大模型网关
今天我们来聊一下大模型中的“上下文管理(Context Management)”。很多人第一次接触 LLM 时都会有一个疑问:为什么它能够记住前面说过的话,并且后续回答还能和之前的内容关联起来?实际上,当前的大模型本身并不具备真正意义上的“长期记忆”。绝大多数 LLM 都是无状态(Stateless)的。也就是说,每一次请求对模型而言,都是一次全新的推理过程。之所以我们会感觉模型“记得”之前的内容,本质上是因为系统在请求时,将历史对话、用户信息、业务数据等内容一起重新发送给了模型。模型基于这些上下文进行推理,从而形成连续性的对话体验。这也就是所谓的:上下文管理(Context Management)。
为什么上下文管理如此重要?
最近我在开发知识库系统时,对这个问题有了比较深的体会。
一开始,我采用的是一种非常简单的方案:
-
- 将历史上下文保存在内存中
- 每次取最近的 10 条记录发送给模型
这种方案在普通聊天场景下问题不大,但在知识库场景中,很快就暴露出了问题。
因为知识库中的数据并不是“等权重”的:
-
- 有些是用户真实问题
- 有些是系统检索结果
- 有些是中间推理内容
- 有些是历史无效对话
如果只是简单地按时间顺序拼接上下文,就会导致:
-
- 上下文噪声越来越大
- 有效信息被淹没
- 模型注意力被错误内容干扰
最终最明显的问题就是:
大模型开始出现“幻觉(Hallucination)”
例如:
-
- 胡编不存在的数据
- 错误引用历史内容
- 将无关信息错误关联
- 回答偏离真实业务逻辑
后来的优化方案
后面我对上下文架构进行了调整。
我不再单纯依赖“最近几条对话”,而是将上下文信息进行向量化后存入:
-
- 向量数据库(Vector Database)
例如:
-
- Milvus
- Pinecone
- Weaviate
- Qdrant
这样做之后,系统会基于“语义相似度”检索真正相关的上下文,而不是机械地取最近几条记录。
优化后的效果非常明显:
-
- 幻觉问题大幅减少
- 上下文相关性更高
- 模型回答稳定性提升
- 长对话质量明显改善
本质上,这已经从: “时间维度的上下文管理” 升级为了:“语义维度的上下文管理”。
但问题还没有结束:Token 限制
即便解决了上下文相关性问题,还有一个非常现实的问题:Token 上限,所有大模型都有上下文窗口限制(Context Window)。
例如:
-
- 8K
- 32K
- 128K
- 甚至更高
但无论窗口多大,它始终是有限的。
当:
-
- 历史对话越来越长
- 检索内容越来越多
- 系统 Prompt 越来越复杂
最终都会遇到:
-
- Token 超限
- 请求失败
- 成本飙升
- 推理速度下降
因此,仅仅“存上下文”是不够的。更重要的是:如何对上下文进行“压缩(Compression)”和“摘要(Summarization)”
常见的上下文压缩方案
目前业内比较常见的做法包括:
1. 对话摘要(Conversation Summary)
将长对话压缩为结构化摘要,例如:
-
- 用户关注什么
- 已完成哪些步骤
- 当前问题是什么
- 关键结论是什么
然后只保留摘要,而不是完整历史记录。
2. 分层记忆(Hierarchical Memory)
将记忆拆分为:
-
- 短期记忆(Recent Context)
- 长期记忆(Long-term Memory)
- 业务知识(Knowledge Base)
不同类型的数据采用不同存储策略。
3. 基于 LLM 的上下文压缩
这是目前比较先进的一种方案。
通过另一个 LLM 对历史内容进行:
-
- 提炼
- 去噪
- 归纳
- 结构化
然后重新写入向量数据库。
例如:原本 5000 Token 的历史内容,
可能最终压缩成:
-
- 用户画像
- 当前任务
- 已知约束
- 关键业务数据
最终只保留几百 Token。
这样既能降低成本,又能保留核心语义。
一个很关键的认知
很多人以为:“做 AI 应用最重要的是 Prompt”,但实际上,当项目进入生产环境后,你会发现:真正决定系统质量的,往往是:
-
- 上下文管理
- 记忆架构
- 检索策略
- Token 控制
- 数据清洗
- 向量召回质量
Prompt 只是最表层的一部分。而真正困难的部分,是:如何让模型在有限 Token 内,始终拿到“最正确的信息”。
下面我们来用python的langchain的LLM框架和dependency_injector依赖注入,而这次课程用的是redis来做记录上下文,当然我们也可以使用向量数据库,本章只用redis做一个简单的上下文管理。
上面代码就是我们本章的上下文管理,这就是我们现有看到一整套Chat对话的的系统,结合上一章的RAG可以快速帮助企业文档知识库的搜索。利于专业知识的学习。
from dependency_injector.wiring import ( inject, Provide ) from fastapi import ( APIRouter, Depends ) from app.containers.container import Container from app.models.dto import ( AskRequest, AgentResponse ) router = APIRouter() @router.post( "/ask", response_model=AgentResponse ) @inject async def ask( req: AskRequest, agent_service = Depends( Provide[ Container.agent_service ] ) ): return await agent_service.ask(req)
import os from fastapi import FastAPI from app.api.agent import router as agent_router from app.containers.container import Container from fastapi.middleware.cors import CORSMiddleware def create_app() -> FastAPI: # ========================================= # FastAPI # ========================================= app = FastAPI( title="Agent Aggregator API" ) # ========================================= # CORS # ========================================= app.add_middleware( CORSMiddleware, # 允许前端地址 allow_origins=[ "http://localhost:1003", "http://127.0.0.1:1003", ], # 是否允许 Cookie allow_credentials=True, # 允许请求方法 allow_methods=["*"], # 允许请求头 allow_headers=["*"], ) # ========================================= # Dependency Injector Container # ========================================= container = Container() # ========================================= # Config # ========================================= container.config.from_dict({ "llm_base": os.getenv( "LLM_BASE", "https://localhost:5001" ), "api_key": os.getenv( "LLM_API_KEY", "sk-" ), "mcp_base": os.getenv( "MCP_BASE", "http://localhost:5265" ) }) # ========================================= # Wire DI # ========================================= container.wire( packages=[ "app.api" ] ) # ========================================= # 挂载 container # ========================================= app.container = container # ========================================= # Router # ========================================= app.include_router( agent_router, prefix="/api/agent" ) return app app = create_app() # ============================================= # 启动 # ============================================= if __name__ == "__main__": import uvicorn uvicorn.run( "app.main:app", host="0.0.0.0", port=int( os.getenv( "PORT", "8000" ) ), # 开发环境建议 True reload=True )
最后看看我们的展示效果,以下是用vue实现的chat UI界面:

python agent源码地址:https://gitee.com/runwei/pylang-chain
mcp service源码地址:https://gitee.com/runwei/mcp.git
net ocelot网关源码地址:https://gitee.com/runwei/netocelot.git
chatUI vue界面的源码地址:https://gitee.com/runwei/chaiui
接下来:网关(Gateway)架构设计
在完成 AI 对话系统后,接下来一个非常关键的部分,就是:AI 网关(AI Gateway)例如:API 统一入口,服务路由,身份认证,权限校验,限流,熔断,负载均衡,日志追踪,链路监控。而在 AI 系统中,网关的重要性会更高。因为大模型接口相比传统 API,还多了一个非常核心的成本维度:Token 消耗。因此,我们在传统网关能力基础上,又额外增加了一层:Token Usage Tracking(Token 用量统计)。
为什么要统计 Token?
因为目前几乎所有主流大模型平台,都是基于 Token 进行计费。
例如:
-
- 输入 Token
- 输出 Token
- 上下文 Token
- Embedding Token
都会直接影响最终成本。因此,如果企业内部没有 Token 管控能力,就很容易出现:
-
- 成本不可控
- 用户滥用
- 高并发资源浪费
- 模型调用失衡
所以在 AI Gateway 中,我们通常会实现:
1. Token 实时统计
记录:
-
- 请求 Token
- 响应 Token
- 总消耗 Token
- 模型名称
- 用户 ID
- 会话 ID
- 请求时间
2. 用户级配额控制(Quota)
例如:
-
- 每日 Token 限额
- 每月调用额度
- 不同模型不同价格
- VIP 用户配额提升
3. 限流与熔断
防止:
-
- 高频恶意请求
- 模型服务雪崩
- 下游 API 崩溃
- 突发流量冲击
常见方案包括:
-
- 漏桶算法
- 令牌桶算法
- 熔断器(Circuit Breaker)
- 降级策略
4. 多模型负载均衡
在生产环境中,通常不会只接一个模型。
例如可能同时接入:
-
- OpenAI
- Anthropic
- DeepSeek
网关可以根据:
-
- 模型负载
- 响应速度
- Token 成本
- 用户权限
- 可用性状态
动态路由到不同模型。这其实已经非常接近现代 AI 平台的核心架构了。
AI 系统真正复杂的地方
很多人认为:“接一个大模型 API 就算 AI 系统了”,但真正进入生产环境后会发现:真正复杂的并不是模型调用本身,而是外围系统。
例如:
-
- 上下文管理
- RAG 检索
- 向量数据库
- Prompt 编排
- AI Gateway
- Token 计费
- 会话记忆
- 权限体系
- 审计日志
- 多模型调度
这些部分,才是真正决定 AI 系统是否能够企业化落地的关键。除此之外,我们要实现大模型的高可用的情况下,可搭配k8s容器编排来实现。
总结
由此看来我们的大模型,在实现大平台时,可以看作一个大脑服务,提供其他服务调用。在整个大模型体系来看,应用层的开发是相对简单的,技术讲究的是动手能力,所以快去动动你发财的小手吧。

浙公网安备 33010602011771号