news 2026/9/29 17:58:49

Agent上线就翻车?从工具调用到状态管理的工程化落地指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agent上线就翻车?从工具调用到状态管理的工程化落地指南

1. 为什么你的Agent总是“演示惊艳,上线翻车”

做Agent项目的人,大概率都经历过这种落差:Demo里它像个全能助理,能查资料、能调接口、能多轮追问,甚至还能自己规划任务;可一旦放到真实环境里跑,用户稍微换个说法、多问两轮、或者某个工具返回慢了一点,它就开始胡言乱语、重复调用、忘记目标,甚至直接卡死。表面看是“模型不够聪明”,实际上绝大多数问题根本不在模型本身,而在工具调用、上下文管理、状态流转、评估体系这四个工程环节上。

我过去一年参与过几个Agent项目的落地,从客服工单自动处理到内部知识助手,踩过的坑几乎都能归到同一类:把Agent当成一个“更聪明的聊天机器人”来设计,而不是当成一个“有状态、有边界、有失败恢复能力的执行系统”来设计。这两者的区别,就像你拿一个会背菜谱的人去开餐厅,和真正建一套能出餐、能退单、能补货的后厨系统,完全是两码事。

这篇文章不聊虚的,就围绕一个核心问题展开:Agent项目为什么经常“看起来很聪明,用起来不稳定”?我会从整体设计思路、核心细节、实操落地、问题排查四个层面,把工具调用、上下文、状态管理、评估集这些关键点拆开讲清楚。适合正在做Agent开发、准备做Agent开发,或者已经被Agent稳定性折磨过的朋友。读完你至少能明白:你的Agent到底卡在哪一层,以及怎么用工程手段把它从“玩具”变成“工具”。

2. 整体设计与思路拆解:Agent不是模型,是系统

2.1 先搞清楚:Agent和普通LLM应用的本质区别

普通LLM应用,比如一个问答机器人,它的核心链路很短:用户输入 → 拼提示词 → 模型生成 → 返回结果。整个过程是无状态的,一次请求结束,上下文就丢了。这种模式简单、可控,但能力上限也低,因为它不能主动做事。

Agent不一样。Agent的核心是**“感知-决策-行动-观察”的循环**。它需要根据当前目标,决定下一步做什么,调用什么工具,拿到结果后再判断是否继续。这就引入了一个根本性变化:Agent是有状态的,而且状态会跨多轮、跨多个工具调用持续演化。

我见过很多项目,代码结构上就是把LLM调用包在一个while循环里,然后塞几个工具函数进去,就管这叫Agent。这种写法在Demo阶段能跑通,因为Demo的路径短、输入干净、工具稳定。但真实环境里,用户输入是模糊的,工具返回是多样的,网络是波动的,模型输出是不确定的。四个不确定性叠加,系统必然不稳定。

所以第一个设计原则:把Agent当成一个分布式系统来设计,而不是一个函数调用链。分布式系统的核心问题它都有:状态一致性、超时重试、幂等性、可观测性、失败隔离。你不在这些地方下功夫,模型再强也救不了。

2.2 工具调用:为什么“能调”和“调得稳”是两回事

工具调用是Agent最核心的能力,也是最容易出问题的地方。很多开发者第一次接工具调用时,觉得只要把函数描述写好、参数schema定义清楚,模型就能正确调用。实际跑起来你会发现,问题远不止“调不调得对”。

常见的问题包括:模型在不需要调用工具时强行调用;调用时参数格式错误;同一个工具被连续重复调用;工具返回错误后模型不知道如何处理;多个工具之间的依赖顺序混乱。这些问题背后,其实是工具调用的边界定义和错误处理机制没有设计好。

我的经验是,工具调用要分三层来设计。第一层是工具描述层,也就是给模型看的函数说明。这里的关键不是写得多详细,而是写得多“无歧义”。比如一个查询订单的工具,参数是订单号,你就要明确告诉模型:订单号必须是用户提供的,如果用户没提供,你应该先询问,而不是自己编一个。第二层是调用约束层,在代码层面限制模型的调用行为,比如设置最大调用次数、禁止连续调用同一工具、对参数做前置校验。第三层是结果处理层,工具返回后,不是直接把原始结果丢给模型,而是要先做结构化处理,把错误信息、空结果、超时情况都转成模型能理解的格式。

