系列篇章💥

No. 文章
1 LangChain4j Java AI 应用开发实战(一):LangChain4j 快速入门指南
2 LangChain4j Java AI 应用开发实战(二):大模型参数调优实战:Temperature、TopP、MaxTokens 深度解析
3 LangChain4j Java AI 应用开发实战(三):多模态 AI 开发 - 图片理解与图像生成实战
4 LangChain4j Java AI 应用开发实战(四):提示词工程进阶 - 模板化与结构化 Prompt 设计
5 LangChain4j Java AI 应用开发实战(五):流式响应与对话记忆 - 提升用户体验的关键技术
6 LangChain4j Java AI 应用开发实战(六):声明式 AI Service - LangChain4j 的核心编程模型


前言

传统的 AI 调用需要手动拼接 Prompt、发送 HTTP 请求、解析 JSON 响应,代码冗长且难以维护。LangChain4j 提供了革命性的声明式编程模型——AI Service,通过定义 Java 接口即可自动获得 AI 能力,无需手写实现类。本文将深入讲解 AiServices.create() 的动态代理原理,@SystemMessage@UserMessage@V 等核心注解的使用技巧,以及 String、List、Enum、POJO 等多种返回值类型的映射机制。你将学会如何将复杂的 AI 调用简化为优雅的接口方法,让 Java 开发者以熟悉的方式构建 AI 应用,大幅提升开发效率和代码可维护性。


一、为什么需要 AI Service?

1.1 传统方式的痛点

回顾之前的示例,我们这样调用 AI:

// ❌ 传统方式:手动构建 Prompt
ChatModel chatModel = OpenAiChatModel.builder()
    .apiKey("demo")
    .modelName("gpt-4o-mini")
    .build();

String prompt = "请将以下文本翻译成英文:你好世界";
String response = chatModel.chat(prompt);
System.out.println(response);

这种方式存在以下问题:

问题 说明 影响
Prompt 硬编码 提示词散落在业务代码中 难以维护和复用
参数拼接复杂 需要手动格式化变量 容易出错
返回值解析麻烦 需要手动解析 JSON/文本 代码冗长
缺乏类型安全 字符串传递,编译期无法检查 运行时才能发现错误
测试困难 难以 Mock 和单元测试 质量难保证

1.2 AI Service 的优势

使用 AI Service 后:

// ✅ 声明式方式:定义接口即可
interface Translator {
    @SystemMessage("你是专业翻译助手")
    @UserMessage("将以下文本翻译成{{language}}:{{text}}")
    String translate(@V("text") String text, @V("language") String language);
}

Translator translator = AiServices.create(Translator.class, chatModel);
String result = translator.translate("你好世界", "英文");
// 输出:Hello World

优势

  • 声明式编程:只需定义接口,框架自动生成实现
  • 类型安全:编译期检查,IDE 智能提示
  • 自动 Prompt 构建:注解驱动,无需手动拼接
  • 结构化输出:自动解析为 Java 对象
  • 易于测试:接口可 Mock,支持单元测试
  • 代码简洁:减少 80% 的样板代码

二、基础 AI Service代码详解

2.1 最简单的 AI Service

static class Simple_AI_Service_Example {

    interface Assistant {
        // 用户输入的 message 会直接作为 UserMessage 发送给 LLM
        String chat(String message);
    }

    public static void main(String[] args) {
        // AiServices.create() 使用 Java 动态代理,在运行时生成 Assistant 的实现类
        Assistant assistant = AiServices.create(Assistant.class, model);

        String userMessage = "Translate 'Plus-Values des cessions de valeurs mobilières'";

        // 像调用本地方法一样调用大模型
        String answer = assistant.chat(userMessage);

        System.out.println(answer);
    }
}

核心概念

(1)接口定义规则

interface Assistant {
    String chat(String message);
}

规则

  • 必须是 interface(不能是 class)
  • 方法只有一个 String 参数时,自动作为 UserMessage
  • 返回 String 时,直接返回模型的文本输出

