LangChain4j AiServices 机制详解:快速构建智能体应用
1. 引言
在前面的文章中,我们深入探讨了 LangChain4j 中的 Tools 机制,了解了如何让大模型调用本地方法。然而,在实际开发中,我们往往需要将 ChatLanguageModel、ChatMessage、ChatMemory、Tools 等多个组件整合起来,才能构建一个功能完整的智能体应用。如果每次都要手动编排这些组件,开发效率会非常低下。
LangChain4j 提供了一个强大的上层抽象——AiServices,它通过代理模式,将这些基础组件无缝整合,让我们能够以极低的代码量快速构建出功能强大的 AI 服务。本文将带你从零开始,一步步掌握 AiServices 的核心用法,并深入其源码,理解其背后的工作原理。
2. 什么是 AiServices?
简单来说,AiServices 是 LangChain4j 提供的一个服务构建器,它允许你通过定义一个 Java 接口来描述 AI 服务的行为,然后自动生成该接口的代理实现。这个代理对象会负责与大模型进行交互,并自动处理消息的组装、记忆的管理以及工具的调用。
核心优势:
- 极简开发:通过接口定义,告别繁琐的底层 API 调用。
- 组件整合:轻松整合
ChatMemory、Tools、SystemMessage等核心组件。 - 多用户支持:内置对多用户会话隔离的支持。
3. 快速入门:构建你的第一个 AiServices 代理
让我们从一个最简单的例子开始。假设我们想让大模型扮演一个作家,根据给定的题目写一篇短文。
首先,定义一个接口:
interface Writer {
String write(String topic);
}
然后,使用 AiServices 创建代理并调用:
ChatLanguageModel model = ModelUtil.getZhipuAIModel(); // 获取模型,过程略
Writer writer = AiServices.create(Writer.class, model);
String content = writer.write("我最感谢的人");
System.out.println(content);
运行这段代码,大模型就会根据“我最感谢的人”这个题目,生成一篇短文。这就是 AiServices 的第一个作用:通过接口代理,快速完成与大模型的交互。
4. 进阶用法:整合核心组件
上面的例子虽然简单,但生成的作文往往比较粗糙。接下来,我们将逐步整合 @SystemMessage、ChatMemory 和 Tools,让我们的“作家”变得更智能。
4.1 通过 @SystemMessage 增加系统提示词
为了让大模型更好地理解我们的需求,我们可以通过 @SystemMessage 注解来设定系统提示词。
interface Writer {
@SystemMessage("你是一名作家,根据输入的题目写一篇200字以内的作文")
String write(String topic);
}
这样,每次调用 write() 方法时,LangChain4j 都会自动将 SystemMessage 和用户输入的 UserMessage 组合发送给大模型,从而得到更符合预期的结果。
你还可以通过 @V 注解,让系统提示词支持动态参数:
interface Writer {
@SystemMessage("你是一名作家,写一篇作文,题目是{{title}},字数不超过{{count}}个字")
String write(@UserMessage String message, @V("title") String title, @V("count") Long count);
}
注意:当方法参数使用了 @V 注解后,必须有一个参数带有 @UserMessage 注解,或者方法只有一个参数时,该参数默认作为 UserMessage 处理。
4.2 整合 ChatMemory 和 Tools
AiServices 提供了一个 Builder 组件,可以方便地整合 ChatMemory 和 Tools。
interface Assistant {
String chat(@MemoryId Long userId, @UserMessage String message);
}
@Tool("获取当前日期")
public static String dateUtil() {
return LocalDateTime.now().toString();
}
public static void main(String[] args) {
ChatLanguageModel model = ModelUtil.getZhipuAIModel();
ChatMemory chatMemory = MessageWindowChatMemory.withMaxMessages(10);
ToolSpecification toolSpecification = ToolSpecifications.toolSpecificationFrom(
UserAiService.class.getMethod("dateUtil")
);
Assistant assistant = AiServices.builder(Assistant.class)
.chatLanguageModel(model)
.chatMemoryProvider(memoryId -> MessageWindowChatMemory.withMaxMessages(10))
.tools(toolSpecification)
.build();
// 与用户1的交互
System.out.println(">>>" + assistant.chat(1L, "你好,我是楼兰"));
System.out.println(">>>" + assistant.chat(1L, "我的名字是什么"));
// 与用户2的交互
System.out.println(">>>" + assistant.chat(2L, "你好,我是老王"));
System.out.println(">>>" + assistant.chat(2L, "我的名字是什么"));
}
关键点:
@MemoryId:用于标识不同的用户会话。AiServices会根据memoryId自动管理不同用户的聊天记录,实现多用户隔离。chatMemoryProvider:相比于直接设置chatMemory,使用chatMemoryProvider可以更灵活地为每个用户创建独立的记忆空间。
5. AiServices 重点源码解读
理解源码有助于我们更好地掌握 AiServices 的细节。其核心在于 JDK 动态代理。
5.1 代理对象的创建
AiServices 创建服务接口代理对象的核心方法在 DefaultAiServices 中,它通过 JDK 的 Proxy.newProxyInstance 创建接口代理。
// dev.langchain4j.service.DefaultAiServices#build
Object proxyInstance = Proxy.newProxyInstance(
context.aiServiceClass.getClassLoader(),
new Class<?>[]{context.aiServiceClass},
new InvocationHandler() {
// 核心业务方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// ... 处理 @SystemMessage, @UserMessage, ChatMemory, Tools 等
}
}
);
5.2 核心执行流程
当调用代理对象的方法时,InvocationHandler 的 invoke 方法会被触发,其大致流程如下:
- 解析注解:解析方法上的
@SystemMessage、@UserMessage、@V等注解,以及参数上的@MemoryId、@V等注解。 - 构建消息:根据注解和传入的参数,构建
SystemMessage和UserMessage对象。 - 管理记忆:根据
@MemoryId从ChatMemoryProvider中获取或创建对应的ChatMemory对象,并将历史消息加载到上下文中。 - 准备工具:获取通过
Builder注册的ToolSpecification列表。 - 调用模型:将消息、记忆和工具信息一并发送给
ChatLanguageModel。 - 处理工具调用:如果模型返回了工具调用请求,则执行对应的本地方法,并将结果作为新的消息再次发送给模型,直到模型返回最终文本结果。
- 保存记忆:将本次交互的消息保存到
ChatMemory中。 - 返回结果:将模型的最终文本结果返回给调用方。
6. 总结
AiServices 是 LangChain4j 框架中一个极其重要的组件,它通过代理模式极大地简化了 AI 应用的开发流程。通过本文的学习,你应该已经掌握了:
- 如何使用
AiServices.create()快速创建 AI 代理。 - 如何通过
@SystemMessage和@V注解定制提示词。 - 如何使用
Builder整合ChatMemory和Tools,并实现多用户会话隔离。 - AiServices 基于 JDK 动态代理的核心工作原理。
掌握了 AiServices,你就拥有了快速构建复杂智能体应用的利器。你可以将生成的代理对象保存到 Spring 的 IOC 容器中,轻松构建出功能完整的 AI 服务。
更多推荐
所有评论(0)