做智能体这几年我越来越觉得一个观点应该被反复强调智能体和普通“套了壳的大模型”之间的分水岭恰恰不在模型层而在感知层。很多人一上来就调Prompt、选模型、接Agent框架结果跑起来发现智能体像个“睁眼瞎”——信息摆在面前看不见用户说两句就丢上下文业务数据明明能查到却不知道怎么喂给它。这基本都是感知系统没有认真构建的锅。这篇文章就把“第7章 智能体感知系统构建”这件事拆开揉碎讲清楚。我会从感知系统的整体设计思路讲起再到多源数据接入、上下文管理、知识库感知融合最后给出一套可以直接参考的简化实现方案和踩坑记录。适合正在做智能体开发、或者想从“调用模型”升级到“构建完整智能体”的开发者、算法工程师和技术产品经理阅读。1. 感知系统整体设计与思路拆解1.1 什么是感知系统——先搞清楚它在智能体里的位置感知系统是智能体接收外部信息的入口负责把现实世界或业务系统中的零散数据转换成模型能够理解、推理和决策的结构化信息。用生活类比来说大模型是大脑规划决策是思考而感知系统就是眼睛、耳朵和皮肤。没有感知大脑再聪明也做不了任何判断。但这里有个非常容易误判的点感知不等于“收集数据”。数据只是原料感知是把原料加工成“当前状态下智能体需要理解的语义”。同样是拿到一条用户消息“我要退货”感知系统要做的不仅是把这句话放进Prompt还要结合用户历史订单、售后政策、当前客服会话状态判断出这是一次售后咨询情绪是否激烈是否需要优先转人工。这个过程才是感知系统的完整闭环。1.2 感知层的五级架构拆解我在实际项目中会把感知层拆成五个子层每一层职责单一替换起来也方便数据源层定义所有可能的数据来源包括用户输入、业务API、数据库、日志、消息队列、Webhook回调、甚至文件上传和图像输入。接入层负责打通数据源和智能体之间的通道统一协议HTTP/WebSocket/gRPC、统一鉴权、统一连接管理。解析与清洗层把不同格式、不同质量的数据转换成统一的数据结构做去重、纠错、归一化。语义理解层从清洗后的数据中提取意图、实体、情感、状态标签这一步是整个感知系统的核心增值所在。状态管理层将零散的感知结果累积成可查询、可回溯、带时效的上下文状态供规划模块和模型调用。举个例子一个销售智能体要感知“客户是否高意向”数据源层可能包含官网浏览记录埋点API、销售备注CRM系统、聊天消息对话服务、企业公开信息外部API。接入层统一获取后解析层把时间戳格式化、把渠道来源归一化语义理解层从“客户主动问价格”“浏览报价单页面三次”这些信号里抽取意向标签最后状态管理层汇总成一份带置信度的客户画像。这个过程看起来复杂但每一层都相对独立很好维护。1.3 为什么感知系统直接决定智能体的能力上限我见过不少团队花大力气调模型效果却忽视感知层。结果就是同一个模型别人做出来的智能体像个老手自己做的像失忆症患者。差异不在推理而在它能不能在关键时刻拿到关键信息。一个做智能客服的朋友跟我吐槽他接了一个大模型API之后满心欢喜结果用户问“我上个月订单为什么还没发货”模型回答得很有礼貌但全是模板话术因为它根本没感知到订单查询接口里返回的数据。后来把订单状态、物流轨迹、预计到达时间作为结构化感知结果注入上下文同样的模型立刻变得“懂事”了。感知系统的价值曲线是感知覆盖的信息越准确、越及时模型需要“猜”的部分就越少回答的可信度和可操作性就越高。与其花大量精力去设计复杂Prompt来弥补信息缺失不如先把感知链路打通让模型“看得见”再说话。2. 感知数据接入与预处理实战2.1 多源数据接入——先盘点“感知源”再写代码设计感知系统的第一步不是写代码而是拉一张表把智能体运行过程中可能触碰到的所有信息源列出来。我常用的盘点维度是数据来源、数据格式、更新频率、实时性要求、访问方式、敏感级别。以我最近做的一个项目运维智能体为例感知源有下面这些数据来源数据格式更新频率访问方式典型用途用户对话消息文本实时WebSocket意图识别、情绪判断监控系统告警JSON秒级Webhook异常事件感知数据库状态结构化查询结果分钟级SQL/API业务指标感知日志系统半结构化文本实时消息队列根因定位辅助外部知识库文档/网页日级检索API参考知识匹配用户行为埋点事件流准实时数据管道会话偏好感知这张表的意义在于让团队对“要感知什么”达成一致避免开发到一半才发现某些重要数据没有接入。实际操作中我还会在表上加一列“优先级”第一版只接P0数据源P1往后放防止范围蔓延。2.2 数据清洗与标准化——脏数据会污染整个推理链感知系统的输入质量直接决定上层语义理解的准确率。脏数据比没有数据更可怕因为模型会一本正经地基于错误信息做推理。我踩过的坑包括订单号的数字型ID在不同接口里被当成整数和字符串混传去重时出现两套ID时间戳有的带时区有的不带排序时错乱用户消息里混入大量无意义字符直接拉低情感分析准确率。这些问题的统一解法是在解析层写一套清洗管线按顺序处理缺失值填充或标记、格式归一化时间统一UTC8、ID统一走字符串、去除重复事件、过滤噪声文本链接、乱码、无意义符号保留占位信息。清洗规则要沉淀成可配置的规则集不要每次都hardcode在代码里。这里有一个经验值一个感知模块里清洗和归一化的代码量往往是语义理解代码的两倍以上。这很正常别嫌脏活累活多这块做扎实了后续省下的排查时间远超预期。2.3 时效性管理——感知信息必须带“保鲜期”感知信息和静态知识最大的区别就是时效性。同样的数据两秒钟前是有效状态两分钟后就可能过期甚至引发错误决策。我在感知层给所有事件和状态都打上“新鲜度”标签用时间戳过期策略来控制。具体做法每条感知数据入库时记录采集时间和有效期读取时先判断是否过期。比如库存数量是秒级数据超过5秒就标记过期决策时不再作为参考用户会话偏好是分钟级数据10分钟内有效企业基础信息是日级数据24小时内都可用。过期数据要么主动触发重新采集要么从上下文中被降权移除优先级低于新鲜数据。关于时效性还有一点值得注意不要让过期数据“静默残留”。智能体如果把旧状态当成当前状态会在用户看来非常“蠢”。所以感知状态管理要包含“事件撤销”和“状态回退”机制例如某个告警自动恢复后必须立刻从感知上下文里把这条异常标记清除而不是让模型把已恢复的故障继续当作当前风险分析。3. 上下文管理与环境感知3.1 会话级上下文——从“失忆”到“有连续记忆”没有上下文管理的智能体对话超过三轮就开始胡言乱语。本质原因是模型输入只能覆盖有限内容而感知系统负责决定“哪些历史信息值得留下、哪些可以丢弃、哪些需要压缩”。我通常把智能体的上下文分成三层短期工作记忆当前对话轮次内的全部交互直接保留完整内容。会话记忆过去N轮的核心信息做摘要或抽取关键结构化字段如用户ID、诉求类型、当前进度。长期记忆跨会话的用户画像、历史偏好、原始行为记录带权重按需召回。举例一个理财咨询智能体如果只在当天会话里知道用户“偏向稳健”但长期记忆里已经记录了用户三个月前问过“基金定投怎么选”那么这次推荐策略就完全不一样。感知系统要主动从长期记忆里拉取这些相关历史而不是等模型自己“想起来”。3.2 环境状态感知——时间、位置、设备、业务状态会话级上下文关注“用户说了什么”环境状态感知关注“系统此刻处于什么环境”。两者的区别在于对话内容会随轮次变化但环境状态往往是持续的隐含约束。我整理的环境感知要素至少包括当前时间是否工作日、是否营业时间、用户位置如涉及配送/门店选择、设备类型移动端还是桌面端影响交互方式、业务系统状态某个外部服务是否可用、当前订单流程处于哪个审批节点。这些要素不需要用户说出口但智能体需要主动感知。这里引出一个概念“智能体技能敏感变量”。通俗解释就是某些环境变量一旦变化智能体的技能执行方式就要跟着变。比如外卖智能体的“预计送达时间”这个敏感变量会同时影响话术用“尽量准时”还是“会有延迟”、配送时长预估逻辑、以及要不要主动推送补偿。感知系统必须能识别并跟踪敏感变量当它发生跳变时触发策略切换。3.3 多模态感知——文本之外的信息接入智能体的感知不能只停留在文本。用户上传一张售后图片、打开某个页面的截图、语音转文字后的语音特征这些都属于感知信息。多模态感知的核心思想是所有非文本信息在进入模型之前都要转换成模型可以消费的统一表征。我的做法分两步先用轻量识别模型或API把图片/音频转成结构化描述“图片中含有一双有磨损痕迹的运动鞋”再把这个描述作为文本感知结果融入上下文。语音场景还可以额外提取语速、停顿、音量等特征作为情绪判断的信号。多模态转文本会损失一部分细节但胜在通用、稳定、成本低适合大多数业务场景。如果涉及图像细节判断类任务则要保留图像编码后的向量表征与文本一起拼入上下文。3.4 上下文窗口预算——让信息“排好队”进模型模型上下文窗口是有限的感知系统要解决的是信息竞争问题把最相关、最新鲜、最容易影响决策的信息排到前面把次要信息压缩或延后。我在工程上踩过最严重的坑就是无脑把所有感知结果拼成一个超长Prompt结果模型开始“注意力稀释”抓不住重点。现在我在感知层做“上下文预算分配”比如当前可用上下文总计8000 token预算的话当前用户输入预留1500 token高优先级结构化状态订单状态、用户ID、紧急告警预留2500 token检索到的知识片段预留2500 token历史会话摘要预留1500 token临时任务信息1000 token。超过预算的感知结果按优先级降权只保留摘要或完全丢弃并在状态日志里记录被丢弃的原因。这条经验我强烈建议直接抄上下文预算分配做得好不好直接影响智能体“看起来聪明还是话痨”。4. 知识库感知与检索增强4.1 知识库构建——先让智能体“有东西可感知”知识库感知是感知系统的高级形态智能体在决策时可以主动感知相关领域知识。这也正是RAG的核心价值所在。构建知识库的第一步是把散落在文档、FAQ、工单、手册中的信息清洗、切分、向量化形成可检索的知识资产。实际操作中我会把知识构建流程定义成标准管道采集从内部Wiki、导购手册、历史工单中拉取原始文档。清洗去掉页眉页脚、导航重复内容、无效表格。切分按标题层级和段落边界切成400~600字的知识块块与块之间保留10%左右的重叠防止语义断层。向量化用Embedding模型把每块转成向量同时保留原文块作为展示层内容。索引写入向量数据库并建立标量字段如来源、更新时间、适用场景用于过滤。切分大小是有讲究的。切小了检索精准但上下文碎片化切大了信息完整但主题混杂。经验值是面向问答场景500字左右效果比较均衡如果是操作步骤类文档可以按步骤切得更细。4.2 感知触发与检索策略——什么时候主动去“感知”知识不是每个问题都需要检索知识库。如果智能体对每个请求都去向量库里扫一遍延迟和成本都会飙升。我采用多级触发的策略显式触发用户消息中包含清楚的名词或产品名比如“你们的退款政策”“H100服务器的配置”直接触发对应知识域检索。隐式触发用户问题明显超出当前会话上下文的能力范围比如聊到技术细节但上下文里没有相关背景信息此时触发通用知识检索。阈值触发把用户消息向量化后跟当前对话摘要做相似度计算如果相似度低说明历史上下文无法支撑回答启动知识库补充感知。检索出来的知识片段还需要重新排序和过滤。我的做法是先按向量相似度召回Top 20再用一个轻量rerank可以用大模型的打分能力筛出Top 5并根据和用户问句的匹配度决定哪些完整保留、哪些压缩成一句话。这比直接拿Top 3拼进Prompt的效果明显更好尤其是在知识库比较大、相似干扰项多的情况下。4.3 感知结果与生成融合——组装上下文而不是“堆积木”感知结果的融合是最考验工程能力的一环。同样一堆信息排列方式不同模型产出质量天差地别。我的组装原则是先状态后知识再历史。顺序大概是系统指令固定规则→ 当前会话状态用户身份、当前任务、敏感变量→ 新增感知事件订单状态变更、新触发的告警→ 相关知识片段 → 最近几轮对话摘要或原文。这样模型在读上下文的时候先知道“我是谁、用户是谁、当前什么状态”再看“发生了什么、有什么知识可用”最后理解“最近聊了什么”。特别提醒不要把原始知识全文都塞进去每块知识在进入Prompt前都要做一轮“裁剪”只保留和当前问题相关的段落和关键数字。你喂给模型的感知信息必须是经过提炼的而不是数据堆积。感知的质量单位是“决策所需信息密度”不是“字节数”。4.4 知识库更新与感知保鲜——别让智能体“学了旧地图”知识库跟业务现状脱节是感知系统里最隐蔽的雷。政策改了三天智能体还在按旧政策回复用户一投诉一个准。我在知识库层面做了三层保鲜机制第一层是版本化每次知识更新都生成新版本线上环境只激活最新版本旧版本仅用于对比回滚。第二层是变更日志记录每个知识块的增删改时间和原因方便追踪异常。第三层是使用反馈回写如果检索到某条知识用户点击了“没有帮助”或转人工就把这个负反馈标到对应的知识块上定期清理低分块。知识库保鲜容易被忽视但想构建一个能长期稳定运行的智能体这步偷不了懒。感知系统不只是把信息带进来还要保证带进来的信息是当前最可信的版本。5. 感知质量评估与自反馈闭环5.1 感知质量指标体系——不量化就没法优化我从实践里沉淀了一套感知系统质量指标分享给大家直接参考指标含义目标值参考感知覆盖率应感知到的关键事件中实际感知到的比例≥95%感知准确率感知到的信息中被验证正确的比例≥90%感知及时性从事件发生到进入感知状态的平均延迟≤3秒关键事件上下文有效利用率Prompt中感知信息实际被模型参考的比例≥60%知识检索命中率触发检索后返回的内容与问题直接相关的比例≥70%信息新鲜度上下文里未过期信息的占比≥95%这些指标不用一次性全做可以按阶段挑重点。比如刚上线时重点看感知覆盖率和准确率运行稳定后再看有效利用率和及时性。但指标一定要有否则团队优化的方向就变成“猜”。5.2 线上反馈闭环——从用户行为中学习感知遗漏感知准确性不可能靠离线评估一锤定音必须依赖线上数据反馈修正。我常用的反馈信号有三类第一类是用户显式反馈用户点“这个回答没用”或在问卷里说“没答到点上”。第二类是用户隐式行为智能体给出答案后用户不再追问说明回答基本满足或者用户重复表述同一个问题说明感知可能漏了信息。第三类是系统旁路信号用户要求转人工、工单被重复开启、退款流程异常。这些信号实时回到感知日志里做复盘。比如我发现某个售后智能体遇到“发票问题”时用户满意度骤降回放日志后发现是因为发票开具状态的数据源没有接入感知层。补上这个感知源后满意度立刻回升。这就是反馈闭环的价值——感知缺失不是靠推理推出来的是靠行为信号暴露出来的。5.3 自适应调整——感知策略也要动态调参感知策略不是一成不变的。同一个智能体用电高峰时和凌晨空闲时用户需求分布完全不同业务大促期间订单状态感知优先级应该临时调高新产品上线后知识库的检索权重也要跟着调整。我实现的自适应机制很简单给感知参数如TopK数量、上下文预算分配、知识检索阈值加一个可动态读取的配置中心线上运行的服务每次做感知决策前先拉一次最新的参数配合定时分析指标自动调参。初期可以靠人工定时调跑通后可以接一个自动化规则引擎例如“知识检索命中率连续30分钟低于50%自动把检索阈值下调5%”。自适应调整的要点是小步慢跑每次只调整一个维度观察30分钟到1小时的指标变化再决定继续还是回退。一次同时改多个参数出了问题根本不知道是哪个变量引入的。6. 实操一个简化感知系统构建过程6.1 场景定义——给“客户咨询智能体”列感知需求为了让这部分更有抓手我用一个最常见的“客户咨询智能体”作为例子。第一步我把感知需求列成一个清单确保后续开发不跑偏。感知需求清单感知用户当前会话输入消息文本、是否包含图片感知用户身份登录态中获取无登录则置为匿名感知用户近30天的订单状态包括配送、退款、售后进度感知商品基础信息价格、库存、参数来自业务API感知平台最新公告和政策来自知识库感知当前时间与客服在线状态来自时钟和排班系统这个清单确定了以后我给每项感知需求指定责任模块和数据源避免后面“什么都想做、哪个都没做透”。6.2 核心代码实现——感知事件模型与状态管理下面是这类系统里比较核心的感知数据结构和状态管理的工程示例我用Python写了一个简化版本来说明核心逻辑。重点不在于完整项目代码而在于理解感知层的数据流。from dataclasses import dataclass from datetime import datetime, timedelta from typing import Any, Optional dataclass class PerceptEvent: 感知事件一个最小粒度的感知结果 source: str # 数据源标识如 order_api / user_input event_type: str # 事件类型如 order_status_changed payload: dict # 原始负载如 {order_id: 123, status: shipped} occurred_at: datetime # 事件发生时间 ttl_seconds: int 60 # 事件保鲜期默认60秒 def is_fresh(self, now: datetime None) - bool: now now or datetime.now() return (now - self.occurred_at).total_seconds() self.ttl_seconds class PerceptContext: 感知状态管理器聚合所有感知事件并按优先级供上层消费 def __init__(self): self.events [] # 全部感知事件带时间戳 self.state {} # 压缩后的结构化状态 self.budget 8000 # 上下文预算 def ingest(self, event: PerceptEvent, priority: int 0): 接收一个新感知事件并同步更新状态 if not event.is_fresh(): return # 过期数据直接丢弃 self.events.append(event) # 用事件更新压缩状态这里以订单状态为例 if event.event_type order_status_changed: order_id event.payload[order_id] self.state[forder:{order_id}] { status: event.payload[status], updated_at: event.occurred_at, priority: priority } def expire(self): 清理过期状态防止旧数据影响决策 now datetime.now() expired_keys [] for key, info in self.state.items(): if now - info[updated_at] timedelta(secondsself.ttl()): expired_keys.append(key) for key in expired_keys: del self.state[key] def build_prompt_segment(self): 按优先级组装感知信息片段供Prompt使用 segments [] for key, info in sorted(self.state.items(), keylambda x: -x[1][priority]): segments.append(f{key}: {info[status]}) return \n.join(segments)这段代码虽然精简但已经体现了三个关键点感知事件要带时效性、感知状态的聚合要自动更新覆盖、感知信息在进入Prompt前要按优先级排序。实际工程里这个状态管理器会接Redis做持久化用消息队列异步处理高吞吐事件。6.3 关键配置参数——从实测数据里调出来的经验值做了一个月之后我总结了一些感知层参数的初始推荐值供参考参数推荐初始值调整方向说明知识检索TopK5知识库噪声大时降低需求跨领域时提高上下文总预算8000 token模型窗口大可以提到12000但注意成本事件保鲜期最短5秒最长24小时按数据维度单独设置不要一刀切知识块切分大小500字左右步骤类文档可到200字综述类可到800字相似度召回阈值0.65基于余弦相似度命中率偏低时下调误召回多时上调参数不是为了调而调每一个都对应具体问题。比如TopK从3调到5是因为我发现有些问题第一屏相关的知识块只有1个剩下的Tag模糊所以放宽到5再做重排。改任何参数都要在日志里记录改动前后指标对比这样才知道调得对不对。6.4 构建时的禁忌与边界——感知不是“越多越好”感知系统最大的坑是做成了信息囤积癖能接的数据源都接上能把100个字段都存下来结果决策时模型被无关信息绑住了手脚。我现在的准则是每一项感知数据进入系统前都要回答“如果缺失这条感知智能体是否会明显变笨”这个问题。如果答案是否定的就不应该加。第二个禁忌是忽略敏感信息过滤。用户隐私信息身份证、手机号、地址在感知层就应该脱敏而不是让模型直接读原文。很多业务流程并不需要模型知道完整手机号感知层存一个脱敏版本就够了。第三个禁忌是没有回退机制。感知模块挂了智能体不能完全不可用。我的做法是给感知层加“降级模式”关键感知源连接失败时服务自动降级为只使用当前对话文本和一个简单的历史摘要虽然回答会变弱但至少不会崩溃。可靠性设计在感知层同样重要。7. 常见问题与排查技巧实录7.1 感知层问题速查表做感知系统这段时间我把自己和身边团队遇到的高频问题整理成了速查表排障的时候真的能省不少时间。问题现象可能原因排查步骤解决方案智能体回答与最新状态不符感知信息过期未清理检查感知事件时间戳和保鲜期配置在状态管理中增加过期清理任务模型总是漏掉关键订单信息上下文预算分配不当查看Prompt中订单状态段的长度和位置提高结构化状态段的预算和优先级知识库检索结果不相关知识块切分过大或脏数据抽样检查Top N知识块是否和问题语义对齐重新做文档清洗缩小切分粒度智能体长时间“忘记”用户偏好长期记忆未接入感知检查长期记忆召回是否被触发补充长期记忆的相似度召回逻辑感知延迟导致答案过时接入层使用同步调用监控各感知源的P99延迟高实时数据源改异步或消息队列上下文token超限拼接了过多原始知识块检查Prompt中知识段占比加入裁剪/摘要流程压缩冗余片段用户消息重复表达仍答错感知到了但理解层未消化查看意图识别结果和抽取的结构化字段调优语义理解模型或增加规则兜底敏感信息泄露到模型输出感知层未落实脱敏检查日志中的Prompt原样内容感知层强制脱敏先于入库执行这张表的方向是“问题表面现象→排查命令或日志位置→解决动作”但实际排障时不要按顺序从头看到尾而是根据错误率最高的环节优先定位。先看感知日志再看Prompt组装结果最后才怀疑模型本身——大多数时候问题都出在前两步。7.2 排障过程中几个容易踩的隐性坑先说一个最隐蔽的问题感知状态更新覆盖时没有考虑并发。两个事件同时到达后写覆盖先写结果把新状态写成了旧状态。我们之前用Redis做状态存储时遇到的竞态条件就是在这种交互下被线上用户逼出来的。解决办法很简单所有状态更新通过单线程消费队列串行化或者用乐观锁比较版本号。第二个隐性坑是上下文里信息重复。比如用户订单状态被写进结构化状态段又在历史会话摘要里重复出现模型容易把同一信息当成两次数据来判断导致“既在途中又已签收”这类自相矛盾的回答。这个问题的解法是在组装Prompt前做一次“感知信息去重”用字段名和时间戳做唯一性判断同一条订单只保留最新快照。第三个坑和日志有关感知层日志如果不含事件ID和链路追踪出了问题根本没法回放。我给每个感知事件生成唯一event_id贯穿接入、清洗、组装全链路排障时把event_id一搜全流程一目了然。看起来增加了点工作量但在线上故障时这是唯一的救命稻草。7.3 两个值得长期坚持的调试习惯第一个习惯是每天固定时间做感知日志的抽样检查不要只在出故障时看。我每天随机抽10条线上会话人眼检查感知事件是否完整、状态是否有歧义、上下文组装是否合理。很多隐性质量问题比如某个感知源偶尔超时就是在例行检查里发现的而不是等到用户投诉才暴露。第二个习惯是为感知系统的每个接口做“上报对比”。具体做法在开发环境和线上环境都对同一组测试数据跑一遍对比感知输出是否一致。如果线上结果与开发不一致大概率是数据源版本不同或配置被改动而不是模型代码变化。这种对比能帮你快速定位“开发正常、线上诡异”的玄学问题。结尾做了这么多智能体项目之后我越来越觉得感知系统的设计核心其实是“克制”两个字。它不是把更多信息塞给模型而是把更少但更相关的信息、在最需要的时候递给模型。那种“模型反正能理解喂多点无所谓”的偷懒思路最终都会在上下文漂移和用户不满上付出代价。最后再分享一个小技巧新做一个智能体不要一上来就追求全感知源覆盖。先定义清楚最关键的三到五个感知源跑通最小闭环再根据用户反馈逐步补全感知维度。感知系统有点像装修——硬装阶段多花心思在水电和结构上后面软装怎么调都舒服地基没打好后面贴再多明星模型也没用。希望你构建智能体感知系统的时候少走我踩过的这些坑每一步都踩在实实在在的地基上。