当前位置: 首页 > news >正文

AI智能体架构优化:将LLM移出检索路径,提升性能与降低成本

1. 项目概述:从狂热到反思的架构抉择

最近和几个做AI应用的朋友聊天,发现一个挺有意思的现象:大家好像都默认把大语言模型(LLM)塞进了智能体(Agent)的记忆检索路径里。无论是做客服机器人、代码助手还是个人知识库,架构图里总少不了“用户提问 → 向量化 → LLM理解并检索 → 返回答案”这个经典流程。半年前,我也是这个模式的坚定拥护者,觉得用LLM来理解用户意图、重写查询语句、甚至直接生成检索结果,简直是天衣无缝的设计。但经过几个真实项目的迭代和线上流量的考验,我彻底改变了这个想法,并且决定在未来的所有Agent架构中,将LLM从核心的记忆检索路径中移除。这不是一个轻率的决定,背后是实实在在的延迟飙升、成本失控和稳定性噩梦换来的教训。如果你正在设计或优化一个依赖记忆(无论是向量数据库、图数据库还是传统SQL)的AI智能体,那么我踩过的这些坑,或许能帮你省下不少研发资源和云服务账单。

简单来说,这个“停止”动作的核心是:将LLM从“检索”这个需要高确定性、低延迟、高并发的关键路径中剥离,转而将其定位为“检索后”的加工、润色、决策与交互层。记忆检索本身,应该由更轻量、更稳定、更廉价的技术组件来承担。这听起来像是一种退步,仿佛放弃了LLM的“智能”,但实际运行下来,整个系统的综合表现——包括用户体验、技术指标和商业成本——都得到了质的提升。接下来,我就从设计思路、实操细节、问题排查和最终方案这几个层面,详细拆解我为什么这么做,以及具体是怎么做的。

2. 核心架构思路的演变与权衡

2.1 初始方案:LLM作为“智能检索大脑”的诱惑

最初的设计非常直观,也符合当时的技术潮流。我们构建了一个多轮对话智能体,它需要根据对话历史(记忆)和知识库来回答问题。架构流程如下:

  1. 用户输入:用户提出一个问题,例如“我们公司去年Q3在华东区的销售政策是什么?”
  2. 历史记忆加载:系统从对话记录中加载最近几轮的历史(作为上下文)。
  3. 查询理解与重写(LLM介入):将用户原始问题+历史上下文,发送给LLM(如GPT-4),指令是:“请根据对话历史,将用户问题转化为一个更适合知识库检索的查询语句。可能需要补充隐含信息、纠正指代、明确时间范围。”
  4. 向量化检索:将LLM生成的“优化后查询”进行向量化,然后在向量数据库(如Pinecone, Weaviate)中进行相似性搜索,获取Top K个相关片段。
  5. 答案生成(LLM再次介入):将检索到的相关片段、历史上下文和原始问题,再次发送给LLM,指令是:“请根据提供的资料,生成一个准确、友好的回答。”
  6. 返回与记忆存储:将LLM生成的答案返回给用户,并将本轮Q&A存入对话历史。

这个设计的初衷很美:让最聪明的LLM去理解用户复杂的、口语化的、有上下文依赖的意图,生成一个“标准”的检索查询,从而提升检索的准确性。理论上,这能解决“用户问法”和“知识库存储表述”之间的语义鸿沟。在Demo和小流量测试中,效果也确实不错,显得很“智能”。

2.2 理想与现实的裂痕:三大核心痛点

当系统进入灰度测试和正式上线,面对真实、复杂的用户流量时,问题接踵而至:

痛点一:延迟的不可控与用户体验的崩塌这是最直观的打击。一次用户请求,需要串行调用两次LLM API(查询重写和答案生成)。即使每次LLM调用只有2-3秒,加上网络延迟、检索时间,整个链路轻松突破5-8秒。在对话场景中,这是用户无法忍受的。更糟糕的是,LLM API的响应时间存在长尾效应,偶尔一次10秒以上的响应就会导致请求超时,用户看到的是“服务无响应”。我们尝试了各种优化:流式输出、设置更严格的超时、使用更快的模型(如从GPT-4切到GPT-3.5-Turbo),但治标不治本。LLM作为检索路径的一部分,直接成为了系统延迟的瓶颈和最不稳定的一环。

