1. 概述

本文将带你完整走一遍 OpenAI Java 客户端的集成流程。我们将从环境配置、API 认证开始,逐步演示如何与 OpenAI 模型交互实现文本生成和 AI 任务驱动功能。

2. 依赖配置

首先需要添加项目依赖,在 Maven 仓库中找到相关库:

<dependency>
    <groupId>com.openai</groupId>
    <artifactId>openai-java</artifactId>
    <version>0.22.0</version>
</dependency>

3. 学习助手场景

我们将构建一个基于 Baeldung 网站资源的个性化学习路径生成工具。互联网资源虽多,但组织成系统学习路径却很困难,学习新主题时容易陷入信息过载。

为解决此问题,我们开发一个简单的 ChatGPT 交互客户端,它能帮你高效筛选 Baeldung 海量文章,根据学习目标提供精准推荐。

4. API 令牌获取

获取 API 令牌是连接 OpenAI 的第一步,这个密钥用于认证所有 API 请求。

登录 OpenAI 账户后,在 API 设置页面 创建新密钥:

OpenAI 生成新密钥

获取令牌后,在 Java 应用中安全使用它(避免硬编码)。开发时可通过 IDE 环境变量配置(如 IntelliJ IDEA),生产环境建议使用专业密钥管理工具(如 AWS Secrets Manager、HashiCorp Vault 或 Azure Key Vault)。

⚠️ 令牌类型说明

  • 个人令牌:用于个人开发
  • 服务账户令牌:用于机器人或应用集成 (本示例使用个人令牌足够)

5. 初始化 OpenAIClient

将令牌设置到环境变量后,初始化客户端实例:

OpenAIClient client = OpenAIOkHttpClient.fromEnv();

现在我们有了客户端,接下来探索 Completion 和 Assistants 两种 API。

6. Completion API 与 Assistants API 对比

先理解两种核心 API 的差异,以便选择合适方案:

Completion API 适用场景

  • 短文本生成(如代码片段、内容段落)
  • 单轮问答(特定问题→简洁答案)
  • 快速任务处理

Assistants API 适用场景

  • 复杂多轮对话(如整本书编写、软件开发)
  • 需要长期上下文维护的任务
  • 需要工具集成(文件搜索、代码解释器、函数调用)

简单说:Completion API 适合"快问快答",Assistants API 适合"长期项目"。

7. 简单 Completion 实现

使用 Completion API 时,通过 ChatCompletionCreateParams 构建请求。基础配置只需模型和消息列表,但也可调整温度、最大令牌等参数:

Builder createParams = ChatCompletionCreateParams.builder()
  .model(ChatModel.GPT_4O_MINI)
  .addDeveloperMessage("你正在帮我创建编程学习课程,仅使用 www.baeldung.com 的文章")
  .addUserMessage(userMessage);

也可直接传入 ChatCompletionMessageParam 实例或 JSON 格式消息。

简单 Completion 的使用很直接:AI 处理消息后返回文本流,我们直接打印输出:

client.chat()
  .completions()
  .create(createParams.build())
  .choices()
  .stream()
  .flatMap(choice -> choice.message()
    .content()
    .stream())
  .forEach(System.out::println);

8. 对话式 Completion

对话功能支持持续交互,直到用户主动退出。保持相同模型和消息结构,但增加循环逻辑:

do {

    List<ChatCompletionMessage> messages = client.chat()
      .completions()
      .create(createParamsBuilder.build())
      .choices()
      .stream()
      .map(ChatCompletion.Choice::message)
      .toList();

    messages.stream()
      .flatMap(message -> message.content().stream())
      .forEach(System.out::println);

    System.out.println("-----------------------------------");
    System.out.println("还有其他问题吗?输入 EXIT 退出程序");

    String userMessageConversation = scanner.next();

    if ("exit".equalsIgnoreCase(userMessageConversation)) {
      scanner.close();
      return;
    }

    messages.forEach(createParamsBuilder::addMessage);
    createParamsBuilder
      .addDeveloperMessage("继续遵循相同规则提供帮助")
      .addUserMessage(userMessageConversation);

} while (true);

9. Assistants API 实现

现在看如何使用 Assistant 类(需基础参数)。Assistant 支持文件搜索、代码解释器、函数调用等高级工具

初始化步骤

  1. 创建 Assistant(指定名称、模型、指令)
  2. 创建 Thread(对话线程)
  3. 添加用户消息到 Thread
  4. 创建 Run(执行任务)
Assistant assistant = client.beta()
  .assistants()
  .create(BetaAssistantCreateParams.builder()
    .name("Baeldung 导师")
    .instructions("你是一位专业的编程学习导师,擅长研究在线课程")
    .model(ChatModel.GPT_4O_MINI)
    .build());

Thread thread = client.beta()
  .threads()
  .create(BetaThreadCreateParams.builder().build());

client.beta()
  .threads()
  .messages()
  .create(BetaThreadMessageCreateParams.builder()
    .threadId(thread.id())
    .role(BetaThreadMessageCreateParams.Role.USER)
    .content("我想学习字符串相关知识")
    .build());

Run run = client.beta()
  .threads()
  .runs()
  .create(BetaThreadRunCreateParams.builder()
    .threadId(thread.id())
    .assistantId(assistant.id())
    .instructions("你正在帮我创建编程学习课程,仅使用 www.baeldung.com 的文章")
    .build());

关键概念说明

  • Thread:用户与 Assistant 的对话序列(维护上下文)
  • Run:Assistant 处理输入并生成响应的执行实例

轮询等待任务完成(状态从 QUEUED/IN_PROGRESS 变为 COMPLETED):

while (run.status().equals(RunStatus.QUEUED) ||
  run.status().equals(RunStatus.IN_PROGRESS)) {
    System.out.println("轮询任务状态...");
    java.lang.Thread.sleep(500);
    run = client.beta()
      .threads()
      .runs()
      .retrieve(BetaThreadRunRetrieveParams.builder()
        .threadId(thread.id())
        .runId(run.id())
        .build());
}

状态变为 COMPLETED 后处理响应

System.out.println("任务完成,状态: " + run.status() + "\n");

if (!run.status().equals(RunStatus.COMPLETED)) {
  return;
}

BetaThreadMessageListPage page = client.beta()
  .threads()
  .messages()
  .list(BetaThreadMessageListParams.builder()
    .threadId(thread.id())
    .order(BetaThreadMessageListParams.Order.ASC)
    .build());

page.autoPager()
  .stream()
  .forEach(currentMessage -> {
    System.out.println(currentMessage.role());
    currentMessage.content()
      .stream()
      .flatMap(content -> content.text().stream())
      .map(textBlock -> textBlock.text().value())
      .forEach(System.out::println);
    System.out.println();
  });

autoPager() 方法自动处理分页响应,避免手动翻页。

最后清理资源(删除 Assistant 或复用 ID):

AssistantDeleted assistantDeleted = client.beta()
  .assistants()
  .delete(BetaAssistantDeleteParams.builder()
    .assistantId(assistant.id())
    .build());

System.out.println("Assistant 已删除: " + assistantDeleted.deleted());

⚠️ 注意:带 Beta 前缀的类表示实验性功能,生产环境需谨慎使用。

10. 总结

将 OpenAI API 集成到 Java 应用能显著提升生产力和学习效率。通过自动化工作流和智能交互,为 AI 创新开辟了新路径。

后续可探索

这些框架提供了更高级的抽象,简化了 Java 中 LLM 的开发,同时降低对单一供应商的依赖。


原始标题:The OpenAI API Java Client | Baeldung