watsonx.ai
Maven 依赖
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-watsonx</artifactId>
<version>1.18.1-beta28</version>
</dependency>
认证
Watsonx.ai 通过 Authenticator 接口支持认证。
这使你可以根据部署方式使用不同的认证机制:
- IBMCloudAuthenticator – 使用 API 密钥向 IBM Cloud 认证。这是最简单的方式,当你提供
apiKey(...)构建器方法时就会使用它。 - CP4DAuthenticator – 向 Cloud Pak for Data 部署进行认证。
- 自定义认证器 – 可以使用任何
Authenticator接口的实现。
WatsonxChatModel、WatsonxStreamingChatModel 以及其他服务构建器既接受通过 .apiKey(...) 的快捷方式,也接受通过 .authenticator(...) 传入完整的 Authenticator 实例。
示例
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.watsonx.WatsonxChatModel;
import com.ibm.watsonx.ai.core.auth.cp4d.CP4DAuthenticator;
import com.ibm.watsonx.ai.core.auth.cp4d.AuthMode;
import com.ibm.watsonx.ai.CloudRegion;
WatsonxChatModel.builder()
.baseUrl(CloudRegion.FRANKFURT)
.apiKey("your-api-key") // Simple IBM Cloud authentication
.projectId("your-project-id")
.modelName("ibm/granite-4-h-small")
.build();
WatsonxChatModel.builder()
.baseUrl("https://my-instance-url")
.authenticator( // For Cloud Pak for Data deployments
CP4DAuthenticator.builder()
.baseUrl("https://my-instance-url")
.username("username")
.apiKey("api-key")
.authMode(AuthMode.LEGACY)
.build()
)
.projectId("my-project-id")
.modelName("ibm/granite-4-h-small")
.build();
自定义 HttpClient 与 SSL 配置
使用自定义 HttpClient
所有服务与认证器都通过构建器模式支持自定义 HttpClient 实例。这在 Cloud Pak for Data 环境中尤其有用,因为你可能需要配置自定义 TLS/SSL 设置、代理配置或其他 HTTP 客户端属性。
HttpClient httpClient = HttpClient.newBuilder()
.sslContext(createCustomSSLContext())
.executor(ExecutorProvider.ioExecutor())
.build();
EmbeddingModel embeddingModel = WatsonxEmbeddingModel.builder()
.baseUrl("https://my-instance-url")
.modelName("ibm/granite-embedding-278m-multilingual")
.projectId("project-id")
.httpClient(httpClient) // Custom HttpClient
.authenticator(
CP4DAuthenticator.builder()
.baseUrl("https://my-instance-url")
.username("username")
.apiKey("api-key")
.httpClient(httpClient) // Custom HttpClient
.build()
)
.build();
注意: 在 Cloud Pak for Data 中使用自定义
HttpClient时,请务必在服务构建器与认证器构建器上都设置它,以确保所有请求的 HTTP 行为一致。
禁用 SSL 验证
如果你只需要禁用 SSL 证书验证,可以使用 verifySsl(false) 选项,而无需提供自定义 HttpClient:
EmbeddingModel embeddingModel = WatsonxEmbeddingModel.builder()
.baseUrl("https://my-instance-url")
.modelName("ibm/granite-embedding-278m-multilingual")
.projectId("project-id")
.verifySsl(false) // Disable SSL verification
.authenticator(
CP4DAuthenticator.builder()
.baseUrl("https://my-instance-url")
.username("username")
.apiKey("api-key")
.verifySsl(false) // Disable SSL verification
.build()
)
.build();
如何创建 IBM Cloud API 密钥
你可以在 https://cloud.ibm.com/iam/apikeys 通过点击 Create + 创建 API 密钥。
如何查找你的 Project ID
- 访问 https://dataplatform.cloud.ibm.com/projects/?context=wx
- 打开你的项目
- 进入 Manage 标签页
- 从 Details 部分复制 Project ID
WatsonxChatModel
WatsonxChatModel 类允许你创建完全封装在 LangChain4j 中的 ChatModel 接口实例。
要创建实例,必须指定以下必填参数:
baseUrl(...)– IBM Cloud 端点 URL(可为String、URI或CloudRegion);apiKey(...)– IBM Cloud IAM API 密钥;projectId(...)– IBM Cloud Project ID(或使用spaceId(...));modelName(...)– 用于推理的基础模型 ID;
或者,你可以通过指定以下参数使用已部署的模型:
baseUrl(...)– IBM Cloud 端点 URL(可为String、URI或CloudRegion);apiKey(...)– IBM Cloud IAM API 密钥;deploymentId(...)– 按需部署模型的 Deployment ID;
你可以使用
.apiKey(...)或通过.authenticator(...)传入完整的Authenticator实例进行认证。
示例
使用目录中的基础模型
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.watsonx.WatsonxChatModel;
import com.ibm.watsonx.ai.CloudRegion;
ChatModel chatModel = WatsonxChatModel.builder()
.baseUrl(CloudRegion.FRANKFURT)
.apiKey("your-api-key")
.projectId("your-project-id")
.modelName("ibm/granite-4-h-small")
.temperature(0.7)
.maxOutputTokens(0)
.build();
String answer = chatModel.chat("Hello from watsonx.ai");
System.out.println(answer);
使用已部署的模型(按需部署)
IBM watsonx.ai 允许你在专用硬件上按需部署基础模型,供组织独占使用。这些已部署的模型可通过其 deploymentId 访问。
import dev.langchain4j.model.chat.ChatModel;
import dev.langchain4j.model.watsonx.WatsonxChatModel;
import com.ibm.watsonx.ai.CloudRegion;
ChatModel chatModel = WatsonxChatModel.builder()
.baseUrl(CloudRegion.FRANKFURT)
.apiKey("your-api-key")
.deploymentId("your-deployment-id")
.temperature(0.7)
.maxOutputTokens(0)
.build();
String answer = chatModel.chat("Hello from watsonx.ai");
System.out.println(answer);
注意: 使用
deploymentId时,无需指定projectId、spaceId或modelName,因为部署中已包含这些信息。
🔗 查看可用模型
WatsonxStreamingChatModel
WatsonxStreamingChatModel 在 LangChain4j 中为 IBM watsonx.ai 提供流式支持。当你希望在 token 生成时即时处理它们时很有用,非常适合聊天 UI 或长文本生成等实时应用。
流式使用与非流式 WatsonxChatModel 相同的配置结构和参数。主要区别在于响应通过处理器接口增量交付。
示例
使用目录中的基础模型
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.StreamingChatResponseHandler;
import dev.langchain4j.model.chat.ChatResponse;
import dev.langchain4j.model.watsonx.WatsonxStreamingChatModel;
import com.ibm.watsonx.ai.CloudRegion;
StreamingChatModel model = WatsonxStreamingChatModel.builder()
.baseUrl(CloudRegion.FRANKFURT)
.apiKey("your-api-key")
.projectId("your-project-id")
.modelName("ibm/granite-4-h-small")
.maxOutputTokens(0)
.build();
model.chat("What is the capital of Italy?", new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String partialResponse) {
System.out.println("Partial: " + partialResponse);
}
@Override
public void onCompleteResponse(ChatResponse completeResponse) {
System.out.println("Complete: " + completeResponse);
}
@Override
public void onError(Throwable error) {
error.printStackTrace();
}
});
使用已部署的模型(按需部署)
import dev.langchain4j.model.chat.StreamingChatModel;
import dev.langchain4j.model.chat.StreamingChatResponseHandler;
import dev.langchain4j.model.chat.ChatResponse;
import dev.langchain4j.model.watsonx.WatsonxStreamingChatModel;
import com.ibm.watsonx.ai.CloudRegion;
StreamingChatModel model = WatsonxStreamingChatModel.builder()
.baseUrl(CloudRegion.FRANKFURT)
.apiKey("your-api-key")
.deploymentId("your-deployment-id")
.maxOutputTokens(0)
.build();
model.chat("What is the capital of Italy?", new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String partialResponse) {
System.out.println("Partial: " + partialResponse);
}
@Override
public void onCompleteResponse(ChatResponse completeResponse) {
System.out.println("Complete: " + completeResponse);
}
@Override
public void onError(Throwable error) {
error.printStackTrace();
}
});
注意: 使用
deploymentId时,无需指定projectId、spaceId或modelName,因为部署中已包含这些信息。
🔗 查看可用模型
工具集成
WatsonxChatModel 和 WatsonxStreamingChatModel 都支持 LangChain4j Tools,允许模型调用带有 @Tool 注解的 Java 方法。
下面是使用同步模型(WatsonxChatModel)的示例,相同方法也适用于流式变体。
static class Tools {
@Tool
LocalDate currentDate() {
return LocalDate.now();
}
@Tool
LocalTime currentTime() {
return LocalTime.now();
}
}
interface AiService {
String chat(String userMessage);
}
ChatModel chatModel = WatsonxChatModel.builder()
.baseUrl(CloudRegion.FRANKFURT)
.apiKey("your-api-key")
.projectId("your-project-id")
.modelName("mistralai/mistral-small-3-1-24b-instruct-2503")
.maxOutputTokens(0)
.build();
AiService aiService = AiServices.builder(AiService.class)
.chatModel(model)
.tools(new Tools())
.build();
String answer = aiService.chat("What is the date today?");
System.out.println(answer);
注意: 请确保所选模型支持工具使用。
启用思考 / 推理输出
一些基础模型可以在响应中包含内部推理(也称为思考)步骤。
根据模型的不同,该推理可能嵌入在与最终响应相同的文本中,或从 watsonx.ai 以专用字段单独返回。
要正确启用并捕获此行为,必须根据模型的输出格式配置 thinking(...) 构建器方法。
这可确保 LangChain4j 能够自动从模型输出中提取推理与响应内容。
有两种主要配置模式:
ExtractionTags→ 用于在同一文本块中返回推理与响应的模型(例如 ibm/granite-3-3-8b-instruct)。ThinkingEffort→ 用于已自动分离推理与响应的模型(例如 openai/gpt-oss-120b)。
在同一文本中返回推理与响应的模型
当模型在同一文本字符串中输出推理与响应时,使用 ExtractionTags。
这些标签定义用于将推理与最终响应分离的类 XML 标记。
示例标签:
- 推理标签:
<think>— 包含模型的内部推理。 - 响应标签:
<response>— 包含面向用户的答案。
行为
- 如果指定了两个标签,则直接用它们提取推理与响应片段。
- 如果仅指定推理标签,则该标签之外的所有内容被视为响应。
ibm/granite-3-3-8b-instruct 示例
ChatModel chatModel = WatsonxChatModel.builder()
.baseUrl(CloudRegion.FRANKFURT)
.apiKey("your-api-key")
.projectId("your-project-id")
.modelName("ibm/granite-3-3-8b-instruct")
.maxOutputTokens(0)
.thinking(ExtractionTags.of("think", "response"))
.build();
ChatResponse chatResponse = chatModel.chat(
UserMessage.userMessage("Why is the sky blue?")
);
AiMessage aiMessage = chatResponse.aiMessage();
System.out.println(aiMessage.thinking());
System.out.println(aiMessage.text());
分别返回推理与响应的模型
对于已将推理与响应作为独立字段返回的模型,使用 ThinkingEffort 来控制模型在生成过程中应用的推理量。
或者,使用布尔标志启用它。
openai/gpt-oss-120b 示例
ChatModel chatModel = WatsonxChatModel.builder()
.baseUrl(CloudRegion.DALLAS)
.apiKey("your-api-key")
.projectId("your-project-id")
.modelName("openai/gpt-oss-120b")
.thinking(ThinkingEffort.HIGH)
.build();
或
ChatModel chatModel = WatsonxChatModel.builder()
.baseUrl(CloudRegion.DALLAS)
.apiKey("your-api-key")
.projectId("your-project-id")
.modelName("openai/gpt-oss-120b")
.thinking(true)
.build();
流式示例
StreamingChatModel model = WatsonxStreamingChatModel.builder()
.baseUrl(CloudRegion.FRANKFURT)
.apiKey("your-api-key")
.projectId("your-project-id")
.modelName("ibm/granite-3-3-8b-instruct")
.thinking(ExtractionTags.of("think", "response"))
.build();
List<ChatMessage> messages = List.of(
UserMessage.userMessage("Why is the sky blue?")
);
ChatRequest chatRequest = ChatRequest.builder()
.messages(messages)
.build();
model.chat(chatRequest, new StreamingChatResponseHandler() {
@Override
public void onPartialResponse(String partialResponse) {
...
}
@Override
public void onPartialThinking(PartialThinking partialThinking) {
...
}
});
说明:
- 请确保所选模型支持推理输出。
- 对在单个文本字符串中嵌入推理与响应的模型使用
ExtractionTags。- 对已自动分离推理与响应的模型使用
ThinkingEffort或thinking(true)。
WatsonxModelCatalog
WatsonxModelCatalog 提供了一种以编程方式发现并列出 IBM watsonx.ai 上所有可用基础模型的方法。
它实现了 LangChain4j 的 ModelCatalog 接口,允许你检索每个模型的详细信息。
示例
import dev.langchain4j.model.catalog.ModelCatalog;
import dev.langchain4j.model.catalog.ModelDescription;
import dev.langchain4j.model.watsonx.WatsonxModelCatalog;
import com.ibm.watsonx.ai.CloudRegion;
ModelCatalog modelCatalog = WatsonxModelCatalog.builder()
.baseUrl(CloudRegion.FRANKFURT)
.build();
var models = modelCatalog.listModels();
WatsonxModerationModel
WatsonxModerationModel 提供了使用 IBM watsonx.ai 的 LangChain4j ModerationModel 接口实现。
它允许你通过**检测器(detectors)**自动检测并标记文本中敏感、不安全或违反策略的内容。
可以使用一个或多个检测器来识别不同类型的内容,例如:
- Pii – 检测个人身份信息(例如邮箱、电话号码)
- Hap – 检测仇恨、滥用或脏话
- GraniteGuardian – 检测有风险或有害的语言
示例
ModerationModel model = WatsonxModerationModel.builder()
.baseUrl(CloudRegion.FRANKFURT)
.apiKey("your-api-key")
.projectId("your-project-id")
.detectors(Hap.ofDefaults(), GraniteGuardian.ofDefaults())
.build();
Response<Moderation> response = model.moderate("...");
元数据
每个审核响应都包含一个 metadata 映射,提供有关检测的额外上下文。
| 键 | 说明 |
|---|---|
detection | 检测器分配的检测到的标签或类别 |
detection_type | 触发标记的检测器类型 |
start | 检测到的片段的起始字符索引 |
end | 检测到的片段的结束字符索引 |
score | 检测的置信度分数 |
这些元数据值可通过 Response.metadata() 获取:
Map<String, Object> metadata = response.metadata();
System.out.println("Detection type: " + metadata.get("detection_type"));
System.out.println("Score: " + metadata.get("score"));
通过环境变量配置
LangChain4j watsonx 集成允许通过环境变量自定义内部 HTTP 行为。
这些设置是可选的,未显式定义变量时会使用合理的默认值。
重试配置
HTTP 请求在瞬时失败或认证令牌过期时会自动重试。
可以使用以下环境变量自定义重试行为:
| 环境变量 | 说明 | 默认值 |
|---|---|---|
WATSONX_RETRY_TOKEN_EXPIRED_MAX_RETRIES | 认证令牌过期时的最大重试次数(HTTP 401 / 403) | 1 |
WATSONX_RETRY_STATUS_CODES_MAX_RETRIES | 瞬时 HTTP 状态码的最大重试次数(429、503、504、520) | 10 |
WATSONX_RETRY_STATUS_CODES_BACKOFF_ENABLED | 为瞬时重试启用指数退避 | true |
WATSONX_RETRY_STATUS_CODES_INITIAL_INTERVAL_MS | 初始重试间隔(毫秒,用作指数退避的基数) | 20 |
HTTP IO 执行器配置
流式响应与 HTTP 响应处理由内部 IO 执行器处理。
默认使用单线程执行器,以确保流式事件的顺序处理。
可以使用以下环境变量自定义此行为:
| 环境变量 | 说明 | 默认值 |
|---|---|---|
WATSONX_IO_EXECUTOR_THREADS | 用于 HTTP IO 与 SSE 流解析的线程数 | 1 |
Quarkus
更多详情见此处。