(2)AiServices.create()

Assistant assistant = AiServices.create(Assistant.class, model);

工作原理

AiServices.create()
       ↓
Java 动态代理(Proxy.newProxyInstance)
       ↓
生成 Assistant 接口的实现类(运行时)
       ↓
拦截方法调用
       ↓
构建 Prompt → 调用 ChatModel → 解析响应
       ↓
返回结果

关键点

  • 不需要手写 implements Assistant
  • 不需要 new AssistantImpl()
  • 框架在运行时自动生成代理对象

2.2 添加系统消息:角色设定

static class AI_Service_with_System_Message_Example {

    interface Chef {
        // @SystemMessage 定义了 AI 的角色
        @SystemMessage("You are a professional chef. You are friendly, polite and concise.")
        String answer(String question);
    }

    public static void main(String[] args) {
        Chef chef = AiServices.create(Chef.class, model);

        String answer = chef.answer("How long should I grill chicken?");
        System.out.println(answer);
        // 输出:Grilling chicken usually takes around 10-15 minutes per side...
    }
}

@SystemMessage 的作用

发送给模型的消息结构:
┌──────────────────────────────────────┐
│ SystemMessage:                       │
│ "You are a professional chef..."     │  ← 设定角色和行为准则
├──────────────────────────────────────┤
│ UserMessage:                         │
│ "How long should I grill chicken?"   │  ← 用户问题
└──────────────────────────────────────┘

常见用途

  • 设定 AI 角色(客服、医生、律师等)
  • 约束回答风格(简洁、详细、幽默等)
  • 定义业务范围(只回答技术问题)
  • 设置语言(只用中文回答)

2.3 模板化消息:动态参数

static class AI_Service_with_System_and_User_Messages_Example {

    interface TextUtils {

        /**
         * 翻译方法。
         */
        @SystemMessage("You are a professional translator into {{language}}")
        @UserMessage("Translate the following text: {{text}}")
        String translate(@V("text") String text, @V("language") String language);

        /**
         * 总结方法。
         */
        @SystemMessage("Summarize every message from user in {{n}} bullet points.")
        List<String> summarize(@UserMessage String text, @V("n") int n);
    }

    public static void main(String[] args) {
        TextUtils utils = AiServices.create(TextUtils.class, model);

        // 调用翻译
        String translation = utils.translate("Hello, how are you?", "italian");
        System.out.println(translation); // Ciao, come stai?

        // 调用总结
        String text = "AI is a branch of computer science...";
        List<String> bulletPoints = utils.summarize(text, 3);
        bulletPoints.forEach(System.out::println);
    }
}

核心注解

(1)@V 注解(Variable)

String translate(@V("text") String text, @V("language") String language);

作用:将方法参数绑定到模板变量

@V("text") → {{text}}
@V("language") → {{language}}

