一、概述
1.1 类定位与核心价值
AiServices 是 LangChain4j 框架的高层核心API,用于封装底层 LLM 交互的复杂逻辑,彻底规避底层 ChatModel、ChatMessage、ChatMemory 等组件的样板代码开发。
其核心设计理念借鉴 Spring Data JPA、Retrofit 声明式编程思想:开发者只需定义Java接口,框架自动生成代理实现类,专注业务逻辑而非底层组件编排。
相较于框架早期的 Chains(遗留链路),AiServices 具备更高的灵活性、可定制性,是官方主推的 LLM 应用开发方案,全面支持对话记忆、工具调用、RAG、结构化输出、流式响应等核心能力。
1.2 核心特性总览
AiServices 一站式支持以下 LLM 应用核心能力:
- 声明式消息模板(静态/动态系统提示、用户提示)
- 会话记忆管理(全局共享记忆、多用户独立记忆)
- 工具调用(静态工具、动态工具、并发工具执行、异常容错)
- RAG 检索增强(基础检索、高阶检索增强器)
- 流式响应、结构化输出(POJO/枚举/布尔值自动解析)
- 内容自动审核、输入/输出防护栅格
- 事件监听、链路可观测、工具补偿机制
二、核心设计架构
2.1 类结构与核心成员
AiServices 为抽象构建器类,采用 Builder 设计模式,所有配置方法支持链式调用,最终通过build() 生成代理实例。
核心成员变量
AiServiceContext context:核心上下文,存储所有配置信息(模型、记忆、工具、RAG、防护规则等)contentRetrieverSet/retrievalAugmentorSet:RAG 配置互斥标记,保证同一实例仅配置一种RAG模式
工厂机制
通过静态内部类 FactoryHolder 实现 SPI 工厂加载,默认使用 DefaultAiServices 实现,支持自定义工厂扩展:
- 优先加载 SPI 配置的
AiServicesFactory - 无自定义工厂时,使用框架默认实现
DefaultAiServices
2.2 核心工作原理
- 接口定义:开发者定义纯Java接口,通过注解/方法参数声明AI能力
- 上下文初始化:通过
builder()初始化上下文,承载所有组件配置 - 代理生成:框架通过反射生成接口代理类,封装底层调用逻辑
- 请求编排:自动完成提示词渲染、记忆拼接、RAG检索、工具调用、参数转换
- 结果解析:自动将LLM原始响应解析为声明的返回类型(字符串、POJO、枚举等)
三、快速创建AI服务实例
AiServices 提供两种实例创建方式,适配简单/复杂场景
3.1 极简创建方式(静态方法)
适用于无复杂配置的基础对话场景,支持普通模型和流式模型
// 1. 普通对话模型
interface Assistant {
String chat(String userMessage);
}
// 快速创建实例
Assistant assistant = AiServices.create(Assistant.class, chatModel);
// 2. 流式对话模型(返回值必须为TokenStream)
interface StreamAssistant {
TokenStream chat(String userMessage);
}
StreamAssistant streamAssistant = AiServices.create(StreamAssistant.class, streamingChatModel);
3.2 构建器创建方式(推荐)
适用于需要配置记忆、工具、RAG、防护规则的复杂场景,支持全量自定义配置
Assistant assistant = AiServices.builder(Assistant.class)
.chatModel(chatModel) // 绑定模型
.chatMemory(memory) // 绑定会话记忆
.tools(new UserTools()) // 绑定工具
.contentRetriever(retriever) // 绑定RAG检索器
.moderationModel(moderationModel) // 绑定内容审核
.build();
四、核心配置能力详解
4.1 模型配置
AiServices 严格限制同一实例只能配置一种模型(普通对话模型/流式对话模型二选一)
chatModel(ChatModel):配置普通LLM模型,用于同步对话streamingChatModel(StreamingChatModel):配置流式LLM模型,接口返回值必须为TokenStream
基础校验规则:构建时会校验模型非空,未配置模型将抛出 illegalConfiguration 异常
4.2 提示词配置体系
支持静态注解、动态函数、消息转换器三级提示词配置,优先级:注解 > 动态提供者 > 转换器
4.2.1 系统提示配置
- 静态系统提示:
systemMessage(String)固定系统提示词 - 动态系统提示(按记忆ID):
systemMessageProvider(Function)根据会话ID动态生成提示 - 动态系统提示(全上下文):
systemMessageProviderWithContext(Function)可感知模型、请求参数上下文 - 系统提示转换器:
systemMessageTransformer全局后置修改系统提示,支持追加/覆盖内容
4.2.2 用户提示配置
支持动态用户提示模板,可通过 {{it}} 或 @V 注解绑定方法参数,实现动态Prompt渲染
4.3 会话记忆配置
解决LLM无状态问题,支持两种记忆模式,互斥配置
- 全局共享记忆:
chatMemory(ChatMemory)所有请求共用一个记忆实例,适用于单会话场景 - 多用户独立记忆:
chatMemoryProvider(ChatMemoryProvider)配合@MemoryId注解,按会话ID隔离记忆,适用于多用户场景
重要注意事项:同一 @MemoryId 不支持并发调用,会导致记忆数据错乱,框架无并发防护机制,需业务层控制
4.4 请求转换器配置
chatRequestTransformer 支持在请求发送至LLM前,动态修改完整 ChatRequest,适用场景:追加全局上下文、动态修改请求参数、统一消息预处理
- 单参数转换器:仅感知请求对象
- 双参数转换器:同时感知请求对象和会话记忆ID
4.5 内容审核配置
通过 moderationModel(ModerationModel) 配置审核模型,配合 @Moderate 注解实现方法级内容审核,检测到违规内容抛出 ModerationException
五、工具调用核心机制
AiServices 提供业界完善的工具调用能力,支持静态注册、动态工具、并发执行、异常容错、工具搜索优化
5.1 工具注册方式
- 注解式静态工具:注册带
@Tool注解的Java对象,自动解析工具方法 - 编程式工具:手动绑定
ToolSpecification和ToolExecutor - 动态工具提供者:
ToolProvider每次请求动态返回工具列表,适配动态场景
5.2 工具执行优化
- 并发执行:
executeToolsConcurrently()开启多工具并发执行,支持自定义线程池 - 最大轮次限制:
maxToolCallingRoundTrips()限制LLM工具调用轮次,防止死循环(默认100轮) - 工具搜索策略:
toolSearchStrategy延迟加载工具,减少每次请求的Token消耗
5.3 工具异常容错机制
针对工具调用全流程异常提供自定义处理器,解决LLM幻觉、参数错误、执行失败问题
- 幻觉工具处理:
hallucinatedToolNameStrategy处理LLM调用不存在工具的场景 - 参数异常处理:
toolArgumentsErrorHandler处理参数解析失败、缺失参数等问题,支持LLM自动重试 - 执行异常处理:
toolExecutionErrorHandler处理工具业务执行异常,支持脱敏错误信息,避免敏感数据泄露
5.4 工具补偿机制
compensateOnToolErrors(boolean) 开启工具故障补偿,工具执行失败时,反向执行已成功工具的补偿方法(@CompensateFor),实现事务回滚能力
5.5 工具执行回调
beforeToolExecution:工具执行前回调,可做参数校验、日志记录afterToolExecution:工具执行后回调,可做结果统计、异常监控
六、RAG检索增强能力
AiServices 原生集成RAG能力,提供两种配置模式,互斥生效,满足简单/复杂检索场景
6.1 基础检索模式
contentRetriever(ContentRetriever):快速配置检索器,框架自动封装为 DefaultRetrievalAugmentor,适用于简单的向量检索场景
6.2 高阶检索模式
retrievalAugmentor(RetrievalAugmentor):自定义检索增强器,支持查询改写、路由、重排序、内容聚合、注入等全流程自定义,适配复杂企业级RAG场景
6.3 记忆存储优化
storeRetrievedContentInChatMemory(boolean) 配置是否将RAG检索后的增强消息存入会话记忆:
- true(默认):存储增强后消息,上下文连贯,但记忆体积更大
- false:仅存储原始用户消息,减小内存占用,避免检索内容冗余堆积
七、防护栅格机制(Guardrail)
框架提供输入/输出双层防护栅格,用于风险校验、prompt注入防御、输出合规校验,优先级低于注解配置
7.1 输入防护栅格
作用于用户原始输入,校验失败直接抛出 GuardrailException,不支持重试,适用于prompt注入、非法内容拦截
支持三种配置方式:批量类配置、实例配置、数组/列表批量注入
7.2 输出防护栅格
作用于LLM最终输出,支持重试、重prompt机制,校验失败可自动重试生成合规结果,适用于输出脱敏、格式校验、内容合规检测
多防护栅格叠加时,任意一个触发重试/重prompt,所有栅格将重新校验新响应结果
八、可观测与事件监听
支持AI服务全链路事件监听,实现日志统计、链路追踪、自定义监控能力
registerListener/registerListeners:注册单/多个事件监听器unregisterListener/unregisterListeners:注销监听器,支持动态启停
可监听事件包含:服务调用开始/结束、工具执行、RAG检索、异常报错等全生命周期事件
九、工具类静态方法
9.1 消息过滤
removeToolMessages():过滤对话消息列表中的工具执行消息、工具调用请求消息,仅保留纯对话消息,用于上下文清理
9.2 审核结果校验
verifyModerationIfNeeded():异步审核结果校验,捕获审核异常,统一抛出内容违规异常,适配异步审核场景
十、核心约束与最佳实践
10.1 配置互斥约束
- 普通模型与流式模型二选一,不可同时配置
- 基础检索器(contentRetriever)与高阶检索增强器(retrievalAugmentor)二选一
- 全局记忆与多用户记忆提供者二选一
10.2 并发约束
同一 @MemoryId 禁止并发调用,框架无并发锁控制,需业务层加锁或限流,避免记忆数据错乱
10.3 版本兼容说明
maxSequentialToolsInvocations已废弃,推荐使用maxToolCallingRoundTrips- 旧版工具映射方法废弃,推荐使用
tools(List<AiServiceTool>)支持返回行为配置 - 2.0版本将调整工具异常默认处理策略,由「抛出异常」改为「返回错误信息允许LLM重试」
十一、核心能力落地示例
11.1 多用户记忆示例
// 定义带会话ID的AI接口
interface UserAssistant {
String chat(@MemoryId Long userId, @UserMessage String message);
}
// 构建多用户记忆AI服务
UserAssistant assistant = AiServices.builder(UserAssistant.class)
.chatModel(model)
.chatMemoryProvider(id -> MessageWindowChatMemory.withMaxMessages(10))
.build();
// 不同用户独立会话
assistant.chat(1L, "我叫张三");
assistant.chat(2L, "我叫李四");
11.2 工具调用异常容错示例
AiServices.builder(Assistant.class)
.chatModel(model)
.tools(new MathTools())
// 工具参数异常返回友好提示,允许LLM重试
.toolArgumentsErrorHandler((error, ctx) -> ToolErrorHandlerResult.text("参数格式错误,请重新输入"))
// 执行异常脱敏,避免泄露内部信息
.toolExecutionErrorHandler((error, ctx) -> ToolErrorHandlerResult.text("工具执行失败,请稍后重试"))
.build();