跳到主要内容

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 接口的实现。

WatsonxChatModelWatsonxStreamingChatModel 以及其他服务构建器既接受通过 .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

  1. 访问 https://dataplatform.cloud.ibm.com/projects/?context=wx
  2. 打开你的项目
  3. 进入 Manage 标签页
  4. Details 部分复制 Project ID

WatsonxChatModel

WatsonxChatModel 类允许你创建完全封装在 LangChain4j 中的 ChatModel 接口实例。 要创建实例,必须指定以下必填参数:

  • baseUrl(...) – IBM Cloud 端点 URL(可为 StringURICloudRegion);
  • apiKey(...) – IBM Cloud IAM API 密钥;
  • projectId(...) – IBM Cloud Project ID(或使用 spaceId(...));
  • modelName(...) – 用于推理的基础模型 ID;

或者,你可以通过指定以下参数使用已部署的模型

  • baseUrl(...) – IBM Cloud 端点 URL(可为 StringURICloudRegion);
  • 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 时,无需指定 projectIdspaceIdmodelName,因为部署中已包含这些信息。

🔗 查看可用模型

🔗 了解更多关于按需部署模型

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 时,无需指定 projectIdspaceIdmodelName,因为部署中已包含这些信息。

🔗 查看可用模型

🔗 了解更多关于按需部署模型

工具集成

WatsonxChatModelWatsonxStreamingChatModel 都支持 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
  • 对已自动分离推理与响应的模型使用 ThinkingEffortthinking(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 状态码的最大重试次数(42950350452010
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

更多详情见此处

示例