规则

  • 注解值必须与模板中的占位符名称一致
  • 支持任意类型(会自动调用 toString()

(2)@UserMessage 直接标注参数

List<String> summarize(@UserMessage String text, @V("n") int n);

作用:该参数的内容直接作为用户消息(不使用模板)

对比

// 方式 1:使用模板
@UserMessage("总结以下内容:{{text}}")
String summarize1(@V("text") String text);

// 方式 2:直接作为消息
@UserMessage 
String summarize2(String text);

// 效果相同,但方式 2 更简洁

三、结构化输出:从文本提取 Java 对象

3.1 枚举类型提取

static class Sentiment_Extracting_AI_Service_Example {

    enum Sentiment {
        POSITIVE, NEUTRAL, NEGATIVE
    }

    interface SentimentAnalyzer {

        /**
         * {{it}} 是特殊占位符,表示方法的第一个参数。
         */
        @UserMessage("Analyze sentiment of {{it}}")
        Sentiment analyzeSentimentOf(String text);

        /**
         * 返回 boolean 类型时,框架会将模型的 Yes/No 回答解析为 true/false。
         */
        @UserMessage("Does {{it}} have a positive sentiment?")
        boolean isPositive(String text);
    }

    public static void main(String[] args) {
        SentimentAnalyzer sentimentAnalyzer = AiServices.create(SentimentAnalyzer.class, model);

        Sentiment sentiment = sentimentAnalyzer.analyzeSentimentOf("It is good!");
        System.out.println(sentiment); // POSITIVE

        boolean positive = sentimentAnalyzer.isPositive("It is bad!");
        System.out.println(positive); // false
    }
}

支持的返回值类型

返回类型 说明 示例
String 原始文本 "你好"
enum 枚举值 Sentiment.POSITIVE
boolean 布尔值 true/false
int/long/double 数值 42, 3.14
List<T> 列表 ["苹果", "香蕉"]
POJO 自定义对象 new Person("张三", 25)

工作原理

模型输出:"POSITIVE"
    ↓
LangChain4j 解析器
    ↓
匹配枚举值 Sentiment.POSITIVE
    ↓
返回 Java 对象

3.2 列表枚举提取(多标签分类)

static class Hotel_Review_AI_Service_Example {

    public enum IssueCategory {
        MAINTENANCE_ISSUE,     // 维护问题
        SERVICE_ISSUE,         // 服务问题
        COMFORT_ISSUE,         // 舒适度问题
        FACILITY_ISSUE,        // 设施问题
        CLEANLINESS_ISSUE,     // 清洁度问题
        CONNECTIVITY_ISSUE,    // 网络连接问题
        CHECK_IN_ISSUE,        // 入住办理问题
        OVERALL_EXPERIENCE_ISSUE // 整体体验问题
    }

    interface HotelReviewIssueAnalyzer {

        // |||{{it}}||| 使用分隔符包裹文本
        @UserMessage("Please analyse the following review: |||{{it}}|||")
        List<IssueCategory> analyzeReview(String review);
    }

    public static void main(String[] args) {
        HotelReviewIssueAnalyzer analyzer = AiServices.create(HotelReviewIssueAnalyzer.class, model);

        String review = "Our stay at hotel was a mixed experience. The location was perfect... " +
                        "However, we encountered several issues. The air conditioning... " +
                        "Additionally, the room service was slow...";

        List<IssueCategory> issues = analyzer.analyzeReview(review);
        System.out.println(issues);
        // 输出:[MAINTENANCE_ISSUE, SERVICE_ISSUE, COMFORT_ISSUE, OVERALL_EXPERIENCE_ISSUE]
    }
}

应用场景

  • 情感分析(正面/负面/中性)
  • 意图识别(查询/投诉/建议)
  • 内容分类(技术/业务/管理)
  • 风险评级(低/中/高)

3.3 数值类型提取

static class Number_Extracting_AI_Service_Example {

    interface NumberExtractor {

        @UserMessage("Extract number from {{it}}")
        int extractInt(String text);

        @UserMessage("Extract number from {{it}}")
        double extractDouble(String text);

        @UserMessage("Extract number from {{it}}")
        BigDecimal extractBigDecimal(String text);
    }

    public static void main(String[] args) {
        NumberExtractor extractor = AiServices.create(NumberExtractor.class, model);

        int age = extractor.extractInt("我今年二十五岁");
        System.out.println(age); // 25

        double price = extractor.extractDouble("价格是 99.99 元");
        System.out.println(price); // 99.99

        BigDecimal amount = extractor.extractBigDecimal("总金额为 1,234,567.89 元");
        System.out.println(amount); // 1234567.89
    }
}

支持的数值类型

类型 适用场景 示例
int 整数 年龄、数量
long 大整数 订单号、ID
float/double 浮点数 价格、评分
BigDecimal 高精度小数 金额、汇率
BigInteger 超大整数 天文数字

3.4 POJO 提取(复杂对象)

虽然 AIServiceExamples.java 中未展示,但这是最重要的功能之一。让我们补充一个完整示例:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
    
    @Description("姓名")
    private String name;
    
    @Description("年龄")
    private int age;
    
    @Description("邮箱地址")
    private String email;
    
    @Description("手机号码")
    private String phone;
}