痛点二:成本的无底洞与商业模型的压力成本以惊人的速度攀升。每一次用户交互,无论问题简单或复杂,都需要为“查询重写”这个步骤支付LLM API的费用。假设使用GPT-3.5-Turbo,一次查询重写消耗约500 tokens,每天1万次请求,仅这一项成本就非常可观。而很多简单的、明确的查询(例如“帮我查一下订单号12345的状态”),根本不需要LLM来重写,一个简单的规则或关键词提取就能搞定。让LLM去处理所有请求,就像用高精度数控机床去切水果,不仅浪费,而且慢。在检索路径中使用LLM,使得系统的边际成本始终居高不下,严重影响了商业模式的可持续性。

痛点三:稳定性的“阿喀琉斯之踵”LLM服务的稳定性不完全可控。提供商可能限流、可能宕机、可能更新模型导致输出格式变化。当LLM成为检索的必经之路,它的任何不稳定都会直接导致整个智能体服务瘫痪。我们经历过因为LLM服务商临时维护,导致所有用户问题都无法检索的窘境。此外,LLM的“创造性”在检索场景成了双刃剑。它有时会过度“理解”,将简单的查询改写得面目全非,甚至引入错误的前提假设,导致检索结果完全偏离主题。这种不确定性,对于要求高准确性的知识问答来说是致命的。

注意:这里说的稳定性,不仅仅是服务可用性,更包括输出行为的确定性。检索需要的是“精确命中”,而LLM的本质是“概率生成”,这两者在根本上是存在矛盾的。

2.3 思路转变:解耦“检索”与“理解”

基于上述痛点,我的架构思路发生了根本转变:将“记忆检索”视为一个需要高吞吐、低延迟、高确定性的基础设施,而将“语义理解与交互”视为其上的智能增强层。两者应该解耦,而非耦合。

  • 检索层(Retrieval Layer):职责是快速、准确、廉价地根据输入找到最相关的记忆片段。它应该轻量、稳定、可预测。输入是什么,就应该尽最大可能找到与之匹配的内容。这一层应避免使用LLM。
  • 理解与交互层(Reasoning & Interaction Layer):职责是处理检索到的信息。包括:对多个检索结果进行综合、去重、排序;判断检索结果是否充分,是否需要发起新的、更精确的检索(即“思考-行动”循环);将原始信息组织成自然、友好的语言回复给用户。这一层是LLM的主场。

这个转变的核心在于:不再要求LLM去“猜”用户想要什么然后帮ta检索,而是让一个更可靠的检索系统先把可能相关的东西都找出来,再让LLM这个“聪明的大脑”来判断哪些有用、并组织答案。这样,检索的失败不会导致整个流程崩溃(LLM还可以基于检索失败这一事实进行回复,如“我暂时没找到相关信息,您可以尝试这样问…”),而LLM的波动也不会阻塞检索。

3. 新架构的核心细节与实操要点

3.1 轻量级检索引擎的选型与优化

移除了LLM,检索路径的核心就变成了一个高效的“召回器”。我们的目标是:用最低的成本和延迟,实现尽可能高的召回率(Recall)。精确度(Precision)可以稍后由LLM来筛选。

1. 双路召回策略(Hybrid Search)这是提升召回效果的关键。我们不再单纯依赖向量语义搜索。

  • 向量检索路:用于处理语义相似性。使用开源的嵌入模型(如BAAI/bge-small-zh-v1.5thenlper/gte-base),在本地进行向量化,然后查询向量数据库(如Chroma, Qdrant)。这一步解决“不同说法,相同意思”的问题。
  • 关键词检索路:用于处理精确匹配和关键词权重。使用经过优化的全文检索引擎(如Elasticsearch, Meilisearch)或轻量级库(如Whoosh)。对用户查询进行分词、去除停用词、计算TF-IDF等。这一步解决“特定术语、编号、名称”的精确查找问题。

