Agent系统四根支柱:会话、工具、MCP与记忆的工程实践
1. 从标题拆解一个Agent系统的四根支柱第一次看到“会话、工具、MCP、记忆”这四个词摆在一起我的直觉是这是一个把Agent从“能聊天”推进到“能干活”的完整能力清单。会话解决的是上下文怎么组织工具解决的是手能伸多长MCP解决的是外部能力怎么标准化接入记忆解决的是跨会话还能不能记住人和事。四者缺一个Agent就只是个玩具四个都打通它才像一个真正能托付任务的数字同事。这篇内容适合两类人看一类是正在设计或自研Agent框架的开发者想知道每个模块的边界在哪里、坑在哪里另一类是把Agent接进实际业务流程的工程同学关心的是怎么让它在多轮、多工具、多会话的场景下不崩、不丢状态、不重复劳动。我会按“为什么这么设计—核心细节—实操落地—问题排查”的顺序展开尽量把每个决策背后的取舍讲清楚而不是只丢结论。需要先说明一点下面涉及的具体实现是基于当前主流Agent框架的常见做法做的合理推演不同技术栈细节会有差异但设计思路是通用的。你完全可以把它当成一份架构评审清单来对照自己的系统。2. 会话管理Agent的“工作台”而不是聊天记录2.1 会话到底在管什么很多人把会话理解成“聊天历史”这是最容易踩的认知坑。聊天历史只是会话的一个切片真正的会话管理要管四件事消息序列、角色与权限、上下文窗口预算、以及会话生命周期。消息序列决定Agent看到什么角色与权限决定它能以谁的身份说话、能调用哪些工具上下文预算决定哪些历史会被压缩或丢弃生命周期决定会话什么时候创建、挂起、恢复、销毁。我见过不少项目把会话做成一个无限增长的数组每轮把全部历史塞进模型结果token成本爆炸、延迟飙升模型还因为上下文太长开始“失忆”。正确的做法是把会话当成一个有预算的工作台工作台上只放当前任务真正需要的材料其余归档到记忆层。这个边界一旦划清后面工具调用和记忆读写都会顺很多。2.2 上下文窗口的预算分配策略假设你用的模型上下文窗口是128K token听起来很大但实际能用的远没有这么多。系统提示词、工具定义、MCP服务描述、当前会话历史、工具返回结果、记忆召回内容全都要挤在这个窗口里。我的经验分配大致是这样组成项建议占比说明系统提示词与角色设定5%–10%稳定内容尽量精简工具与MCP描述10%–20%工具越多占比越高需动态裁剪会话历史30%–40%近期消息优先远期压缩工具返回结果20%–30%大结果要截断或摘要记忆召回5%–15%按相关度动态注入这个比例不是死的但核心原则是任何一项都不能无限膨胀。工具返回结果是最容易被忽视的“空间杀手”一次网页抓取或数据库查询就可能返回几万token如果不做截断和摘要会话窗口瞬间被撑满。2.3 会话压缩与摘要的实操要点会话压缩不是简单地把老消息删掉那样会丢关键信息。我常用的策略是分层压缩最近N轮保留原文N轮之前做滚动摘要更早的只保留结构化要点比如任务目标、已确认事实、待办事项。摘要本身也要控制长度否则摘要会变成新的负担。具体操作上可以设一个阈值比如会话历史超过窗口的40%就触发压缩。压缩时把待压缩的消息按“用户意图—Agent动作—工具结果—结论”四段式提炼保留决策链而不是对话原文。这里有个细节工具调用的原始参数和返回码要保留因为排查问题时它们是关键证据而自然语言描述可以压缩。注意压缩触发点不要设得太晚等到窗口快满了再压缩模型可能已经在“遗忘”早期关键信息了。我一般留20%的缓冲空间。2.4 多会话隔离与并发处理一个Agent服务往往同时服务多个用户或多个任务会话隔离必须做干净。隔离的维度至少包括消息存储隔离、工具权限隔离、记忆命名空间隔离。我见过因为会话ID复用导致A用户看到B用户上下文的案例根因就是存储层没有按会话维度做硬隔离。并发方面同一个会话内的消息要保证顺序不同会话之间可以并行。实现上可以用会话级锁或者消息队列串行化单会话请求避免两个请求同时读写同一份历史导致状态错乱。这个点在压测时特别容易暴露平时单用户测试看不出来。3. 工具调用让Agent的手真正伸出去3.1 工具设计的粒度与边界工具不是越多越好粒度也不是越细越好。工具太细Agent要调十几次才能完成一个任务延迟和出错概率都上升工具太粗参数复杂、复用性差Agent很难正确填参。我的经验是一个工具对应一个明确的动作参数控制在5个以内返回值结构化。举个例子“查询订单”和“修改订单地址”应该是两个工具而不是一个“订单管理”工具带一个action参数。前者语义清晰Agent容易判断何时调用后者需要Agent理解action的枚举值出错率明显更高。工具描述也要写清楚“什么时候用”和“什么时候不用”这比写参数说明更重要。3.2 工具调用的参数校验与容错模型生成的工具参数不可全信必须做服务端校验。常见问题包括参数类型不对、必填项缺失、枚举值越界、ID格式错误。校验失败时不要直接把错误抛回给模型让它重试而是返回结构化的错误说明比如“参数order_id应为16位数字字符串当前值为空”这样模型下一轮修正的成功率会高很多。容错还要考虑幂等性。同一个工具调用可能因为超时被模型重试如果工具本身不幂等就会产生重复下单、重复扣款这类严重问题。我的做法是给每个工具调用生成一个幂等键服务端在一定时间窗口内对相同幂等键的请求直接返回缓存结果。3.3 工具返回结果的处理策略工具返回结果的处理直接决定会话窗口的健康度。我的处理链路是原始结果先落盘存档然后按类型做处理——结构化数据提取关键字段文本数据截断到合理长度并生成摘要二进制数据只返回元信息。返回给模型的内容要带一个明确的“结果边界”比如用固定标记包裹避免模型把结果和后续对话混淆。对于特别大的结果可以采用“分页引用”的方式先返回摘要和结果ID模型如果需要细节再调用一个“读取结果详情”的工具。这样既控制了窗口占用又保留了按需获取细节的能力。3.4 工具调用的可观测性建设工具调用是Agent系统里最容易出问题的环节可观测性必须做足。至少要记录调用时间、会话ID、工具名、参数、返回状态、耗时、token消耗。这些数据不仅能用于排查问题还能分析哪些工具高频、哪些工具经常失败、哪些参数组合容易出错。我习惯在日志里给每次工具调用打一个trace ID串联起模型请求、工具调用、结果处理整条链路。出问题时按trace ID一查整条链路一目了然。这个投入在系统复杂之后回报极高。4. MCP外部能力接入的标准化协议4.1 MCP解决了什么问题在没有MCP之前每接一个外部能力就要写一套适配代码数据库一套、文件系统一套、第三方API一套每套的参数格式、错误处理、鉴权方式都不一样。Agent框架要维护大量胶水代码扩展成本极高。MCP的价值在于把这些外部能力抽象成统一的服务描述和调用协议Agent只需要理解一套标准就能接入任意实现了MCP的服务。你可以把MCP理解成“Agent世界的USB接口”不管外接的是键盘、鼠标还是硬盘接口形状是统一的Agent不需要为每个设备写驱动。这个类比不严谨但很好懂。4.2 MCP服务的描述与发现MCP服务需要向Agent声明自己提供哪些能力、每个能力的输入输出格式是什么。这份描述的质量直接决定Agent能不能正确使用。描述要包含能力名称、用途说明、参数schema、返回值schema、使用示例、以及必要的限制条件。发现机制上常见做法是启动时拉取所有已注册MCP服务的描述运行时按需加载。服务多的时候要注意描述本身占用的上下文可以按任务类型做分组只加载当前任务相关的服务描述。4.3 MCP接入的实操步骤接入一个MCP服务大致分四步服务注册在Agent配置中登记MCP服务的地址和鉴权信息。能力拉取启动时调用服务的描述接口获取能力清单。描述注入把能力描述按预算裁剪后注入系统提示词或工具列表。调用转发Agent发起调用时框架把标准请求转发给MCP服务再把结果标准化返回。每一步都有坑。注册阶段的鉴权信息要加密存储拉取阶段要处理服务不可用的情况不能让一个服务挂掉导致整个Agent启动失败注入阶段要控制描述长度转发阶段要做超时和重试控制。4.4 MCP与原生工具的关系MCP服务和原生工具不是替代关系而是互补。高频、核心、对延迟敏感的能力适合做成原生工具直接内嵌在框架里长尾、第三方、变化频繁的能力适合通过MCP接入。我的划分标准是如果一个能力每天调用上万次或者延迟要求低于100毫秒就做原生否则优先MCP。这样划分的好处是核心链路稳定可控扩展能力灵活低成本。全部走MCP会导致核心调用多一层转发开销全部做原生又会让框架越来越臃肿。5. 记忆系统让Agent跨会话记住人和事5.1 记忆的分层设计记忆不是一个大池子至少要分三层工作记忆当前会话内的临时信息、短期记忆近期会话的关键事实、长期记忆跨会话的稳定偏好和知识。工作记忆随会话销毁短期记忆保留数天到数周长期记忆长期保留但需要定期整理。分层的意义在于成本和精度的平衡。工作记忆可以全量保留短期记忆需要摘要长期记忆需要向量化检索。如果不分层要么成本失控要么关键信息被淹没。5.2 记忆的写入时机与内容筛选什么信息值得写入记忆我的筛选标准是用户明确表达的偏好、任务中确认的稳定事实、以及可复用的结论。比如“我习惯用表格看数据”值得记“今天天气不错”不值得记。写入时机上可以在会话结束时做一次批量提炼也可以在关键节点实时写入。写入内容要结构化至少包含记忆类型、内容、来源会话、时间戳、置信度。置信度很重要模型提炼的记忆不一定准确低置信度的记忆在召回时要降权或标注。5.3 记忆召回的相关度排序召回不是把所有相关记忆都塞进上下文而是按相关度排序后取Top-K。相关度计算可以综合向量相似度、时间衰减、置信度、使用频率几个因子。时间衰减让近期记忆优先使用频率让常用记忆优先置信度过滤掉不可靠记忆。召回数量要控制一般3到5条足够。召回太多会挤占上下文还会让模型在矛盾信息之间纠结。如果召回的记忆之间有冲突要在注入时标注冲突让模型知道需要澄清。5.4 记忆的更新与遗忘机制记忆会过时必须有更新和遗忘机制。更新包括覆盖新事实替代旧事实、合并多条相关记忆合并成一条、修正发现错误时更正。遗忘包括过期删除超过保留期的短期记忆、低价值清理长期未被召回且置信度低的记忆、用户主动删除。这里有个容易忽视的点记忆更新要有版本记录否则一旦更新出错无法回滚。我一般保留最近三个版本的记忆内容出问题可以追溯。6. 四者协同一个完整任务的执行链路6.1 从用户输入到任务完成的全流程把四个模块串起来看一个完整任务用户发起请求会话模块创建或恢复会话注入系统提示词和工具描述记忆模块召回相关长期记忆注入上下文模型判断需要调用工具工具模块执行调用并处理结果如果工具涉及外部服务通过MCP转发任务完成后记忆模块提炼本次会话的关键信息写入记忆会话模块决定是否压缩历史或结束会话。这条链路上任何一环出问题都会影响整体体验。比如记忆召回不准模型就会基于错误前提行动工具结果处理不当会话窗口就会被撑爆MCP服务超时任务就会卡住。6.2 状态一致性保障四个模块各自维护状态一致性是个大问题。我的做法是会话状态是主状态工具调用和记忆读写都挂在会话ID下通过事务或补偿机制保证最终一致。比如工具调用成功但结果写入会话失败要有重试或补偿逻辑不能让状态悬空。跨会话的记忆写入尤其要注意不能因为记忆写入失败就影响主任务完成。记忆写入应该是异步的、可重试的失败时记录日志但不阻塞主流程。6.3 性能与成本的平衡四个模块都会消耗资源和成本。会话压缩消耗模型调用工具调用消耗外部资源MCP转发增加延迟记忆检索消耗向量计算。优化时要抓大头通常工具调用和模型推理是成本大头记忆检索和会话压缩是次要的。我的优化顺序是先优化工具调用的参数和返回处理减少无效调用和大结果再优化会话压缩策略降低压缩频率最后优化记忆检索减少召回数量。这个顺序的回报率最高。7. 常见问题与排查技巧实录7.1 会话相关高频问题问题现象可能原因排查方向模型“忘记”早期信息上下文被压缩或截断检查压缩触发点和摘要质量多用户上下文串扰会话隔离不彻底检查存储层会话ID隔离响应越来越慢历史无限增长检查会话长度和压缩策略并发请求状态错乱单会话未串行化检查会话级锁或队列7.2 工具与MCP相关高频问题工具调用失败最常见的原因是参数校验不通过和超时。参数问题要看模型生成的原始参数和服务端校验日志对比超时问题要看是工具本身慢还是网络问题。MCP服务不可用要有降级策略不能让一个外部服务拖垮整个Agent。还有一个隐蔽问题工具描述和实际行为不一致。比如描述说返回列表实际返回分页对象模型就会解析错误。这个要在接入时做契约测试确保描述和实现一致。7.3 记忆相关高频问题记忆召回不准通常有三个原因向量模型不适合当前语种或领域、召回排序因子权重不合理、记忆内容本身质量差。排查时先看召回结果再回溯记忆写入内容最后检查排序逻辑。记忆冲突是另一个常见问题用户前后说法不一致时两条记忆都存着召回时模型不知道该信哪个。解决方法是给记忆加时间戳和置信度召回时优先近期高置信度的冲突时在上下文里标注让模型澄清。7.4 我的避坑清单会话压缩一定要留缓冲别等窗口满了再压。工具参数服务端必须校验不能信模型。工具调用要幂等重试不能产生副作用。MCP服务要有健康检查和降级。记忆写入要异步不能阻塞主流程。记忆要有版本更新要能回滚。所有模块都要有trace ID排查时能串起来。压测要模拟多会话并发单会话测试发现不了隔离问题。8. 一些实操后的个人体会这套东西我前后调了大半年最大的体会是Agent系统的难点不在模型而在工程。模型能力再强会话管理混乱、工具调用不可靠、记忆读写不一致整体体验就是不行。反过来把这四个模块的工程做扎实即使模型能力一般Agent也能稳定干活。另一个体会是不要追求一步到位。我一开始想把记忆系统做得很智能结果复杂度失控后来退回到“结构化写入向量召回时间衰减”的简单方案反而稳定好用。工具也是先做几个核心的跑通了再扩展。MCP接入更是先接一两个服务验证流程再批量接入。最后分享一个小技巧给每个模块加一个“降级开关”。会话压缩失败就退回全量历史虽然贵但能用工具调用失败就返回明确错误让模型换路径MCP服务挂了就临时禁用相关能力记忆检索失败就不注入记忆。有降级开关系统在部分模块出问题时还能提供基本服务而不是直接崩掉。这个设计在线上救过我好几次。