interface PersonExtractor {
    
    @UserMessage("从以下文本中提取人员信息:{{text}}")
    Person extractPerson(@V("text") String text);
}

public class POJOExtractionExample {
    
    public static void main(String[] args) {
        
        ChatModel model = OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("gpt-4o-mini")
            .build();

        PersonExtractor extractor = AiServices.create(PersonExtractor.class, model);

        String text = "张三,今年28岁,邮箱是zhangsan@example.com,手机号13800138000";
        
        Person person = extractor.extractPerson(text);
        
        System.out.println(person.getName());   // 张三
        System.out.println(person.getAge());    // 28
        System.out.println(person.getEmail());  // zhangsan@example.com
        System.out.println(person.getPhone());  // 13800138000
    }
}

@Description 注解

@Description("姓名")
private String name;

作用:为字段添加语义说明,帮助模型理解如何提取

关键点

  • ✅ 字段必须有 @Description 注解(帮助模型理解)
  • ✅ 支持嵌套对象(POJO 中包含 POJO)
  • ✅ 支持 List(提取多个对象)

工作原理

模型接收 Prompt → 生成 JSON 格式文本
    ↓
LangChain4j 解析 JSON
    ↓
映射到 Java 对象字段
    ↓
返回 Person 实例

四、高级特性

4.1 记忆集成

AI Service 可以轻松集成对话记忆:

interface AssistantWithMemory {

    @SystemMessage("你是友好的聊天助手")
    String chat(String message);
}

public static void main(String[] args) {
    
    // 创建对话记忆
    ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);

    // 创建带记忆的 AI Service
    AssistantWithMemory assistant = AiServices.builder(AssistantWithMemory.class)
        .chatModel(model)
        .chatMemory(chatMemory)  // 绑定记忆
        .build();

    // 第一轮对话
    String reply1 = assistant.chat("我叫张三");
    System.out.println(reply1); // 你好,张三!

    // 第二轮对话(能记住名字)
    String reply2 = assistant.chat("我叫什么名字?");
    System.out.println(reply2); // 你叫张三。
}

关键 API

AiServices.builder(Assistant.class)
    .chatModel(model)           // 设置模型
    .chatMemory(chatMemory)     // 设置记忆
    .tools(tools)               // 设置工具(后续文章讲解)
    .build();                   // 构建

4.2 多用户记忆隔离

interface PersonalAssistant {

    @SystemMessage("你是个人助手")
    String chat(@MemoryId String userId, String message);
}

public static void main(String[] args) {
    
    // 为每个用户创建独立的记忆
    ChatMemoryProvider memoryProvider = userId -> 
        MessageWindowChatMemory.withMaxMessages(10);

    PersonalAssistant assistant = AiServices.builder(PersonalAssistant.class)
        .chatModel(model)
        .chatMemoryProvider(memoryProvider)  // 记忆提供者
        .build();

    // 用户 A 的对话
    String replyA1 = assistant.chat("user-A", "我喜欢篮球");
    String replyA2 = assistant.chat("user-A", "我喜欢什么运动?");
    System.out.println(replyA2); // 你喜欢篮球。

    // 用户 B 的对话(不受影响)
    String replyB1 = assistant.chat("user-B", "我喜欢足球");
    String replyB2 = assistant.chat("user-B", "我喜欢什么运动?");
    System.out.println(replyB2); // 你喜欢足球。
}

@MemoryId 注解

  • 标记哪个参数作为用户/会话 ID
  • LangChain4j 自动为该 ID 维护独立记忆
  • 不同用户互不干扰

4.3 流式输出

AI Service 也支持流式响应:

import dev.langchain4j.service.TokenStream;

interface StreamingAssistant {

    @SystemMessage("你是聊天助手")
    TokenStream chat(String message);  // 返回 TokenStream
}

