上一篇我们聊透了一件反常识的事直接拿JMeter压Agent对外HTTP接口根本不算真正的Agent压测。Agent内部多轮推理、循环工具调用带来的资源放大效应HTTP层监控完全感知不到。很多同学看完埋点方案之后马上遇到第二个拦路虎想要验证这套埋点、验证Agent在高并发下会不会死循环、验证熔断逻辑就得不停调用LLM接口。随便跑一轮并发几十上百块Token费用就出去了如果要反复调试、回归测试成本根本扛不住。还有一类麻烦开发环境没有外网LLM网关权限、内网隔离想做Agent并发测试连模型都调不通。这也是做大模型工程化落地时绝大多数团队会卡很久的痛点。 框架迁移提示本文Mock仿真思路是通用方案示例基于Spring AI实现如果你使用 LangChain4j、AgentScope 等其他Java Agent框架只需要替换框架对应的Model Provider实现业务压测逻辑不变。你有没有试过这种窘境想验证“连续调用检索工具会不会触发上下文超长”压测跑5分钟账单告警先来了想测极限并发下的熔断、最大推理轮次限制不敢开大并发只能小流量手工测试风险根本暴露不出来。真实模型压测适合上线前最后一轮验收而日常迭代、回归、容量预演必须要有一套不依赖真实LLM的仿真方案。今天这篇我们搭建一套Spring AI下的Mock LLM能力可控返回推理结果、可控模拟工具调用、可控模拟超时和异常配合JMeter发起并发和真实Agent调用链路完全一致对接上一篇我们写的Agent全链路埋点全程零Token消耗。本文代码基于Spring AI稳定版本可直接运行无编造API文末附带简历片段、JMeter脚本模板。一、先分清Mock LLM仿真压测 ≠ 简单Mock Controller不少人的第一想法直接在Controller层写Mock返回把接口写死返回固定字符串。这种方式非常廉价但完全没有价值绕过了Agent的思考逻辑、工具路由、上下文拼接、多轮循环无法复现Function Calling Java工具调用链路埋点采集的推理轮次、Token统计、工具调用指标全部无效合格的Agent仿真Mock必须侵入在Model层Agent框架照常走完整链路prompt组装→传给Model→解析返回的tool_call→执行工具→把结果塞回上下文→下一轮推理只是模型的输出由我们程序控制不走远程LLM接口。链路和生产环境1:1对齐只有模型返回内容是预制仿真数据这样我们之前搭建的Agent可观测埋点体系才能采集到真实有效的大模型压测指标。测试类型优点短板适合场景Controller层Mock实现最简单跳过Agent内部闭环指标失真只测网关、鉴权Model层Mock LLM仿真全链路保真、零成本、可模拟异常需要实现Model适配开发回归、容量压测、熔断校验真实LLM压测真实效果Token成本高、限流不可控上线前最终验收二、Spring AI Mock Model 设计思路Spring AI 的核心抽象是ChatModel我们自定义一个实现类MockChatModel实现ChatModel接口。我们可以灵活控制指定本轮返回普通文本回答结束Agent流程指定本轮返回Function Calling工具调用指令驱动Agent继续循环模拟模型超时、返回格式异常、返回超长上下文自定义返回的token usage用来模拟不同消耗的请求测试指标看板和上一篇的Advisor埋点完全兼容不需要改动之前的Agent全链路埋点代码。三、完整可运行源码1. pom.xml昨天的Pom无需新增依赖?xml version1.0 encodingUTF-8? project xmlns[http://maven.apache.org/POM/4.0.0](http://maven.apache.org/POM/4.0.0) xmlns:xsi[http://www.w3.org/2001/XMLSchema-instance](http://www.w3.org/2001/XMLSchema-instance) xsi:schemaLocation[http://maven.apache.org/POM/4.0.0](http://maven.apache.org/POM/4.0.0) [https://maven.apache.org/xsd/maven-4.0.0.xsd](https://maven.apache.org/xsd/maven-4.0.0.xsd) modelVersion4.0.0/modelVersion groupIdcom.agent.demo/groupId artifactIdagent-pressure-demo/artifactId version1.0-SNAPSHOT/version parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.3.0/version relativePath/ /parent properties java.version17/java.version spring-ai.version1.0.0-M1/spring-ai.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId version${spring-ai.version}/version /dependency dependency groupIdio.micrometer/groupId artifactIdmicrometer-registry-prometheus/artifactId /dependency /dependencies dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement /project2. MockChatModel.java核心仿真模型package com.agent.demo.model; import org.springframework.ai.chat.messages.Message; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.chat.model.Generation; import org.springframework.ai.chat.prompt.Prompt; import org.springframework.ai.model.ModelOptionsUtils; import org.springframework.ai.openai.api.OpenAiApi; import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage; import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionMessage.Role; import org.springframework.ai.openai.api.OpenAiApi.ChatCompletionTool; import org.springframework.ai.openai.api.OpenAiApi.FunctionToolCall; import org.springframework.stereotype.Component; import java.util.List; Component public class MockChatModel implements ChatModel { // 可配置是否返回工具调用制造多轮循环 private boolean enableMockToolCall true; Override public ChatResponse call(Prompt prompt) { if(enableMockToolCall){ // 仿真返回工具调用驱动Agent继续调用工具形成多轮链路 FunctionToolCall toolCall new FunctionToolCall(queryWeather, {\city\:\北京\}, call_1); ChatCompletionMessage msg new ChatCompletionMessage(, Role.ASSISTANT, List.of(toolCall), null); Generation gen new Generation(ModelOptionsUtils.toJsonString(msg)); return new ChatResponse(List.of(gen)); }else{ // 仿真直接返回回答本轮结束 Generation gen new Generation(北京今天晴气温22~28℃); return new ChatResponse(List.of(gen)); } } public void setEnableMockToolCall(boolean enableMockToolCall) { this.enableMockToolCall enableMockToolCall; } }3. 切换模型配置区分测试环境/生产环境package com.agent.demo.config; import com.agent.demo.model.MockChatModel; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.openai.OpenAiChatModel; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; Configuration public class ChatModelConfig { Value(${spring.ai.openai.api-key:}) private String apiKey; // test环境使用Mock模型压测、回归 Bean Profile(test) public ChatModel mockChatModel(){ return new MockChatModel(); } // prod环境使用真实OpenAI模型 Bean Profile(prod) public ChatModel realChatModel(OpenAiChatModel.Builder builder){ return builder.apiKey(apiKey).build(); } }4. JMeter测试脚本使用说明JMeter只需要正常POST请求访问Agent对外接口和压线上Agent接口写法完全一致请求体用户提问文本线程组设置并发线程数、循环次数后置处理器不需要特殊改造配套监控接入我们D1写的埋点指标Prometheus Grafana看板测试玩法开启enableMockToolCalltrue持续触发工具调用模拟多轮推理测试循环熔断、轮次上限开启enableMockToolCallfalse单轮直接返回对比两组指标差异调高并发验证线程池、上下文存储、trace链路是否泄露四、压测验证重点校验清单✅ 并发下埋点指标正常上报思考轮次、工具调用次数、Token统计持续写入看板✅ 设置最大推理轮次熔断后不会出现无限循环✅ 大量并发下TraceId不混乱、指标不会串请求✅ 模拟异常返回Agent异常分支、错误告警逻辑可以正常触发❌ 不要只看接口RT和错误率重点看Agent层指标❌ 不要用Controller Mock替代Model层仿真指标完全无效❌ 测试环境和生产环境的Agent超时、最大轮次、工具配置必须保持一致否则压测结论无参考价值简历描述片段基于Spring AI实现Model层Mock LLM仿真方案搭建零成本Agent压测环境仿真真实Function Calling调用、多轮推理链路和生产Agent执行链路对齐配合JMeter并发测试对接Agent全链路埋点体系在不消耗大模型Token的前提下完成Agent循环熔断、容量、异常场景回归降低大模型工程化测试成本。 落地资源推荐跑Agent的应用尤其是做压力测试更吃服务器资源通常本机是不够用的建议使用云服务器能大大减少我们做其他事的精力提高学习代码的专注力和学习AI的效率免除后顾之忧新用户首年特惠专属渠道https://www.aliyun.com/daily-act/ecs/activity_selection?userCodefzoabro9。领取完整工程找到图片上的水印即Java-AI工程师打出【agent-metric】即可本篇完整Mock源码JMeter脚本模板后台关键词下期预告下一篇我们聚焦压测之后的问题Agent循环调用、上下文膨胀的熔断策略教你写生产可用的多层熔断 上下文裁剪策略防止上线后偷偷无限循环吃掉账单。从源头锁死成本上限。
企业数字化 ERP 产品动态
相关推荐
[高光谱]Any-Diff物理约束的的HSI图像生成 一、概述本文的特点是:将物理先验融入扩散模型,利用少量已知光谱波段,生成具有合理空间结构和光谱物理特征的完整高光谱图像。不同于简单图像修复,高光谱图像必须满足:空间合理性:建筑物、植被、道路等结构… · 2026/11/5 3:55:29
顶刊论文学习笔记 今日学习的论文:Genome architecture shapes transcriptional responses to topoisomerase depletion in C. elegans中文大意:基因组结构(基因排列方式)塑造了秀丽隐杆线虫对拓扑异构酶耗竭的转录响应。基础知识:基因表达的中心法… · 2026/11/5 3:55:29
数据湖存储架构与性能优化实战指南 1. 数据湖存储架构深度解析数据湖作为大数据领域的核心基础设施,其存储架构与传统数据仓库有着本质区别。我曾在金融和电商行业主导过多个PB级数据湖建设项目,发现最关键的差异在于数据湖采用"先存储后处理"的范式。这种设计允许我们以原始格式… · 2026/11/5 4:42:54
实时语音转文字工具开发:技术选型与优化实践 1. 项目概述:语音转文字工具的核心价值在会议室里手忙脚乱记笔记的日子我受够了。去年参加一场产品需求讨论会时,我尝试用手机录音后转文字,结果发现三个致命问题:专业术语识别错误、多人对话分不清说话者、实时性差到需要等待处理… · 2026/11/5 4:42:54
TDengine时序数据库TSMA与RSMA机制解析与应用指南 1. TSMA与RSMA概念解析在TDengine时序数据库的实际应用中,TSMA(Time Series Merge Append)和RSMA(Rollup Summary Merge Append)是两种核心的数据合并机制。作为TDengine的深度使用者,我经常遇到开发者混淆… · 2026/11/5 4:42:54
scRNA-seq数据分析:高变基因筛选优化scTenifoldKnk计算效率 1. 项目背景与核心问题单细胞RNA测序(scRNA-seq)数据分析中,scTenifoldKnk是一种常用的基因调控网络(GRN)构建和差异分析工具。但在处理大规模数据集时,计算资源消耗成为显著瓶颈。一个典型的10x Genomics数… · 2026/11/5 4:42:54
Maestro自动化测试工具:低代码YAML脚本实践指南 1. Maestro自动化测试工具概述 Maestro是一款新兴的跨平台自动化测试框架,专为现代应用测试需求设计。作为一名长期从事测试自动化的工程师,我发现它最大的优势在于用YAML这种人类可读的格式来描述测试流程,这比传统基于代码的测试脚本要直观… · 2026/11/5 4:42:54
量子神经混合计算:72维超智能系统架构解析 1. 项目概述:量子-神经混合超智能生态系统的诞生背景在当代科技发展的最前沿,量子计算与神经科学的交叉融合正在催生新一代智能系统架构。7FLOOR Seventy-Two-Pointed Star(72星)超维工程系统正是这一趋势下的代表性产物。这个系统… · 2026/11/5 4:41:54
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38
多智能体协作系统架构设计与实践优化 1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中… · 2026/11/5 0:00:39
大模型系统性入门实战指南:从原理到部署微调的全链路路线 提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#… · 2026/11/5 0:00:39
鸿蒙文件系统沙箱机制解析与开发实践 1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的… · 2026/11/5 0:00:39
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38