注意:不要指望模型自己学会“什么时候不该调工具”。这个边界必须由代码来兜底。模型负责决策,代码负责约束。

2.3 上下文管理:不是塞得越多越好,而是留得越准越好

上下文是Agent的“工作记忆”。很多项目不稳定,根源就在上下文管理上。常见做法是把所有历史对话、所有工具返回结果、所有系统提示词一股脑塞进上下文窗口。短期看没问题,因为现在模型上下文窗口越来越大,动辄128K、200K甚至1M。但上下文越长,模型注意力越分散,关键信息越容易被淹没。

我做过一个对比测试:同一个多轮任务,把完整历史塞进去和只保留最近三轮加关键摘要,后者的任务成功率反而更高。原因很简单,模型不是数据库,它不擅长从大量冗余信息里精准提取当前需要的那一条。上下文管理的核心不是“记住所有”,而是“在正确的时间让模型看到正确的信息”。

具体怎么做?我通常分三步。第一步,分层存储:把对话历史、工具调用记录、任务状态分开存,不要混在一起。第二步,动态裁剪:根据当前任务阶段,只把相关的历史片段注入上下文。比如用户正在确认订单信息,那就只注入订单相关的历史,之前的闲聊和无关查询全部裁掉。第三步,关键信息摘要:对长对话做滚动摘要,把已经确认的事实、已达成的共识、未完成的任务用结构化格式保留下来,而不是保留原始对话。

这里有个容易忽略的点:工具返回结果往往很长,但模型真正需要的可能只是其中一两个字段。比如一个天气查询工具返回了完整JSON,模型只需要温度和天气状况。如果你把整个JSON塞进上下文,不仅浪费窗口,还容易让模型在后续推理中被无关字段干扰。所以工具返回后,最好先做一次“信息抽取”,只把关键字段注入上下文。

2.4 状态管理:Agent的“记忆”到底该怎么管

状态管理和上下文管理经常被混为一谈,其实它们是两个层面的事。上下文是给模型看的,状态是给系统用的。状态管理要解决的是:当前任务进行到哪一步了?哪些信息已经确认了?哪些工具已经调用过了?下一步应该做什么?

我见过最典型的翻车场景是:用户在多轮对话中修改了某个条件,比如一开始说“帮我查北京的天气”,后来改口“算了,查上海的”。如果状态管理没做好,Agent可能还在用北京的信息继续执行,或者两个城市的信息混在一起。这就是状态没有正确更新导致的。

我的做法是引入一个显式的任务状态对象,用结构化数据记录当前任务的关键信息。这个对象不直接塞给模型,而是由代码维护,在需要的时候把相关字段转成自然语言注入上下文。比如:

{ "task_id": "weather_query_001", "status": "in_progress", "confirmed_slots": { "city": "上海", "date": "今天" }, "pending_slots": ["需要确认是否要查明天"], "tool_calls": [ {"tool": "weather_api", "params": {"city": "北京"}, "status": "cancelled"}, {"tool": "weather_api", "params": {"city": "上海"}, "status": "success"} ] }

这样做的好处是,状态变更由代码控制,模型只负责在当前状态下做决策,不负责记住所有历史。状态对象还可以持久化,支持断点恢复,这对长任务特别重要。

2.5 评估集:没有评估,你根本不知道Agent哪里不稳

这是最容易被忽视、但最重要的一环。很多团队做Agent,开发阶段靠人工试,上线后靠用户反馈,中间没有系统化的评估。结果就是:你知道它不稳定,但不知道具体哪里不稳、什么条件下不稳、改了一个地方会不会引入新问题。

评估集不是简单的“测试用例”,它要覆盖Agent的完整行为空间。我通常把评估集分成四类:正常路径、边界情况、异常恢复、多轮交互。正常路径就是标准流程,验证基本功能。边界情况包括空输入、超长输入、模糊指代、多意图混合。异常恢复模拟工具超时、工具报错、模型输出格式错误等场景,看Agent能不能正确降级或重试。多轮交互则专门测试状态流转和上下文管理,比如用户中途改需求、连续追问、跨话题切换。

评估指标也不能只看“最终答案对不对”。对于Agent,过程指标往往更重要:工具调用次数是否合理、无效调用占比多少、平均任务完成轮数、异常恢复成功率。这些指标能帮你定位到具体是哪个环节拖了后腿。