public static void main(String[] args) {
    
    StreamingAssistant assistant = AiServices.create(StreamingAssistant.class, model);

    // 流式调用
    assistant.chat("请写一首诗")
        .onNext(token -> System.out.print(token))  // 逐字输出
        .onComplete(response -> System.out.println("\n完成"))
        .onError(error -> error.printStackTrace())
        .start();  // 启动流式传输
}

TokenStream 方法

方法 说明
onNext() 接收每个 token
onComplete() 完成回调
onError() 错误回调
start() 启动传输

五、Spring Boot 集成:@AiService 注解

5.1 传统方式 vs Spring Boot 方式

(1)传统方式(手动创建)

// ❌ 需要手动调用 AiServices.create()
Assistant assistant = AiServices.create(Assistant.class, model);

(2)Spring Boot 方式(自动代理)

// ✅ 只需添加 @AiService 注解,Spring 自动管理
@AiService
interface Assistant {
    @SystemMessage("你是助手")
    String chat(String message);
}

5.2 完整示例

(1)pom.xml 依赖

<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-spring-boot-starter</artifactId>
    <version>1.14.0</version>
</dependency>

(2)application.properties 配置

# OpenAI 配置
langchain4j.open-ai.chat-model.api-key=${OPENAI_API_KEY}
langchain4j.open-ai.chat-model.model-name=gpt-4o-mini
langchain4j.open-ai.chat-model.base-url=https://api.openai.com/v1

(3)定义 AI Service

@AiService
public interface CustomerServiceAssistant {

    @SystemMessage("""
        你是电商平台的智能客服助手。
        
        职责:
        1. 解答用户关于订单、物流、退款等问题
        2. 语气友好、专业、简洁
        3. 如果无法回答,引导用户联系人工客服
        """)
    String chat(@MemoryId String userId, String message);
}

(4)Controller 使用

@RestController
@RequestMapping("/api/chat")
public class ChatController {

    @Autowired
    private CustomerServiceAssistant assistant;

    @PostMapping("/send")
    public String sendMessage(@RequestParam String userId, 
                              @RequestParam String message) {
        return assistant.chat(userId, message);
    }
}

优势

  • ✅ 无需手动创建 AiServices.create()
  • ✅ Spring 自动注入 Bean
  • ✅ 支持 @Autowired、构造函数注入
  • ✅ 与其他 Spring Bean 无缝集成

5.3 配置多个 AI Service

// 客服助手
@AiService
interface CustomerService {
    @SystemMessage("你是客服助手")
    String chat(String message);
}

// 技术顾问
@AiService
interface TechAdvisor {
    @SystemMessage("你是技术专家,擅长 Java 编程")
    String advise(String question);
}

// Controller 中使用
@RestController
public class MultiServiceController {

    @Autowired
    private CustomerService customerService;

    @Autowired
    private TechAdvisor techAdvisor;

    @GetMapping("/customer")
    public String customerChat(@RequestParam String msg) {
        return customerService.chat(msg);
    }

    @GetMapping("/tech")
    public String techAdvice(@RequestParam String question) {
        return techAdvisor.advise(question);
    }
}

六、实战案例:智能翻译服务

6.1 需求

构建支持多语言翻译的 AI Service,要求:

  • 支持中英日韩等多语言
  • 保持专业术语准确
  • 返回结构化结果(原文、译文、置信度)

6.2 完整代码

(1)定义返回值 POJO

@Data
@AllArgsConstructor
@NoArgsConstructor
public class TranslationResult {
    
    @Description("原始文本")
    private String originalText;
    
    @Description("翻译后的文本")
    private String translatedText;
    
    @Description("源语言")
    private String sourceLanguage;
    
    @Description("目标语言")
    private String targetLanguage;
    
    @Description("置信度(0-1之间)")
    private double confidence;
}

(2)定义 AI Service 接口

@AiService
public interface TranslationService {