两路检索结果并行获取,然后进行融合(Fusion)。常用的融合算法有:

  • 加权分数融合:给向量检索和关键词检索的结果分别赋予权重,计算综合分。
  • RRF(Reciprocal Rank Fusion):不依赖绝对分数,只根据各自结果列表中的排名进行融合,对异构检索系统更鲁棒。 我们实测下来,RRF的效果更稳定,避免了不同检索系统分数尺度不一致的问题。

2. 查询预处理管道(Query Pre-processing Pipeline)这是替代LLM进行查询重写的轻量级方案。一个典型的管道包括:

  • 标准化:转小写、去除特殊字符、统一标点。
  • 拼写纠正:使用轻量级库(如pyspellchecker)处理明显的拼写错误。
  • 实体识别与扩展:使用本地NER模型(如spaCy)识别出人名、地名、产品名等实体。对于产品名、内部术语,可以配置同义词词典进行扩展。例如,用户输入“苹果手机”,可以扩展为“iPhone, Apple iPhone”。
  • 意图分类(可选但推荐):训练一个简单的文本分类模型(如FastText或小型的BERT),将查询分为“事实查询”、“操作指令”、“闲聊”、“多轮澄清”等类别。不同类别的查询可以触发不同的检索策略和后处理逻辑。

这个预处理管道全部在本地运行,延迟在毫秒级,成本几乎为零,却能解决大部分简单的查询优化问题。

3. 向量模型与数据库的优化

  • 模型选型:放弃追求顶级效果的大型嵌入模型(如OpenAI的text-embedding-3-large),转而使用效果足够好、速度更快的开源小模型。对于中文场景,BAAI/bge-small-zh系列是很好的平衡点。将其部署在本地GPU甚至CPU上,消除网络延迟。
  • 索引优化:对于向量数据库,选择合适的索引类型(如HNSW)和参数(ef_construction,M)。在召回率和查询速度之间取得平衡。定期对索引进行重建,以纳入新数据并优化性能。
  • 分片与过滤:根据业务逻辑,对记忆数据进行分片(例如按部门、按时间)。检索时先根据用户上下文或元数据过滤到特定分片,再执行搜索,能极大减少搜索空间,提升速度和准确度。

3.2 LLM在新架构中的精准定位

在新的架构中,LLM被移到了检索路径之后,其角色更加清晰和强大:

1. 检索后处理器(Post-Retriever)LLM接收的是“检索系统返回的、可能相关的原始材料列表”。它的任务包括:

  • 相关性精排:判断每个检索片段与用户问题的真实相关性,过滤掉误召回的结果。
  • 信息综合:从多个相关片段中提取、总结、去重,合成一个连贯的信息体。
  • 答案生成:基于合成后的信息,生成最终的自然语言回答。这是LLM最擅长的工作。

2. 检索决策器(Retrieval-Decision Maker)这是实现“智能”的关键。LLM可以分析当前检索结果的质量,并决定下一步行动,形成一个闭环:

  • 判断充分性:“当前检索到的信息足够回答用户问题吗?”
  • 决定是否重试:如果不够,LLM可以分析原因,并生成一个新的、更精确的查询语句,触发系统进行第二轮检索。注意,这个新查询是给轻量级检索引擎的,而不是LLM自己再去检索。例如,LLM可能判断“需要更近期的信息”,从而在新查询中加上“2024年”这个过滤器。
  • 多跳查询:对于复杂问题,LLM可以规划多步检索。例如,先检索“公司A的主要产品”,得到产品名“X1”,再自动以“X1的技术白皮书”为查询进行第二次检索。

3. 交互与安全层

  • 处理无结果:当检索系统返回空或极低相关性结果时,LLM可以生成得体的回应,引导用户提供更多信息或换种问法,而不是直接报错。
  • 内容安全与合规检查:LLM可以在最终答案生成前,检查其是否包含不安全、不恰当或与检索源矛盾的内容。
  • 多模态整合:如果答案需要结合文本、数据图表,LLM可以规划调用相应的工具(如绘图API、数据查询API)。

