ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Spring AI 2.0 进阶入门:Badcase、Eval 与大模型应用效果优化

Spring AI 2.0 进阶入门:Badcase、Eval 与大模型应用效果优化 前面的 Agent 已经具备 Memory、RAG、Tool、MCP、Workflow 和 Task State。系统能力越来越丰富以后会出现一个更加实际的问题模型回答错了到底应该修改 Prompt、优化 RAG、调整 Tool还是直接去微调模型大模型应用由多个环节共同产生最终结果。一个错误回答只能说明最终结果出了问题【结果导向】无法直接说明模型本身能力不足。因此效果优化的第一步通常是定位错误发生在哪一层。一、先判断问题发生在哪一层一个典型 Agent 可以简化为用户问题 ↓ Prompt / Context / Memory ↓ RAG ↓ LLM ↓ Tool / Workflow ↓ 业务系统 ↓ 最终结果不同错误需要完全不同的解决方法。例如模型不知道企业内部退款政策首先应该补充 RAG知识库存在正确政策但检索到了旧文件需要优化切片、Embedding、混合检索、Metadata Filter 或 Rerank正确资料已经进入 Context模型依然遗漏关键要求则需要检查 Prompt、Few-shot、上下文组织和 Structured Output。如果问题需要查询库存、读取数据库、获取当前用户状态或者执行退款这已经属于外部真实状态和业务动作应当使用 Tool Calling 或 Workflow。因此大模型应用优化可以先形成一条顺序知识不足 → RAG 检索不准 → Retrieval 优化 正确知识已经拿到但使用不好 → Prompt / Context / Structured Output 需要真实数据或执行动作 → Tool / Workflow 偶发错误仍然很多 → Badcase / Eval / 回归测试 / Observability 长期存在稳定能力缺陷 → SFT / LoRA 成本、延迟、模型体积成为主要问题 → 量化 / 蒸馏 / 专用小模型这条顺序很重要因为越往后开发成本和数据要求通常越高。二、什么是大模型应用中的“偶发错误”传统代码面对同样的输入和状态通常会进入确定的执行路径。LLM 属于概率性模型同一个应用可能在绝大多数情况下运行正常却在某些输入、上下文组合、检索结果或者采样过程中突然产生错误。例如客服 Agent 测试 100 个问题其中 95 个正常另外 5 个出现答非所问 遗漏退款条件 引用旧政策 调用错误 Tool Tool 参数提取错误 正确检索到资料后仍然理解错误这种问题很容易产生一个误区发现一个错误以后立即修改 Prompt。单独修改某一句 Prompt 后当前案例可能正常了但无法回答两个更重要的问题这个问题真的稳定解决了吗 修改以后会不会让原来正常的问题出错【偶发错误如果只修改prompt会对未来用户产生负担让用户也遇到错误然后修改么不会的所以要稳定解决该问题并且保证不会产生新问题】因此偶发错误越来越多时开发方式需要从“手工试 Prompt”进入工程化测试。三、Badcase把错误变成测试资产Badcase 就是经过确认的失败案例。例如输入 “购买7天后还能无理由退款吗” 期望 根据最新退款政策判断并指出适用条件。 实际结果 模型引用了已经失效的旧政策。【极为重要】一个有价值的 Badcase 最好保存用户输入 当时的上下文 检索到的文档 Tool Call 与结果 模型最终回答 期望结果 错误类型这样以后才能判断错误究竟发生在 Retrieval、Prompt、Tool 还是模型推理阶段。随着系统运行Badcase 会逐渐形成一套真实测试集。这些案例通常比随意编写几十个测试问题更有价值因为它们来自系统实际暴露过的问题。四、Eval给大模型应用建立“考试”有了 Badcase还需要定义怎样判断模型回答是否合格【考试】这就是 Eval。例如一个 RAG 问答可以评价是否回答了用户问题 是否与检索到的资料一致 是否遗漏关键条件 是否出现资料之外的事实Spring AI 提供统一的Evaluator接口并提供RelevancyEvaluator和FactCheckingEvaluator等实现。RelevancyEvaluator可以结合用户问题、RAG Context 和模型回答判断回答是否与问题及上下文相关FactCheckingEvaluator可以检查模型生成的 Claim 是否能够被提供的 Context 支持。例如一个简化的 RAG EvalEvaluationRequest request new EvaluationRequest( question, retrievedDocuments, answer ); RelevancyEvaluator evaluator new RelevancyEvaluator( ChatClient.builder(chatModel) ); EvaluationResponse result evaluator.evaluate(request); assertTrue(result.isPass());这里相当于把用户问题 检索资料 模型答案一起交给 Evaluator 判断。Eval 不一定全部由另一个 LLM 完成。对于订单金额、JSON 字段、Tool 名称、分类结果等明确规则普通 Java 断言往往更加稳定。LLM Evaluator 更适合语义正确性、相关性和内容完整性等难以用固定规则表达的问题。五、回归测试防止“修好 A又弄坏 B”假设当前已经积累 200 条 Badcase。修改了System Prompt RAG 切片方式 Embedding Model Tool 描述以后不应该只重新运行刚刚出错的那个问题而应该重新运行整个测试集200 条历史案例 ↓ 运行新版 Agent ↓ Eval ↓ 与旧版本结果比较例如Version 1 通过176 / 200 通过率88% Version 2 通过191 / 200 通过率95.5%同时还需要检查原本通过的案例是否出现退化。这就是回归测试的核心意义每一次修改都重新验证历史能力防止局部优化破坏其他场景。因此可以把 Agent 开发逐渐转变成发现错误 ↓ 加入 Badcase ↓ 建立 Eval ↓ 修改系统 ↓ 重新运行全部案例 ↓ 比较新旧版本六、Observability回答“错误到底发生在哪里”Eval 可以告诉开发者这个结果错了。Observability 进一步回答为什么错例如一次退款请求失败需要能够观察用户发送了什么 ↓ 实际使用了什么 Prompt ↓ Memory 提供了哪些历史信息 ↓ RAG 检索了哪些 Document ↓ LLM 返回了什么 ↓ 调用了哪个 Tool ↓ Tool 参数是什么 ↓ Tool 执行多久Spring AI 的 Observability 基于 Spring 生态中的 Micrometer Observations可以覆盖ChatClient、Advisor、ChatModel、EmbeddingModel 和 VectorStore 等核心组件Tool Calling 也会产生独立 observation并记录工具名称、执行时间以及 tracing 信息。因此Eval → 判断结果好不好 Observability → 定位为什么不好二者共同使用时才真正形成大模型应用的质量控制能力。七、什么时候才应该考虑 SFT 和 LoRA完成前面的措施以后如果模型仍然在一种稳定、重复、可标注的行为上长期表现不足并且已经积累了足够多高质量训练样本才开始具备微调价值。例如长期存在固定行业术语抽取错误 某类报告始终无法按照内部格式生成 大量相似输入都存在相同分类偏差而且已经积累输入 → 高质量标准输出这样的训练数据就可以进一步考虑 SFT 或 LoRA。这里要注意SFT、LoRA 属于模型训练层面的技术Fine-tuning并不是 Spring AI 的核心应用开发能力。Spring AI 更关注如何使用模型、组织 Context、RAG、Tool、Workflow 和 Eval。因此可以形成一个非常实用的判断知识不知道 → RAG 事情做不了 → Tool 流程不稳定 → Workflow 回答偶尔出错 → Eval Badcase Regression 某项能力长期稳定不足 → Fine-tuning八、量化和蒸馏解决的是另一类问题如果当前模型已经能够很好地完成任务真正的瓶颈变成【性能成本时空成本】推理成本太高 响应时间太长 显存占用太大 端侧无法部署此时才进入量化、蒸馏或者专用小模型的问题。这些技术主要优化模型的Size Latency Compute Cost Deployment它们解决的目标与 RAG、Prompt、Tool、Eval 有明显区别。因此“模型效果不好”本身通常不足以成为直接做量化或蒸馏的理由。九、把整个优化过程连接起来到这里可以建立一套比较完整的大模型应用优化路径用户发现错误 ↓ Observability 定位问题 ↓ 判断错误层级 ↓ RAG / Prompt / Tool / Workflow ↓ 加入 Badcase ↓ Eval 衡量 ↓ Regression Test 验证历史能力 ↓ 仍存在稳定重复能力缺陷 ↓ 是 ↓ 积累高质量训练数据 ↓ SFT / LoRA ↓ 性能成本成为瓶颈 ↓ 量化 / 蒸馏 / 专用小模型因此成熟的大模型应用开发已经非常接近传统软件工程中的质量保障思想。区别在于系统内部增加了 LLM 这一概率性组件因此测试对象从“代码路径是否正确”进一步扩展到了“检索内容、上下文、模型判断和工具行为是否共同产生了稳定结果”【路径扩大问题概率性发生但始终以结果为导向找到问题发生的位置并解决】。最终可以把这一过程简化为一句很实用的工程原则发现错误 → Badcase 固化问题 → Observability 定位根因 → 修改对应层 → Eval 验证该问题 → 回归测试验证整个系统。发现错误 ↓ 记录 Badcase ↓ Observability / Trace 定位原因 ↓ 确定错误类型 ↓ 修改对应层 Prompt / RAG / Tool / Workflow ... ↓ 针对该 Badcase 做 Eval 确认问题是否修好 ↓ 运行完整回归测试 确认没有“修好 A、弄坏 B”“Badcase 已经知道是错的为什么还要 Eval”关键在这里Badcase 只告诉我们“这个案例曾经失败”Eval 定义“以后怎样客观判断它是否已经修好”。例如 Badcase 是用户问退款规则 模型引用了旧政策我们已经知道它错了。但是修完 RAG 后需要一个判断标准是否引用最新政策 是否回答退款条件 是否出现旧政策内容这些标准就是 Eval。它可以是 Java 断言也可以是 LLM Evaluator。当这套质量保障循环真正建立以后大模型应用的优化才逐渐从“凭感觉调 Prompt”进入可测量、可比较、可持续迭代的软件工程过程。
返回列表