如何使用LangChain4j框架创建和使用多种AI服务。它通过定义接口和注解,将自然语言处理任务(如情感分析、数字提取、日期提取、POJO提取等)封装为服务,并通过LangChain4j的AiServices动态生成这些服务的实现。
本章主要讲述基于LangChain调用大模型如何进行结构化输出的真实示例,一共列列举,本章主要介绍如何从自然语言中借助大模型提取特定的数字的例子
整体代码结果说明
代码定义了多个静态内部类,每个类都展示了LangChain4j中不同类型的AI服务示例。这些服务通过接口和注解定义,并通过AiServices.create()方法动态生成实现。每个类都包含一个main方法,用于演示如何调用这些服务。
数字提取服务(NumberExtractor)
数字提取服务(NumberExtractor)是LangChain4j框架中另一个典型的AI服务实现,它展示了如何从文本中提取不同类型的数字,并将其转换为相应的数值类型。
1. 接口定义
数字提取服务通过定义一个接口NumberExtractor来封装数字提取功能。接口中包含多个方法,每个方法对应一种数值类型:
- extractInt(String text):从文本中提取整数(int)。
- extractLong(String text):从文本中提取长整数(long)。
- extractBigInteger(String text):从文本中提取大整数(BigInteger)。
- extractFloat(String text):从文本中提取浮点数(float)。
- extractDouble(String text):从文本中提取双精度浮点数(double)。
- extractBigDecimal(String text):从文本中提取高精度浮点数(BigDecimal)。
interface NumberExtractor {
@UserMessage("Extract number from {{it}}")
int extractInt(String text);
@UserMessage("Extract number from {{it}}")
long extractLong(String text);
@UserMessage("Extract number from {{it}}")
BigInteger extractBigInteger(String text);
@UserMessage("Extract number from {{it}}")
float extractFloat(String text);
@UserMessage("Extract number from {{it}}")
double extractDouble(String text);
@UserMessage("Extract number from {{it}}")
BigDecimal extractBigDecimal(String text);
}
2. 注解的使用
@UserMessage:用于定义用户消息模板。模板中的{{it}}会被替换为方法参数(即要提取数字的文本)。这使得AI能够理解用户的意图,并生成相应的响应。
3. 动态生成服务实现
通过AiServices.create()方法,LangChain4j框架动态生成了NumberExtractor接口的实现。这意味着开发者不需要手动实现接口方法,而是由框架根据接口定义和注解自动生成实现逻辑。
NumberExtractor extractor = AiServices.create(NumberExtractor.class, chatLanguageModel);
4. 调用服务
在main方法中,通过调用NumberExtractor的各个方法,展示了如何使用该服务:
- 调用extractInt(String text)方法提取整数。
- 调用extractLong(String text)方法提取长整数。
- 调用extractBigInteger(String text)方法提取大整数。
- 调用extractFloat(String text)方法提取浮点数。
- 调用extractDouble(String text)方法提取双精度浮点数。
- 调用extractBigDecimal(String text)方法提取高精度浮点数。
String text = "After countless millennia of computation, the supercomputer Deep Thought finally announced " +
"that the answer to the ultimate question of life, the universe, and everything was forty two.";
int intNumber = extractor.extractInt(text);
System.out.println(intNumber); // 输出:42
long longNumber = extractor.extractLong(text);
System.out.println(longNumber); // 输出:42
BigInteger bigIntegerNumber = extractor.extractBigInteger(text);
System.out.println(bigIntegerNumber); // 输出:42
float floatNumber = extractor.extractFloat(text);
System.out.println(floatNumber); // 输出:42.0
double doubleNumber = extractor.extractDouble(text);
System.out.println(doubleNumber); // 输出:42.0
BigDecimal bigDecimalNumber = extractor.extractBigDecimal(text);
System.out.println(bigDecimalNumber); // 输出:42.0
5. 技术优势
封装性:通过接口和注解,将数字提取功能封装为一个服务,使得代码更加模块化,易于维护和扩展。
动态性:利用LangChain4j框架的动态生成能力,自动实现接口方法,减少了手动编码的工作量。
灵活性:通过注解定义用户消息模板,可以灵活地调整AI的输入和输出格式,适应不同的业务需求。
可扩展性:可以轻松添加更多类型的数字提取功能或扩展到其他自然语言处理任务。
类型安全:支持多种数值类型,确保提取的数字可以无缝地转换为所需的类型,避免类型转换错误。
完整代码
public class OtherServiceExamples {
// 使用OpenAI的API密钥初始化ChatLanguageModel
static ChatLanguageModel chatLanguageModel = OpenAiChatModel
.withApiKey(ApiKeys.OPENAI_API_KEY);
/**
* 数字提取服务示例
*/
static class Number_Extracting_AI_Service_Example {
// 定义数字提取接口
interface NumberExtractor {
// 提取整数
@UserMessage("Extract number from {{it}}")
int extractInt(String text);
// 提取长整数
@UserMessage("Extract number from {{it}}")
long extractLong(String text);
// 提取BigInteger
@UserMessage("Extract number from {{it}}")
BigInteger extractBigInteger(String text);
// 提取浮点数
@UserMessage("Extract number from {{it}}")
float extractFloat(String text);
// 提取双精度浮点数
@UserMessage("Extract number from {{it}}")
double extractDouble(String text);
// 提取BigDecimal
@UserMessage("Extract number from {{it}}")
BigDecimal extractBigDecimal(String text);
}
public static void main(String[] args) {
// 动态生成数字提取服务的实现
NumberExtractor extractor = AiServices.create(NumberExtractor.class, chatLanguageModel);
// 测试文本
String text = "After countless millennia of computation, the supercomputer Deep Thought finally announced " +
"that the answer to the ultimate question of life, the universe, and everything was forty two.";
// 提取不同类型的数字
int intNumber = extractor.extractInt(text);
System.out.println(intNumber); // 输出:42
long longNumber = extractor.extractLong(text);
System.out.println(longNumber); // 输出:42
BigInteger bigIntegerNumber = extractor.extractBigInteger(text);
System.out.println(bigIntegerNumber); // 输出:42
float floatNumber = extractor.extractFloat(text);
System.out.println(floatNumber); // 输出:42.0
double doubleNumber = extractor.extractDouble(text);
System.out.println(doubleNumber); // 输出:42.0
BigDecimal bigDecimalNumber = extractor.extractBigDecimal(text);
System.out.println(bigDecimalNumber); // 输出:42.0
}
}
}
代码解读
功能:
从文本中提取数字,并将其转换为不同类型的数值(int、long、BigInteger、float、double、BigDecimal)。
实现:
定义了一个NumberExtractor接口,包含多个方法,每个方法对应一种数值类型。
- 使用@UserMessage注解定义了用户消息模板。
- 通过AiServices.create()动态生成NumberExtractor的实现。
调用:
从文本中提取数字42,并将其转换为不同类型的数值。
总结
数字提取服务(NumberExtractor)通过定义接口、使用注解和动态生成服务实现,展示了LangChain4j框架的强大功能。这种实现方式不仅简化了开发流程,还提高了代码的可维护性和可扩展性。通过@UserMessage注解,AI能够理解用户意图并生成相应的响应,而动态生成的服务实现则避免了手动编写复杂的逻辑。这种模式可以广泛应用于其他自然语言处理任务,为开发者提供了一种高效、灵活的解决方案。