相关新闻

TensorFlow生产环境实战:从训练到部署的避坑指南

TensorFlow生产环境实战:从训练到部署的避坑指南

说实话,每次一聊到 TensorFlow,总有人会问我一句:“现在还有必要深入学习它吗?社区里到处都在说别的框架更好用。”我在某团队带项目这几年,从最初的图像分类 Demo 到后来的产线级推理服务,TensorFlow 一直…

2026/10/14 21:29:12 阅读更多 →
模型检查实战:有界模型检查与抽象细化全解析

模型检查实战:有界模型检查与抽象细化全解析

“Model checking Part IV”这个系列走到第四篇,默认你已经把基本概念过了一遍:状态空间、时态逻辑、Kripke结构,以及最原始的那套“穷举所有可达状态”的验证思路。可一旦你真的拿它去验证工业级系统,立刻就会撞上三堵墙&#xf…

2026/10/14 21:29:12 阅读更多 →
显存不够也能跑大模型?airllm层间卸载原理与实战

显存不够也能跑大模型?airllm层间卸载原理与实战

我第一次看到airllm这个名字的时候,第一反应是"又一个跑大模型的工具,估计又是那种要吃满整张卡才能动的玩意儿"。直到身边一位开发者在只有4GB显存的旧笔记本上,把一个几十B参数的大模型真的跑出了推理结果,我才意识到…

