本文分享了如何用Java生态中的Spring AI和DeepSeek打造高性能智能客服Agent的经验。针对Java不适合AI的普遍认知,作者通过实际案例说明Java在AI应用工程化方面的优势,详细阐述了系统架构设计、核心代码实现及踩坑实录。最终上线效果显示,平均响应延迟仅1.2秒,日均处理8000+对话,有效降低人工转接率。对于Java开发者想快速接入大模型能力,本文提供了宝贵的实践参考。

去年公司要做智能客服,技术方案评审的时候,我提了一嘴用Java做,会议室安静了三秒。

有人忍不住问:Java做AI?你是不是看错了方向?

这反应我懂。毕竟打开GitHub搜AI项目,10个有9个是Python。Spring AI那会儿还是M版本,文档也不全,团队里确实没几个人看好。

但我们的实际情况是:订单系统、用户中心、支付网关全是Java写的,客服模块本来就嵌在Spring Cloud里。为了AI能力单独起一套Python服务?对接成本、运维成本、团队学习成本,账怎么算都不划算。

最后硬着头皮选了Spring AI + DeepSeek的方案。当时心里也没底,想着先跑个POC,不行再切Python。

结果POC做完,团队说:不用切了,就这个。

现在上线半年,平均响应1.2秒,日均处理8000+对话,Spring AI也GA了。回头看,当初那个"安静的三秒"挺有意思的——很多时候不是技术不行,是惯性思维在拦路。

这篇文章把全过程写下来:为什么选Java、架构怎么设计的、代码怎么写的、踩了哪些坑。如果你也在纠结技术选型,可以参考。

请添加图片描述

一、Java做AI,到底行不行?


反对Java做AI的理由,我听过不少:

  • Python有LangChain、LlamaIndex,Java这边"啥也没有"
  • Python写个prompt就几行代码,Java配环境配半天
  • 搜AI教程10篇有9篇是Python,Java资料少得可怜
  • AI需要频繁试错,Java编译太慢,折腾不动

这些说法有没有道理?有。如果只是跑个demo验证想法,Python确实快。

但回到我们的现实:订单系统Java写的,用户中心Java写的,支付网关也是Java写的。为了AI能力单独起一套Python服务,对接怎么接?两套认证鉴权怎么管?部署要两套流水线,出问题两个团队互相踢皮球。

更别提团队规模:Java开发十几个,Python就一两个。AI模块写完了谁维护?

所以我们的判断是:算法训练交给Python没问题,但AI应用工程化,Java不仅行,而且可能更行。

二、为什么最后选了Spring AI?


Java的AI框架选择确实不多。我们试了LangChain4j,也看了Semantic Kernel for Java,最后锁定的Spring AI。

选它有几个很实际的原因。

跟现有系统无缝衔接。 我们全是Spring Boot服务,加Spring AI就是加个starter,依赖注入、配置管理、监控链路全是现成的。团队成员不用学新东西,出来就能干活。

Function Calling直接可用。 智能客服不是聊天机器人,是要干活的。用户问"我的订单到哪了",系统得去调订单API。Spring AI的Function Calling机制,大模型自己判断什么时候调、传什么参数,跟OpenAI那套一样。不用自己写意图解析,省了不少事。

国产模型支持友好。 这点很关键。我们试过接OpenAI,延迟高不说,数据合规也过不去。DeepSeek的API格式跟OpenAI兼容,Spring AI换个base-url就能切过去,一行业务代码不用改。

还有一个时间上的巧合:我们项目做到一半的时候,Spring AI 1.0 GA了。之前用M版本的时候API天天变,升级一次改一堆代码,挺折腾的。GA之后稳定多了。

三、系统架构怎么设计的?


客服系统的需求很具体:

  • 用户问"帮我查下最近的订单",接着追问"第一个到哪了"——要能记住上下文
  • 查订单、查物流、查FAQ、创建工单——要能调业务接口
  • 退换货政策、保修条款——文档太长不能直接塞prompt,要走检索
  • 实在搞不定的——转人工,不能硬撑

