在这篇文章中,我们将详细介绍如何使用 Spring Boot 框架集成 OpenAI 的 API,并与本地向量数据库 Chroma 集成。通过这样的集成,我们能够创建一个能够快速进行文本生成、检索和增强型搜索的系统。此架构主要应用于基于大规模文本数据的搜索、聊天机器人和自动化问答系统。

一、前提准备

  • Spring Boot:用于构建我们的后端服务。
  • OpenAI API:用于与 OpenAI 的 GPT 模型交互,生成文本、回答问题等。
  • Chroma:一个用于存储和检索向量数据的开源数据库。它支持通过向量搜索进行高效的文本匹配。

在本教程中,我们将:

  • 使用 Spring Boot 构建后端应用。
  • 使用 OpenAI API 生成文本或向量数据。
  • 使用 Chroma 进行文本嵌入的存储和向量检索。

二、项目结构

我们的项目将分为几个主要模块:

  1. Spring Boot 后端:负责提供 RESTful API。
  2. OpenAI API:调用 GPT 模型生成文本。
  3. Chroma 向量数据库:用于存储和检索文本向量。

三、步骤详解

1. 创建 Spring Boot 项目

首先,通过 Spring Initializr 创建一个新的 Spring Boot 项目,选择以下依赖:

  • Spring Web
  • Spring Boot DevTools
  • Spring Configuration Processor
  • Lombok(用于减少冗余代码)

2. 配置 OpenAI API

在 application.properties 或 application.yml 文件中配置 OpenAI 的 API 密钥。

openai.api.key=your_openai_api_key_here

在 Spring Boot 中,我们通过使用 RestTemplate 或 WebClient 来调用 OpenAI API。

3. 集成 OpenAI API

为了与 OpenAI API 进行交互,我们需要定义一个服务类来与其通信。以下是一个简单的 OpenAIService 类,使用 RestTemplate 调用 OpenAI 的 GPT 模型。

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;

@Service
public class OpenAIService {

    @Value("${openai.api.key}")
    private String openAiApiKey;

    private final RestTemplate restTemplate;

    public OpenAIService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public String generateText(String prompt) {
        String url = "https://api.openai.com/v1/completions";

        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + openAiApiKey);
        headers.set("Content-Type", "application/json");

        String payload = "{ \"model\": \"text-davinci-003\", \"prompt\": \"" + prompt + "\", \"max_tokens\": 100}";

        HttpEntity<String> entity = new HttpEntity<>(payload, headers);

        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);

        return response.getBody(); // 返回生成的文本
    }
}

4. 集成 Chroma 向量数据库

Chroma 是一个开源的向量数据库,适合用于存储和检索文本的向量表示。为了集成 Chroma,我们需要首先安装 Chroma 并通过 Python 客户端或 Java 客户端与其进行交互。

假设我们已经设置了 Chroma 数据库,可以通过一个 Python 服务(假设 Chroma 目前没有官方的 Java 客户端)来与 Java 后端进行交互。可以通过 REST API 或直接通过 Python 客户端与 Java 应用集成。

在本示例中,我们假设已经在服务器上运行了 Chroma 并通过 REST API 进行通信。

5. 配置 Chroma REST API 服务

首先,你需要安装 Chroma Python 包并启动 Chroma 服务。你可以在一个 Python 应用中运行 Chroma。

pip install chromadb

然后,启动 Chroma 服务:

import chromadb

# 初始化 Chroma 数据库
client = chromadb.Client()

# 创建一个 collection
collection = client.create_collection("documents")

# 插入文档和其向量表示
documents = [
    {"text": "OpenAI GPT is amazing!", "metadata": {"source": "article_1"}},
    {"text": "Chroma is a powerful vector database.", "metadata": {"source": "article_2"}}
]

# 假设有一个生成文本向量的函数
# 这里我们只是假设已经有了文本的向量表示
vectors = [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]]

# 插入数据
collection.add(documents=documents, embeddings=vectors)

# 检索相关文档
results = collection.query(query_embeddings=[[0.2, 0.3, 0.4]], n_results=2)
print(results)

6. 在 Spring Boot 中调用 Chroma API

通过 RestTemplate 或 WebClient 来调用我们在 Python 中实现的 Chroma API。

import org.springframework.web.client.RestTemplate;

@Service
public class ChromaService {

    private final RestTemplate restTemplate;

    public ChromaService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public String storeDocument(String documentText, List<Float> embeddingVector) {
        String chromaApiUrl = "http://localhost:5000/store_document"; // 假设 Python 服务运行在 5000 端口

        Map<String, Object> payload = new HashMap<>();
        payload.put("text", documentText);
        payload.put("embedding", embeddingVector);

        // 将数据发送到 Python 中运行的 Chroma 服务
        return restTemplate.postForObject(chromaApiUrl, payload, String.class);
    }

    public String queryDocuments(List<Float> queryVector) {
        String chromaApiUrl = "http://localhost:5000/query_documents"; // 假设查询接口存在

        Map<String, Object> payload = new HashMap<>();
        payload.put("query_vector", queryVector);

        // 获取相似的文档
        return restTemplate.postForObject(chromaApiUrl, payload, String.class);
    }
}

7. 集成到 RESTful API 中

在 Spring Boot 应用中,我们可以创建控制器来提供 RESTful API 接口,用户可以通过它来生成文本、存储文本和查询文档。

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class ChatbotController {

    private final OpenAIService openAIService;
    private final ChromaService chromaService;

    public ChatbotController(OpenAIService openAIService, ChromaService chromaService) {
        this.openAIService = openAIService;
        this.chromaService = chromaService;
    }

    @PostMapping("/generate")
    public String generateText(@RequestBody String prompt) {
        return openAIService.generateText(prompt);
    }

    @PostMapping("/store")
    public String storeDocument(@RequestBody String documentText) {
        List<Float> embedding = generateEmbedding(documentText); // 生成文档向量
        return chromaService.storeDocument(documentText, embedding);
    }

    @PostMapping("/query")
    public String queryDocuments(@RequestBody List<Float> queryVector) {
        return chromaService.queryDocuments(queryVector);
    }

    // 假设这里是通过 OpenAI API 或其他工具生成的向量
    private List<Float> generateEmbedding(String text) {
        return Arrays.asList(0.1f, 0.2f, 0.3f); // 假定的向量
    }
}

四、总结

通过结合 Spring BootOpenAI API 和 Chroma 向量数据库,我们构建了一个强大的系统来实现智能文本生成和高效的文本检索。这个架构非常适合构建智能聊天机器人、搜索引擎或基于大规模文本的问答系统。

  • Spring Boot 提供了快速构建后端的能力。
  • OpenAI API 使得我们能够利用 GPT 模型进行文本生成。
  • Chroma 提供了一个快速、有效的方式来存储和查询文本的向量表示。

通过这种方式,我们能够将 OpenAI 的强大自然语言处理能力与 Chroma 高效的向量检索结合,实现更智能的应用场景。如果你有更多问题或需要进一步的实现细节,欢迎随时联系!