这种定位下,LLM的调用不再是每次交互的“必选项”。对于非常简单的、答案明确的查询,系统甚至可以通过规则模板直接组装答案,完全绕过LLM,实现极速响应。

3.3 系统流程与数据流设计

以下是新的、去LLM化的核心检索路径的详细数据流:

  1. 接收请求:系统接收用户查询Q和会话上下文C。
  2. 轻量预处理
    • 对Q进行标准化、拼写纠正。
    • 运行NER识别实体,并通过同义词库扩展。
    • 使用轻量级意图分类模型对Q进行分类。
  3. 生成检索查询:根据意图分类结果,选择策略生成检索查询。
    • 事实查询:将预处理后的Q直接用于双路检索。
    • 操作指令(如“订一张票”):可能触发工具调用,不进入记忆检索流。
    • 多轮澄清:从上下文C中提取上一轮的关键信息,合并到当前查询Q中。
  4. 并行双路检索
    • 路径A(语义):用本地嵌入模型将查询向量化,在向量库中进行近似最近邻搜索。
    • 路径B(关键词):将查询分词,在全文检索引擎中进行搜索。
    • (可选)路径C(元数据过滤):根据实体识别结果(如时间、人物),对检索范围进行过滤。
  5. 结果融合与粗排:使用RRF等方法,融合A、B两路的结果,得到Top N(例如N=10)的候选记忆片段列表[Doc1, Doc2, ...]及其原始分数、来源。
  6. 交付LLM进行精加工:将用户原始问题Q、上下文C以及候选片段列表[Doc1, Doc2, ...],一同发送给LLM。Prompt设计如下:
    你是一个专业的助手。请基于以下用户问题和参考资料,生成回答。 用户问题:{Q} 对话历史:{C} 参考资料列表: [1] 内容:{Doc1.content} (相关性分数:{Doc1.score}) [2] 内容:{Doc2.content} (相关性分数:{Doc2.score}) ... 请遵循以下步骤: 1. 判断每个参考资料与用户问题的相关性。忽略那些明显不相关的。 2. 从所有相关参考资料中,提取、整合关键信息。 3. 如果现有资料不足以回答问题,请明确指出缺少什么信息。 4. 基于整合后的信息,生成一个准确、清晰、完整的回答。 回答:
  7. LLM决策与行动(可选):如果LLM在步骤6中判断信息不足,它可以生成一个“思考过程”,其中包含一个新的、更精确的检索查询(NewQuery)。系统捕获这个NewQuery,跳回第4步,执行新一轮检索,然后将新旧结果一起再次提交给LLM。
  8. 返回最终答案:将LLM生成的结果返回给用户,并将本轮交互存入记忆库。

4. 性能对比与问题排查实录

4.1 量化指标对比:新旧架构的差异

我们在一个内部知识库问答系统上,对两种架构进行了为期一周的A/B测试(各50%流量)。核心指标对比如下:

指标旧架构 (LLM在检索路径中)新架构 (LLM在检索路径后)提升/变化
平均响应时间 (P50)4200 ms950 ms降低77%
长尾延迟 (P95)12500 ms2100 ms降低83%
单次请求成本 (估算)0.012 USD0.004 USD降低67%
检索召回率 (Recall@5)88%85%轻微下降3%
答案准确率 (人工评估)91%94%提升3%
服务可用性99.2%99.95%显著提升

结果分析:

  • 延迟与成本:提升是颠覆性的。这主要归功于移除了串行的、高延迟高成本的LLM调用(查询重写),并用本地化、并行的轻量级组件替代。
  • 召回率:新架构的召回率略有下降,这在意料之中。因为LLM的查询重写有时确实能神奇地匹配到一些边缘case。但这个差距远比我们想象的小,通过优化本地预处理管道和双路检索,我们几乎追平了LLM的效果。
  • 答案准确率不降反升!这是最关键的发现。旧架构中,LLM在检索前重写查询,一旦重写出现偏差,后续检索就是“垃圾进,垃圾出”,且难以纠正。新架构中,LLM在检索后工作,它能看到更全面的原始材料,并行使“裁判”和“编辑”的职责,过滤错误信息,综合多源信息,从而生成更可靠的答案。