架构图如下:

用户消息
    ↓
Spring AI ChatClient(对话编排)
    ↓
DeepSeek LLM(意图理解 + 响应生成)
    ↓
┌─────────────┬──────────────┬──────────────┐
│ Function     │ RAG 检索     │ ChatMemory   │
│ Calling     │ (向量数据库)  │ (Redis)      │
└──────┬──────┴───────┬──────┴──────┬───────┘
       ↓              ↓              ↓
    业务API        知识库         会话上下文
   (订单/物流)    (退换货政策)    (多轮记忆)

流程是:用户消息进来,ChatClient把上下文、工具定义、RAG结果打包发给DeepSeek,模型判断是直接回答还是调工具,最后把结果返回给用户。

听着简单,实际做的时候每个环节都踩过坑。下面细说。

四、核心代码


1. DeepSeek接入配置

spring:
  ai:
    openai:
      base-url: https://api.deepseek.com
      api-key: ${DEEPSEEK_API_KEY}
      chat:
        options:
          model: deepseek-chat
          temperature: 0.3

就这么几行。DeepSeek的API格式跟OpenAI兼容,Spring AI的OpenAI client直接能用。temperature设0.3是因为客服场景要稳定输出,不需要模型发挥创造力。

2. 定义Function(Tool)

@Configuration
public class CustomerServiceTools {

    @Autowired
    private OrderService orderService;

    @Bean
    @Description("根据用户ID查询最近订单列表")
    public Function<OrderQuery, OrderResult> queryOrders() {
        return request -> orderService.queryRecentOrders(request.userId());
    }

    @Bean
    @Description("根据订单号查询物流状态")
    public Function<LogisticsQuery, LogisticsResult> queryLogistics() {
        return request -> orderService.queryLogistics(request.orderId());
    }

    public record OrderQuery(String userId) {}
    public record OrderResult(List<Order> orders) {}
    public record LogisticsQuery(String orderId) {}
    public record LogisticsResult(String status, String location, String estimatedTime) {}
}

@Description里的文字是给大模型看的,它会根据这段描述判断要不要调这个函数。所以描述要写清楚:这个函数是干什么的,参数是什么意思。我们早期有函数描述写得模糊,模型该调的时候没调,不该调的时候乱调,排查了好一阵子。

3. ChatClient对话编排

@Service
public class CustomerServiceAgent {

    private final ChatClient chatClient;

    public CustomerServiceAgent(ChatClient.Builder builder) {
        this.chatClient = builder
            .defaultSystem("你是一个电商客服助手。"
                + "请根据用户的问题,调用相应的工具查询信息并回答。"
                + "如果工具查询不到相关信息,请根据知识库回答。"
                + "如果仍无法回答,建议用户转人工客服。")
            .defaultTools("queryOrders", "queryLogistics")
            .build();
    }

    public String chat(String sessionId, String userMessage) {
        return chatClient.prompt()
            .user(userMessage)
            .advisors(a -> a.param(ChatMemory.CONVERSATION_ID, sessionId))
            .call()
            .content();
    }
}

这段代码的作用:

  • 系统prompt给模型定角色和兜底规则
  • 绑定两个工具函数,让模型知道能调什么
  • 通过sessionId保持多轮对话记忆

advisors是Spring AI的拦截器,ChatMemory通过它注入。每个session有自己的对话历史,用户说"第一个订单到哪了",模型知道"第一个"指的是上一轮查出来的第一条。

4. RAG知识库检索

@Configuration
public class KnowledgeBaseConfig {

    @Bean
    VectorStore knowledgeVectorStore(EmbeddingClient embeddingClient) {
        return PgVectorStore.builder(jdbcTemplate, embeddingClient)
            .dimensions(1536)
            .distanceType(CosineDistance)
            .build();
    }
}

@Service
public class KnowledgeService {

    @Autowired
    private VectorStore vectorStore;

    public List<String> searchRelevant(String query, int topK) {
        return vectorStore.similaritySearch(
            SearchRequest.query(query)
                .withTopK(topK)
                .withSimilarityThreshold(0.7)
        ).stream()
            .map(Document::getText)
            .toList();
    }
}

退换货政策、保修条款这些长文档,先切成小块做向量化,存进PgVector。用户提问时检索相关片段,塞进prompt里给模型参考。

similarityThreshold这个参数是试出来的。设0.6会搜进一些不相关的内容,模型回答容易跑偏;设0.8又会漏掉该命中的,模型说"这个我不清楚"。最后定在0.7,两边平衡。

五、踩坑实录


坑1:DeepSeek API超时

刚上线那几天,偶尔会有请求超过30秒。排查发现是DeepSeek在处理长上下文时偶尔会慢,尤其是对话轮数多了之后。

解决方案:对话超过5轮做一次摘要压缩,把前面的对话总结成一段话再发给模型。同时加了重试机制,超时10秒自动重试一次。

.retryTemplate(
    RetryTemplate.builder()
        .maxAttempts(2)
        .retryOn(TimeoutException.class)
        .exponentialBackoff(1000, 2, 5000)
        .build()
)

坑2:Function Calling的JSON解析

DeepSeek大多数时候能正确返回function call的参数JSON,但偶尔会出幺蛾子——比如把订单号 DD202406150001 解析成 DD202406150001。 后面跟了个中文句号。

这种问题debug了好久才发现。最后在工具函数的参数解析里做了清洗:

private String cleanValue(String raw) {
    return raw.replaceAll("[。.,,;;//s]+$", "").trim();
}

坑3:向量数据库选型

一开始用的Redis Stack的向量搜索功能,数据量小的时候没问题。但知识库文档涨到5000+条之后,搜索延迟明显上升,而且召回率不稳定。

后来换成了PostgreSQL + pgvector,延迟稳定在50ms以内,召回率也好了不少。而且我们本来就有PG在用,不用多维护一个组件。

教训:向量数据库别图省事用Redis,文档量大了扛不住。

坑4:多轮对话上下文丢失

用户反馈"聊着聊着就忘了"。排查发现是ChatMemory默认只保留最近10条消息,某些场景下不够。但也不能无限制保留,token太多不仅慢还费钱。

最后的方案:最近6轮原文保留,再往前的做摘要。自己写了个Advisor来实现:

public class SummarizingMemoryAdvisor implements BaseAdvisor {

    @Override
    public AdvisedResponse before(AdvisedRequest request) {
        List<Message> messages = request.messages();
        if (messages.size() > 12) {
            // 把前面的消息压缩成摘要
            String summary = summarize(messages.subList(0, messages.size() - 12));
            // 用摘要替换原始消息
            request = request.mutate()
                .messages(buildShortenedMessages(summary, messages))
                .build();
        }
        return new AdvisedResponse(request);
    }
}

坑5:并发场景下的限流

大促期间流量暴涨,DeepSeek的API有QPS限制,超了直接429。加了个Sentinel做限流,超过阈值的请求走降级逻辑——先返回FAQ里的通用答案,同时提示用户"当前咨询量大,如需帮助请转人工"。

@SentinelResource(value = "aiChat", fallback = "chatFallback")
public String chat(String sessionId, String userMessage) {
    // 正常AI对话
}

public String chatFallback(String sessionId, String userMessage, Throwable t) {
    return "当前咨询量较大,已为您转接人工客服,请稍候...";
}

六、上线效果


上了半年多,说说数据:

指标 数值
平均响应延迟 1.2秒
P99延迟 3.5秒
日均对话量 8000+
意图识别准确率 95.3%
知识库命中率 91.2%
人工转接率 从原来的60%降到23%
并发支持 单节点200 QPS

最直观的变化是:客服团队从15人减到8人,剩下的都是处理复杂问题的,重复性问题基本被AI消化了。

对比之前用Python做的POC方案,Java版本的优势主要体现在:

  • 部署运维:跟现有Spring Cloud体系一套搞定,不用单独维护Python服务
  • 团队效率:Java开发不用学新语言,review代码、排查问题都顺手
  • 稳定性:JVM的成熟度不用多说,长时间运行内存稳定,Python方案之前有内存泄漏的问题

七、写在最后


回到标题的问题:Java真的不适合AI吗?

如果你说的"AI"是训练大模型、做算法研究,那确实,Python的生态优势摆在那。但如果是做AI应用、把大模型能力接入业务系统,Java不仅能做,而且在企业级场景下可能比Python更合适。

AI应用开发不只是写个prompt调API。认证、限流、监控、容灾、跟业务系统的集成——这些工程化的事,Java生态做了二十年,链路是通的。

Spring AI的意义在于:Java开发者不需要重新学一门语言,就能做AI应用。对已经有Java技术栈的团队来说,这个门槛降低了很多。

技术选型没有标准答案。Python做AI训练很强,Java做AI工程化也很稳。关键是看你自己有什么、要解决什么问题,而不是跟风站队。

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线科技企业深耕十二载,见证过太多因技术卡位而跃迁的案例。那些率先拥抱 AI 的同事,早已在效率与薪资上形成代际优势,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在大模型的学习中的很多困惑。我们整理出这套 AI 大模型突围资料包

  • ✅ 从零到一的 AI 学习路径图
  • ✅ 大模型调优实战手册(附医疗/金融等大厂真实案例)
  • ✅ 百度/阿里专家闭门录播课
  • ✅ 大模型当下最新行业报告
  • ✅ 真实大厂面试真题
  • ✅ 2026 最新岗位需求图谱

所有资料 ⚡️ ,朋友们如果有需要 《AI大模型入门+进阶学习资源包》下方扫码获取~
在这里插入图片描述

① 全套AI大模型应用开发视频教程

(包含提示工程、RAG、LangChain、Agent、模型微调与部署、DeepSeek等技术点)
在这里插入图片描述

② 大模型系统化学习路线

作为学习AI大模型技术的新手,方向至关重要。 正确的学习路线可以为你节省时间,少走弯路;方向不对,努力白费。这里我给大家准备了一份最科学最系统的学习成长路线图和学习规划,带你从零基础入门到精通!
在这里插入图片描述

③ 大模型学习书籍&文档

学习AI大模型离不开书籍文档,我精选了一系列大模型技术的书籍和学习文档(电子版),它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。
在这里插入图片描述

④ AI大模型最新行业报告

2025最新行业报告,针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。
在这里插入图片描述

⑤ 大模型项目实战&配套源码

学以致用,在项目实战中检验和巩固你所学到的知识,同时为你找工作就业和职业发展打下坚实的基础。
在这里插入图片描述

⑥ 大模型大厂面试真题

面试不仅是技术的较量,更需要充分的准备。在你已经掌握了大模型技术之后,就需要开始准备面试,我精心整理了一份大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余

图片

以上资料如何领取?

在这里插入图片描述

为什么大家都在学大模型?

最近科技巨头英特尔宣布裁员2万人,传统岗位不断缩减,但AI相关技术岗疯狂扩招,有3-5年经验,大厂薪资就能给到50K*20薪!

图片

不出1年,“有AI项目经验”将成为投递简历的门槛。

风口之下,与其像“温水煮青蛙”一样坐等被行业淘汰,不如先人一步,掌握AI大模型原理+应用技术+项目实操经验,“顺风”翻盘!
在这里插入图片描述
在这里插入图片描述

这些资料真的有用吗?

这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理,现任上海殷泊信息科技CEO,其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证,服务航天科工、国家电网等1000+企业,以第一作者在IEEE Transactions发表论文50+篇,获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。

资料内容涵盖了从入门到进阶的各类视频教程和实战项目,无论你是小白还是有些技术基础的技术人员,这份资料都绝对能帮助你提升薪资待遇,转行大模型岗位。
在这里插入图片描述
在这里插入图片描述

以上全套大模型资料如何领取?

在这里插入图片描述

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