    @SystemMessage("""
        你是专业的多语言翻译专家。
        
        要求:
        1. 准确翻译,保持原意
        2. 符合目标语言的表达习惯
        3. 专业术语使用标准译法
        4. 评估翻译置信度(0-1之间)
        """)
    @UserMessage("""
        请将以下{{sourceLang}}文本翻译成{{targetLang}}。
        
        原文:{{text}}
        
        请以 JSON 格式返回翻译结果。
        """)
    TranslationResult translate(
        @V("text") String text,
        @V("sourceLang") String sourceLang,
        @V("targetLang") String targetLang
    );
}

(3)Service 层封装

@Service
public class TranslationServiceImpl {

    @Autowired
    private TranslationService translationService;

    /**
     * 翻译文本
     */
    public TranslationResult translate(String text, String sourceLang, String targetLang) {
        
        // 输入校验
        if (text == null || text.isEmpty()) {
            throw new IllegalArgumentException("待翻译文本不能为空");
        }
        
        // 调用 AI Service
        try {
            return translationService.translate(text, sourceLang, targetLang);
        } catch (Exception e) {
            throw new ServiceException("翻译失败:" + e.getMessage(), e);
        }
    }

    /**
     * 批量翻译
     */
    public List<TranslationResult> batchTranslate(List<String> texts, 
                                                   String sourceLang, 
                                                   String targetLang) {
        
        return texts.parallelStream()
            .map(text -> translate(text, sourceLang, targetLang))
            .collect(Collectors.toList());
    }
}

(4)Controller 层

@RestController
@RequestMapping("/api/translation")
public class TranslationController {

    @Autowired
    private TranslationServiceImpl translationService;

    /**
     * 单条翻译
     */
    @PostMapping("/translate")
    public ResponseEntity<TranslationResult> translate(
            @RequestBody TranslationRequest request) {
        
        TranslationResult result = translationService.translate(
            request.getText(),
            request.getSourceLang(),
            request.getTargetLang()
        );
        
        return ResponseEntity.ok(result);
    }

    /**
     * 批量翻译
     */
    @PostMapping("/batch-translate")
    public ResponseEntity<List<TranslationResult>> batchTranslate(
            @RequestBody BatchTranslationRequest request) {
        
        List<TranslationResult> results = translationService.batchTranslate(
            request.getTexts(),
            request.getSourceLang(),
            request.getTargetLang()
        );
        
        return ResponseEntity.ok(results);
    }
}

(5)使用示例

# 请求
curl -X POST http://localhost:8080/api/translation/translate \
  -H "Content-Type: application/json" \
  -d '{
    "text": "人工智能正在改变世界",
    "sourceLang": "中文",
    "targetLang": "英文"
  }'

# 响应
{
  "originalText": "人工智能正在改变世界",
  "translatedText": "Artificial intelligence is changing the world",
  "sourceLanguage": "中文",
  "targetLanguage": "英文",
  "confidence": 0.95
}

七、常见问题与避坑指南

7.1 接口方法参数过多

问题

// ❌ 参数太多,难以维护
String generate(@V("title") String title, 
                @V("author") String author,
                @V("date") String date,
                @V("content") String content,
                @V("tags") String tags,
                @V("category") String category);

解决方案:使用 POJO 封装参数

@Data
public class ArticleRequest {
    String title;
    String author;
    String date;
    String content;
    String tags;
    String category;
}

// ✅ 简洁清晰
String generate(@V("request") ArticleRequest request);

7.2 模板变量名不匹配

现象

@UserMessage("你好,{{name}}")
String greet(@V("userName") String name);  // 变量名不一致

// 输出:你好,{{name}}  (未被替换)

解决方案:确保注解值与占位符一致

@UserMessage("你好,{{name}}")
String greet(@V("name") String name);  // ✅ 一致

7.3 返回值解析失败

现象

int extractNumber(String text);

// 模型输出:"大约五十左右"
// 解析失败:NumberFormatException

解决方案

  1. 优化 Prompt
@UserMessage("从以下文本中提取数字,只返回阿拉伯数字:{{text}}")
int extractNumber(String text);
  1. 添加容错处理
try {
    int number = extractor.extractNumber(text);
} catch (Exception e) {
    logger.warn("数字提取失败,使用默认值", e);
    return 0;
}

