LangChain4j Java AI 应用开发实战(六):声明式 AI Service - LangChain4j 的核心编程模型
系列篇章💥
| 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
✅ 解决方案:
- 优化 Prompt
@UserMessage("从以下文本中提取数字,只返回阿拉伯数字:{{text}}")
int extractNumber(String text);
- 添加容错处理
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'
原因:
- 未添加
langchain4j-spring-boot-starter依赖 - 接口不在 Spring 扫描路径下
- 未配置 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 浪潮已至,愿与你同行。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)