提示:评估集要持续迭代。每次线上发现新的失败案例,就把它加进评估集,形成回归测试。没有这个闭环,你的Agent永远在“修一个坏一个”。

3. 核心细节解析与实操要点

3.1 工具调用的参数设计:别让模型猜

工具调用的稳定性,从参数设计就开始了。很多开发者定义工具参数时,习惯用自然语言描述,比如“city: 城市名称”。这看起来没问题,但模型可能会传入“北京市”、“北京”、“Beijing”、“帝都”等各种形式。如果你的工具后端没有做归一化,就会直接报错。

我的做法是:在参数schema里用枚举或正则约束格式,同时在工具描述里明确告诉模型“如果用户没有提供,你应该先询问”。比如:

{ "name": "query_weather", "description": "查询指定城市的天气。如果用户没有明确提供城市名称,不要猜测,先向用户确认。", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名称,必须是中文标准名称,例如:北京、上海、广州" }, "date": { "type": "string", "enum": ["today", "tomorrow"], "description": "查询日期,只支持今天或明天" } }, "required": ["city"] } }

这里的关键是required字段和描述里的约束语句。模型看到required,就知道这个参数不能省;看到“不要猜测,先确认”,就知道缺参数时应该追问而不是编造。

另一个实操要点是工具返回格式的统一。不管底层API返回什么,到了Agent这一层,都应该转成统一的结构:

{ "success": true, "data": {...}, "error": null, "hint": "如果用户问的是温度,直接使用data.temperature字段" }

hint字段很有用,它相当于给模型的“使用说明”,告诉模型这个结果里哪些字段是关键的、怎么用。这能显著减少模型误读返回结果的情况。

3.2 上下文裁剪的实操策略:什么时候裁、裁什么

上下文裁剪不是简单截断,而是有策略地保留和丢弃。我通常按以下优先级来决定保留什么:

优先级内容类型保留策略
最高系统提示词和工具定义始终保留,但可以精简
高当前任务状态摘要始终保留,结构化注入
高最近2-3轮对话完整保留
中已确认的关键事实摘要保留
中最近一次工具调用结果保留关键字段
低早期对话历史摘要或丢弃
低已完成的工具调用详情只保留状态标记

具体操作时,我会在每轮对话结束后做一次“上下文整理”:把新产生的信息分类,更新任务状态对象,然后重新生成下一轮要注入的上下文。这个过程是代码驱动的,不依赖模型自己判断。

还有一个技巧是用“锚点”标记关键信息。比如在上下文里用[已确认]、[待确认]、[已取消]这样的标签,帮助模型快速识别信息状态。这比让模型自己从对话历史里推断要可靠得多。

3.3 状态机的引入:让Agent的执行路径可预测

如果你的Agent任务步骤比较多,强烈建议引入显式状态机。状态机的好处是:每个状态下的可用动作是有限的,模型只需要在有限选项里做选择,而不是自由发挥。这能大幅降低不确定性。

比如一个订单处理Agent,可以定义这些状态:等待用户提供订单号→查询订单→确认订单信息→等待用户选择操作→执行操作→完成。每个状态下,只允许调用特定的工具,只允许输出特定类型的内容。模型的任务变成“在当前状态下选择正确的下一步”,而不是“从零规划整个流程”。

状态机的实现可以用代码硬编码,也可以用配置驱动。我倾向于配置驱动,把状态转移规则写成JSON或YAML,这样调整流程时不用改代码。但要注意,状态机不能太死板,要留出“异常跳转”的口子,比如用户突然问了一个无关问题,Agent应该能暂时跳出主流程,回答完再回来。

3.4 评估集的构建方法:从真实失败中学习

评估集不是拍脑袋想出来的,而是从真实场景中沉淀出来的。我的做法是:项目初期先手动构造20-30个核心用例,覆盖主要功能路径。上线后,每次发现线上失败案例,就把它脱敏后加入评估集。三个月后,评估集自然会长到几百条,覆盖各种边界情况。

评估集的每条用例应该包含:输入(用户消息序列)、预期行为(应该调用什么工具、应该输出什么类型的结果)、判定标准(怎么算通过)。判定标准要尽量自动化,比如工具调用参数是否匹配、最终答案是否包含关键信息。对于难以自动判定的,可以用另一个模型做裁判,但裁判模型也需要定期校准。

注意:评估集要定期跑,最好每次代码变更后都跑一遍。我见过太多团队,改了一个提示词,结果把之前修好的问题又改坏了,就是因为没有回归测试。

4. 实操过程与核心环节实现

4.1 从零搭建一个稳定Agent的最小闭环

假设我们要做一个“会议安排助手”,能查日程、找空闲时间、创建会议。我按上面的思路走一遍完整流程。

第一步:定义任务状态对象。

{ "task_id": "meeting_scheduler_001", "status": "collecting_info", "slots": { "participants": [], "duration": null, "preferred_date": null, "meeting_title": null }, "confirmed": false, "tool_history": [] }

第二步:定义工具集。

[ { "name": "check_calendar", "description": "查询指定人员在指定日期的日程安排。如果日期未提供,默认查询今天。", "parameters": { "person": {"type": "string", "description": "人员姓名"}, "date": {"type": "string", "description": "日期,格式YYYY-MM-DD"} }, "required": ["person"] }, { "name": "create_meeting", "description": "创建会议。只有在所有必填信息都确认后才能调用。", "parameters": { "title": {"type": "string"}, "participants": {"type": "array", "items": {"type": "string"}}, "start_time": {"type": "string"}, "duration_minutes": {"type": "integer"} }, "required": ["title", "participants", "start_time", "duration_minutes"] } ]

第三步:设计主循环。

主循环的逻辑是:读取当前状态 → 根据状态决定注入哪些上下文 → 调用模型 → 解析模型输出 → 如果是工具调用,执行工具并更新状态 → 如果是文本回复,返回给用户 → 循环直到任务完成或需要用户输入。

关键点在于:每次调用模型前,都要重新生成上下文。不是把历史一股脑塞进去,而是根据当前状态,只注入相关字段。比如当前状态是collecting_info,那就注入已收集的slots和缺失的slots,让模型知道还差什么信息。

第四步:处理工具调用结果。

工具返回后,先做结构化处理,提取关键字段,更新状态对象,然后生成一个简短的“观察结果”注入下一轮上下文。比如check_calendar返回了某人今天有三个会议,那注入给模型的就是“张三今天10:00-11:00有会,14:00-15:00有会,其余时间空闲”,而不是原始JSON。

第五步:设置终止条件。

Agent不能无限循环。我通常设置三个终止条件:任务完成、达到最大轮数(比如10轮)、连续两次工具调用失败。达到任一条件就退出循环,返回当前状态给用户。

4.2 参数计算与选择:超时、重试、最大轮数怎么定

这些参数没有标准答案,但可以根据经验给一个起点,然后根据评估结果调整。

参数建议起点调整依据
单次工具调用超时10秒根据工具后端P99延迟调整
工具调用最大重试次数2次幂等工具可重试,非幂等慎用
Agent最大执行轮数10轮根据任务复杂度调整
上下文最大token数模型窗口的60%留出余量给模型输出
连续失败阈值2次连续失败后应降级或转人工

超时设置特别重要。我见过一个项目,工具调用没设超时,结果某个外部API挂了,Agent就一直等,用户那边直接卡死。后来加了10秒超时和2次重试,稳定性立刻上来了。

重试要注意幂等性。查询类工具可以随便重试,但创建订单、发送消息这类操作,重试前必须确认上一次是否真的失败了,否则可能重复创建。我的做法是给每个工具标记idempotent: true/false,非幂等工具的重试要格外谨慎,最好先查询状态再决定。

4.3 实操现场:一次典型的失败恢复过程

说一个真实案例。用户让Agent帮忙“把下周的团队会议改到周五下午”。Agent先查了日历,发现周五下午大家都有空,然后准备创建会议。但创建时工具返回了“时间冲突”错误,因为会议室被占了。

如果没做错误处理,Agent可能直接把错误信息丢给用户,或者反复重试创建。我的处理方式是:在工具返回错误后,先解析错误类型。如果是“时间冲突”,就自动触发一个“查找替代时间”的子流程,查一下周五其他时间段或者下周一是否有空,然后把选项呈现给用户。

这个过程在状态机里体现为:creating_meeting状态收到冲突错误 → 转移到finding_alternative状态 → 调用check_calendar查找替代时间 → 转移到presenting_options状态 → 输出选项给用户。

整个恢复过程不需要用户重新描述需求,Agent自己完成了降级和补偿。这就是状态管理和错误处理的价值。

4.4 评估集的实际运行:怎么跑、怎么看结果

评估集跑起来很简单,写一个脚本,遍历所有用例,对每个用例模拟用户输入序列,记录Agent的实际行为,然后和预期行为对比。输出一份报告,包含通过率、失败用例详情、关键指标统计。

我通常关注这几个指标:

  • 任务完成率:最终是否完成了用户目标
  • 工具调用准确率:调用的工具和参数是否正确
  • 无效调用率:有多少次工具调用是不必要的或重复的
  • 平均轮数:完成任务平均需要几轮交互
  • 异常恢复率:遇到工具错误时成功恢复的比例

这些指标比单纯的“回答对不对”更能反映Agent的健康状况。比如无效调用率高,说明工具描述或上下文有问题;异常恢复率低,说明错误处理逻辑不完善。

5. 常见问题与排查技巧实录

5.1 工具调用类问题速查

问题现象可能原因排查方法解决思路
模型不调用工具,直接回答工具描述不清晰,或模型不知道何时该调检查工具描述是否说明了触发条件在描述里明确“当用户询问X时,必须调用此工具”
调用参数格式错误参数schema约束不够查看模型实际传入的参数增加枚举、正则、示例
重复调用同一工具上下文里没有标记已调用检查工具调用历史是否注入在上下文里加“已调用”标记
工具报错后模型不知所措错误信息没有结构化查看错误返回格式统一错误格式,加hint字段
多工具依赖顺序混乱缺少状态机约束检查是否允许自由选择工具引入状态机,限制每步可用工具

5.2 上下文类问题速查

问题现象可能原因排查方法解决思路
模型忘记之前确认的信息上下文裁剪过度检查任务状态是否注入把已确认事实结构化注入
模型被无关历史干扰上下文塞了太多无关内容检查注入的历史范围按相关性动态裁剪
长对话后模型开始胡言乱语上下文超长,注意力分散检查token数做滚动摘要,控制长度
工具返回结果被误读原始结果太复杂检查注入的返回内容先抽取关键字段再注入

5.3 状态管理类问题速查

问题现象可能原因排查方法解决思路
用户改需求后Agent还用旧信息状态没有更新检查状态更新逻辑每次用户输入后重新解析并更新slots
任务卡住不推进状态机没有出口检查状态转移条件增加超时和降级路径
多轮后状态混乱状态对象没有持久化检查状态存储持久化状态,支持恢复
并发任务互相干扰状态没有隔离检查task_id隔离每个任务独立状态对象

5.4 独家避坑技巧

技巧一:给模型“思考空间”,但不要让它“自由发挥”。在提示词里加一个“当前状态”区块,明确告诉模型现在处于哪个阶段、已有哪些信息、还缺什么。这比让模型自己从历史里推断要可靠得多。

技巧二:工具返回结果里加一个“建议下一步”字段。比如查询日历后,返回结果里加一句“如果用户想创建会议,请调用create_meeting工具”。这相当于给模型一个轻量级的引导,能显著减少模型在下一步决策时的犹豫和错误。

技巧三:用“影子模式”上线。新Agent上线前,先让它和人工并行跑一段时间。人工处理真实请求,Agent在后台也处理同样的请求,但不直接回复用户。对比两者的结果,找出Agent的失败模式。这比直接上线然后被用户骂要稳妥得多。

技巧四:评估集里一定要有“对抗样本”。比如用户故意说反话、故意提供矛盾信息、故意在任务中途切换话题。这些在真实场景里很常见,但开发时容易忽略。我通常会专门构造一批这样的用例,专门测试Agent的鲁棒性。

技巧五:日志要记录“决策依据”。每次模型调用,除了记录输入输出,还要记录当前状态、注入的上下文摘要、模型选择的工具和参数。这样出问题时,你能快速定位是上下文问题、状态问题还是模型本身的问题。没有这些日志,排查基本靠猜。

5.5 一个容易被忽视的细节:工具调用的“副作用”管理

有些工具是有副作用的,比如创建会议、发送邮件、修改数据。这类工具一旦调用成功,就不能简单重试。我的做法是:对有副作用的工具,调用前先记录“意图”,调用后记录“结果”,中间状态标记为“进行中”。如果调用超时或失败,先查询实际状态,确认是否已经生效,再决定是否重试。

这个逻辑在状态对象里体现为:

{ "tool_calls": [ { "tool": "create_meeting", "params": {...}, "status": "in_progress", "intent_id": "intent_001", "result": null } ] }

调用成功后更新为success,失败后更新为failed,超时后标记为unknown并触发状态查询。这样即使系统崩溃重启,也能根据状态对象恢复执行,不会重复创建会议。

6. 把Agent从“聪明”做到“可靠”的关键认知

做Agent项目,最怕的就是把“模型能力”当成“系统能力”。模型再强,它也只是一个组件,不能替代工程上的状态管理、错误处理、边界约束和评估体系。我见过太多项目,提示词写得天花乱坠,工具接了几十个,但一上真实环境就崩,根本原因就是工程底座没打好。

如果你正在做Agent,或者准备做,我的建议是:先把状态管理和评估集做起来,再考虑加更多工具和更复杂的规划能力。状态管理决定了Agent能不能“记住自己在干什么”,评估集决定了你能不能“知道它哪里不行”。这两个东西没有,后面加什么都是空中楼阁。

另外,不要追求“全自动”。很多场景下,Agent只需要做“辅助决策”而不是“完全替代”。比如让它整理信息、给出建议、执行确认后的操作,而不是让它从头到尾自己跑。人机协作的模式,往往比全自动更稳定、更实用。

最后分享一个我自己的习惯:每次Agent出问题,我都会问自己三个问题——是上下文没给对?是状态没更新?还是工具边界没定义好?这三个问题能覆盖80%以上的稳定性问题。剩下的20%,才轮到模型本身。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 17:57:45

Spring Authorization Server替代Spring Security OAuth2实战指南

1. 为什么必须放弃Spring Security OAuth2,转向Spring Authorization Server?去年底我接手一个金融类SaaS平台的权限体系重构任务,原系统用的是Spring Security OAuth2(即spring-security-oauth2,也就是大家常说的“老…

作者头像 李华
网站建设 2026/9/29 17:57:34

基于Matlab的IEEE 33节点配电网分布式电源接入影响分析

做配电网仿真的人,大概率都绕不过一个问题:分布式电源(光伏、风电、小水电)接入之后,原来的辐射状无源网络变成了多电源的有源网络,电压分布、网损、保护配合全都变了。今天就用Matlab把这件事从头到尾做一…

作者头像 李华
网站建设 2026/9/29 17:57:32

天文后期必备:StarNet星点分离实战教程与StarNet++使用技巧

如果你搜 starnet 这个词,八成和我当初一样,是在处理银河照片时被密密麻麻的星点搞得头大。拍的时候星点是画面里的钻石,可一旦进入后期,它们瞬间变成麻烦:银河核心的暗尘埃被星点糊成一片,拉伸之后星点边缘…

作者头像 李华
网站建设 2026/9/29 17:57:24

防火墙双机热备与VRRP详解:华为华三配置与排查实战

干网络这一行,最怕深夜接到电话说“全公司上不了网了”。赶到机房一看,防火墙上电源灯不亮,那一刻你就知道,之前做的冗余设计全都白搭了。防火墙作为全网流量的必经网关,它挂了,路由、NAT、安全策略全部失效…

作者头像 李华
网站建设 2026/9/29 17:56:24

基于机器学习的入侵检测系统实战:从NSL-KDD到多算法对比与线上推理

简介:这是一份面向网络安全初学者与机器学习实践者的入侵检测系统实战资料,围绕Python与ML算法构建IDS展开,适合想将分类模型落地到安全场景的开发者参考。压缩包共3个文件,含1个csv数据集、1个py脚本和1个md说明文档,…

作者头像 李华
网站建设 2026/9/29 17:56:22

混合检索实战:BM25+向量召回+RRF融合搭建企业问答系统

在企业级智能问答系统的落地过程中,有一个几乎绕不过去的坎:检索效果差。你可能遇到过这样的场景——用户问“我的订单为啥没发货”,关键词检索(BM25)只能匹配“订单”“发货”,把一篇讲“售后流程”的知识…

作者头像 李华