7.4 Spring Boot 中 @AiService 未生效

现象

NoSuchBeanDefinitionException: No qualifying bean of type 'Assistant'

原因

  1. 未添加 langchain4j-spring-boot-starter 依赖
  2. 接口不在 Spring 扫描路径下
  3. 未配置 ChatModel Bean

解决方案

// 1. 确认依赖
<dependency>
    <groupId>dev.langchain4j</groupId>
    <artifactId>langchain4j-spring-boot-starter</artifactId>
</dependency>

// 2. 配置 ChatModel Bean
@Configuration
public class LangChain4jConfig {
    
    @Bean
    public ChatModel chatModel() {
        return OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("gpt-4o-mini")
            .build();
    }
}

// 3. 确保接口在@ComponentScan 路径下
@SpringBootApplication(scanBasePackages = "com.example")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

八、最佳实践

8.1 接口设计规范

推荐

@AiService
public interface CustomerService {
    
    // 方法名清晰表达意图
    @SystemMessage("你是客服助手")
    String answerQuestion(@MemoryId String userId, String question);
    
    // 复杂场景使用结构化输出
    OrderInfo queryOrder(@MemoryId String userId, @V("orderId") String orderId);
}

避免

// ❌ 方法名模糊
String chat(String msg);

// ❌ 参数名无意义
String process(String a, String b);

8.2 SystemMessage 设计原则

好的 SystemMessage

@SystemMessage("""
    你是资深 Java 开发工程师,专注于 Spring Boot 应用开发。
    
    回答要求:
    1. 提供可运行的代码示例
    2. 解释关键概念和原理
    3. 指出常见陷阱和最佳实践
    4. 保持回答简洁,控制在 500 字以内
    """)

原则

  • 明确角色定位
  • 设定回答风格
  • 约束输出格式
  • 限定业务范围

8.3 错误处理策略

@Service
public class RobustTranslationService {

    @Autowired
    private TranslationService translationService;

    public TranslationResult translateWithFallback(String text, 
                                                    String sourceLang, 
                                                    String targetLang) {
        
        // 第一次尝试
        try {
            return translationService.translate(text, sourceLang, targetLang);
        } catch (Exception e) {
            logger.warn("翻译失败,重试中...", e);
            
            // 第二次尝试(降低要求)
            try {
                return simpleTranslate(text, sourceLang, targetLang);
            } catch (Exception e2) {
                logger.error("翻译彻底失败", e2);
                
                // 返回默认值
                return new TranslationResult(
                    text, 
                    "[翻译失败]", 
                    sourceLang, 
                    targetLang, 
                    0.0
                );
            }
        }
    }
}

结语

通过本文的学习,你已经掌握了 LangChain4j 声明式 AI Service 的核心技术。从最简单的接口定义,到 @SystemMessage@UserMessage@V 等注解的组合使用,再到枚举、POJO 等结构化输出的自动映射,这些技术能让你的 AI 调用代码减少 80% 以上。结合 Spring Boot 的 @AiService 注解,更是实现了零配置自动装配,让 Java 开发者以熟悉的方式构建 AI 应用。记住,好的接口设计是成功的关键——清晰的方法命名、合理的参数封装、详细的 SystemMessage,都是构建高质量 AI Service 的基础。下一篇我们将深入探讨 Function Calling 工具调用,学习如何让 AI 自主决策调用 Java 方法,实现真正的智能代理!


在这里插入图片描述

🎯🔖更多专栏系列文章:AI大模型提示工程完全指南AI大模型探索之路(零基础入门)AI大模型预训练微调进阶AI大模型开源精选实践AI大模型Spring AI开发实战🔥🔥🔥 其他专栏可以查看博客主页

🔔 关于作者:资深程序老猿,10年+架构经验,现专注 AIGC 探索与实践。
👍 若文章对你有所触动,恳请点赞 ⭐ 关注 ⭐ 收藏!AI 浪潮已至,愿与你同行。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