4.2 典型问题排查与解决技巧

在架构迁移和优化过程中,我们遇到了不少具体问题,以下是其中三个典型的排查案例:

问题一:关键词检索路召回大量无关结果,拉低了整体精度。

  • 现象:用户问“如何报销差旅费”,关键词检索路返回了大量包含“报销”、“费”但内容是关于“采购费”、“软件费”的文档。
  • 排查:分析发现,中文分词器将“差旅费”切分成了“差旅”和“费”,而“费”这个词的TF-IDF权重在全局很高,导致很多包含“费”的文档被召回。
  • 解决
    1. 自定义词典:将“差旅费”、“iPhone 15”等业务核心复合词加入分词器的自定义词典,确保其作为一个整体被识别。
    2. 提升字段权重:在全文检索中,对文档的“标题”、“摘要”字段赋予比“正文”更高的权重。
    3. 使用BM25算法调参:调整BM25中的k1b参数,控制词频和文档长度归一化的影响,使其更适合短查询。
    4. 查询时Boosting:在构建查询时,对识别出的实体词(如“差旅费”)给予更高的权重。

问题二:向量检索路对特定领域术语不敏感。

  • 现象:内部项目代号“阿波罗计划”,在向量空间中与通用的“阿波罗”或“计划”语义接近,导致误召回。
  • 解决
    1. 领域微调嵌入模型:收集一批公司内部的问答对、文档,对开源的嵌入模型(如BGE)进行轻量级的继续预训练(Continue Pre-training)或对比学习微调,让模型更好地理解内部术语的语义。
    2. 混合检索的权重调整:对于这类专有名词,在融合策略中,提高关键词检索路的权重。因为专有名词的精确匹配比语义相似更重要。
    3. 元数据辅助:为文档添加“项目名称”等元数据字段。检索时,先通过NER识别出“阿波罗计划”作为实体,然后将其作为过滤条件,只检索project_name包含“阿波罗计划”的文档,再在这些文档中进行语义搜索。

问题三:LLM作为后处理器时,有时会“虚构”答案,忽略提供的参考资料。

  • 现象:即使检索到了正确答案的片段,LLM生成的回答中仍包含一些资料中不存在的信息。
  • 排查:这是LLM的“幻觉”问题。在Prompt设计上,我们虽然提供了参考资料,但指令不够强硬,LLM还是会依赖自己的知识。
  • 解决
    1. 强化Prompt指令:在Prompt中明确且强硬地要求“你的回答必须严格且仅基于提供的参考资料。如果资料中没有相关信息,请直接说‘根据现有资料,无法回答该问题’,不要自行编造任何信息。
    2. 引用溯源:要求LLM在回答中的每一句关键陈述后,注明引用的资料编号(如[1])。这不仅能遏制幻觉,还能增加答案的可信度。我们在后端可以解析这些引用,并做验证。
    3. 设置低“温度”参数:将LLM API调用时的temperature参数设为0或接近0(如0.1),减少生成的随机性。
    4. 后处理校验:开发一个简单的校验模块,将LLM生成的答案中的关键事实(如日期、数字、名称)与检索到的原文进行快速匹配,如果匹配度过低,则触发警告或重生成。

5. 总结与个人实践心得

将LLM移出Agent的记忆检索路径,不是一个关于“LLM强不强”的争论,而是一个关于“如何正确使用工具”的架构哲学。LLM是强大的生成式大脑,但它昂贵、缓慢且有一定不确定性。检索系统是高效的记忆提取器,它需要稳定、快速和确定。让两者各司其职,在清晰的边界下协同工作,才能构建出既智能又健壮的应用。

我个人最大的体会是,在AI应用架构中,“解耦”和“边界划分”比“堆砌智能”更重要。初期,我们总想用最强大的模型去解决所有问题,但这往往会导致系统脆弱且昂贵。一个稳健的架构,应该像一台精密的机器,每个部件都有明确的职责和性能指标:检索部件追求速度和召回率,理解部件追求深度和准确性,它们通过定义良好的接口(如检索结果列表、格式化Prompt)进行通信。

对于正准备构建类似系统的朋友,我的建议是:从一开始就设计一个没有LLM参与的、独立的检索核心。先把这个核心的召回率和速度优化到极致。然后,再将LLM作为一个“增强插件”接入,让它来处理检索核心之上的、需要真正智能的任务,比如信息整合、逻辑推理、多轮决策和人性化交互。这样,你的系统基础才是牢固的,也更容易在未来替换或升级其中的任何一个部件,无论是检索模型还是LLM本身。

最后,这个选择也让我们团队更加关注数据本身的质量。当检索不再依赖LLM的“魔法”来弥补缺陷时,我们就必须下功夫去优化知识库的结构、文档的清洗和索引的构建。这反过来又进一步提升了整个系统的最终效果。技术决策往往就是这样,退一步,反而能海阔天空。

http://www.jsqmd.com/news/895096/

相关文章:

  • 用Python和Keras从零搭建CNN:一个医学影像识别课程设计的踩坑与调优实录
  • Anthropic的“部署即收购”:企业AI如何通过私募股权网络实现指数级增长
  • 商品详情接口高并发架构:独立资源池与并发控制实战
  • 从‘free’命令看Linux内存管理:你的服务器内存真的‘不够用’吗?
  • 智能语音识别与多语言实时同传方案:从语音转文字到跨语言实时沟通
  • 手机信号栏突然冒出个5GA,这到底是什么谜之黑话?
  • Windows 10/11 用户福音:手把手教你用注册表让OneDrive选择性同步(避开那些烦人的临时文件)
  • 保姆级教程:用DPABI和Matlab给脑图做‘分区体检’,提取AAL90模板特征
  • 【应用程序】基于 Spring Boot + Spring AI的虚拟宠物Web 应用(二)
  • Spark SQL 窗口函数完整技术文档
  • 传统喷绘还在跟“色差”较劲,会被替代吗
  • 智能体安全授权新范式:便携式作用域令牌设计与实现
  • 字节AI布局
  • wsl2+ubuntu22.04配置docker代理
  • 保姆级教程:用CUDA 12.x的异步流和事件,手把手优化你的PyTorch数据预处理流水线
  • Django 从 0 到 1 打造完整电商平台:商品缓存优化(Redis)
  • 智能体评估误区:为何Token消耗不是衡量AI工作价值的关键指标
  • 内网环境RPA自动化实践:自定义API与离线运行方案
  • 48小时基于Google Cloud构建多智能体AI系统:架构、实现与优化
  • 领域特定AI聊天机器人架构设计:从通用模型到专属专家的构建指南
  • 单片机+RA8889 | RUI Builder 可视化 UI 工具 + 自研多国语言显示方案
  • 保姆级教程:在AMD Ryzen电脑上用VMware 16.2.5搞定macOS Monterey (12.x) 虚拟机
  • 纯视觉GUI智能体Mano-P:OSWorld榜首开源项目解析与实践
  • 八年Java老兵,三个月投了上百份简历没找到下家——2026年的招聘市场到底怎么了?
  • Seatable 4.3 数据迁移翻车实录:从Ubuntu到CentOS,我踩了哪些坑?
  • 如何搭建第一个AI智能体?零代码Coze完整教程
  • 从74LS283到Verilog:手把手教你用硬件描述语言‘复刻’经典BCD加法器(附完整代码与Testbench)
  • springboot - jar包启动指定具体的jdk执行
  • 构建语音控制AI智能体:从LLM意图解析到安全文件操作的实战指南
  • AI代理循环成本优化:Lumin本地代理层实现请求瘦身与缓存压缩