2026/10/14 21:29:12 阅读更多 →

最新新闻

KNN图像识别入门:从PCA降维到手写数字分类实战

KNN图像识别入门:从PCA降维到手写数字分类实战

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

2026/10/15 1:37:04 阅读更多 →
52pojie 的 IoT 固件分析:熵值会告诉你哪一段藏了东西

52pojie 的 IoT 固件分析:熵值会告诉你哪一段藏了东西

副题:魔术字、香农熵、结构体——拆开一个固件镜像的三把钥匙 摘要:吾爱破解软件调试区里有一篇《IoT 漏洞分析之模拟环境搭建》(6037 回复),同区还有《记一次手机付费充电设备研究》(7196)。这…

2026/10/15 1:37:04 阅读更多 →
双 11 核心链路变异测试大摸底:让关键交易状态机测试坚不可摧

双 11 核心链路变异测试大摸底:让关键交易状态机测试坚不可摧

在电商交易系统中,最核心、也最令架构师夜不能寐的领域内核,永远是有限状态机(Finite State Machine, FSM)。 在双 11 狂风暴雨般的流量洪峰冲击下,一笔交易订单在几毫秒内可能经历极其错综复杂的状态跳转:…

2026/10/15 1:37:04 阅读更多 →
u-boot-2020.07在Exynos4412上的电源时钟内存初始化实战

u-boot-2020.07在Exynos4412上的电源时钟内存初始化实战

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

2026/10/15 1:37:04 阅读更多 →
行业术语同义词图谱挖掘:从非结构化语料到标准化知识库的语义归一

行业术语同义词图谱挖掘:从非结构化语料到标准化知识库的语义归一

在将海量企业内部非结构化语料(如研发设计文档、售后工单、专家经验纪要、行业研报)汇聚到统一知识库并驱动 RAG(检索增强生成)系统时,工程团队往往面临一个巨大的语义鸿沟——“专有名词的极度多样性与非标准性”。 在…

2026/10/15 1:37:04 阅读更多 →
工业机器人坐标系全解析:从原理到标定实操

工业机器人坐标系全解析:从原理到标定实操

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

2026/10/15 1:36:03 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →