Embeddings Model API

Embeddings Model API (Spring AI)

텍스트를 숫자 벡터로 바꿔서 의미를 비교하고 싶을 때, Spring AI의 EmbeddingModel이 그 작업을 일관된 API로 처리해 줘요. 이 글은 임베딩이 무엇인지와 Spring AI의 Embeddings Model API를 어떻게 쓰는지 다뤄요.

임베딩(Embeddings)은 입력 간의 관계를 포착하는 텍스트, 이미지, 비디오의 숫자 표현이에요. 텍스트, 이미지, 비디오를 벡터(vector)라고 불리는 부동소수점 배열로 변환해서 동작하는데, 이 벡터들은 텍스트·이미지·비디오의 의미를 포착하도록 설계돼요. 임베딩 배열의 길이를 벡터의 차원(dimensionality)이라고 해요.

두 텍스트의 벡터 표현 사이의 숫자 거리를 계산하면, 애플리케이션은 그 벡터를 생성한 객체들 사이의 유사도를 판단할 수 있어요.

EmbeddingModel 인터페이스는 AI와 머신러닝의 임베딩 모델과의 간단한 통합을 위해 설계됐어요. 주요 기능은 텍스트를 일반적으로 임베딩이라고 불리는 숫자 벡터로 변환하는 거예요. 이 임베딩은 의미 분석(semantic analysis)과 텍스트 분류(text classification) 같은 다양한 작업에 중요해요.

EmbeddingModel 인터페이스 설계는 두 가지 주요 목표에 집중해요.

  • Portability (이식성): 이 인터페이스는 다양한 임베딩 모델에 쉽게 적응할 수 있게 해 줘요. 개발자는 최소한의 코드 변경으로 서로 다른 임베딩 기법이나 모델을 전환할 수 있어요. 이 설계는 Spring의 모듈성과 교체 가능성 철학과 일치해요.
  • Simplicity (단순성): EmbeddingModel은 텍스트를 임베딩으로 변환하는 과정을 단순화해요. embed(String text)embed(Document document) 같은 직관적인 메서드를 제공해서, 원시 텍스트 데이터와 임베딩 알고리즘을 다루는 복잡함을 없애 줘요. 이 설계는 특히 AI에 처음인 개발자가 기본 메커니즘을 깊이 파지 않고도 애플리케이션에서 임베딩을 활용하기 쉽게 해 줘요.

API 개요 (API Overview)

Embedding Model API는 Spring AI 라이브러리의 일부인 일반적인 Spring AI Model API 위에 구축돼요. 그래서 EmbeddingModel 인터페이스는 AI 모델과 상호작용하기 위한 표준 메서드 집합을 제공하는 Model 인터페이스를 확장해요. EmbeddingRequestEmbeddingResponse 클래스는 ModelRequestModelResponse에서 확장되며, 각각 임베딩 모델의 입력과 출력을 캡슐화하는 데 사용돼요.

임베딩 API는 다시 OpenAI, Titan, Ollama 등 특정 임베딩 모델을 위한 Embedding Models 구현에 사용돼요.

EmbeddingModel

다음은 EmbeddingModel 인터페이스와 관련 클래스에 대한 안내예요.

public interface EmbeddingModel extends Model<EmbeddingRequest, EmbeddingResponse> {

	@Override
	EmbeddingResponse call(EmbeddingRequest request);


	/**
	 * Embeds the given document's content into a vector.
	 * @param document the document to embed.
	 * @return the embedded vector.
	 */
	float[] embed(Document document);

	/**
	 * Extracts the text content from a Document to be used for embedding.
	 * By default, returns Document.getText(). Implementations that support
	 * MetadataMode should override this to return
	 * Document.getFormattedContent(MetadataMode) so that metadata is
	 * included in the text sent to the embedding API.
	 */
	default String getEmbeddingContent(Document document) {
		return document.getText();
	}

	/**
	 * Embeds the given text into a vector.
	 * @param text the text to embed.
	 * @return the embedded vector.
	 */
	default float[] embed(String text) {
		Assert.notNull(text, "Text must not be null");
		return this.embed(List.of(text)).iterator().next();
	}

	/**
	 * Embeds a batch of texts into vectors.
	 * @param texts list of texts to embed.
	 * @return list of list of embedded vectors.
	 */
	default List<float[]> embed(List<String> texts) {
		Assert.notNull(texts, "Texts must not be null");
		return this.call(new EmbeddingRequest(texts, EmbeddingOptions.EMPTY))
			.getResults()
			.stream()
			.map(Embedding::getOutput)
			.toList();
	}

	/**
	 * Embeds a batch of texts into vectors and returns the {@link EmbeddingResponse}.
	 * @param texts list of texts to embed.
	 * @return the embedding response.
	 */
	default EmbeddingResponse embedForResponse(List<String> texts) {
		Assert.notNull(texts, "Texts must not be null");
		return this.call(new EmbeddingRequest(texts, EmbeddingOptions.EMPTY));
	}

	/**
	 * @return the number of dimensions of the embedded vectors. It is generative
	 * specific.
	 */
	default int dimensions() {
		return embed("Test String").size();
	}

}

embed 메서드들은 텍스트를 임베딩으로 변환하는 다양한 옵션을 제공해서, 단일 문자열, 구조화된 Document 객체, 텍스트 배치를 모두 지원해요.

텍스트를 임베딩하기 위한 여러 단축(shortcut) 메서드가 제공되는데, 단일 문자열을 받아 해당 임베딩 벡터를 반환하는 embed(String text) 메서드가 있어요. 모든 단축 메서드는 임베딩 모델을 호출하는 주요 메서드인 call 메서드를 중심으로 구현돼요.

getEmbeddingContent(Document) 메서드는 임베딩 전에 Document에서 텍스트를 추출하는 방법을 제어해요. 기본적으로 Document.getText()를 반환하지만, MetadataMode를 지원하는 임베딩 모델 구현(예: OpenAI, Mistral AI)은 이 메서드를 오버라이드해서 Document.getFormattedContent(MetadataMode)를 반환하며, 구성될 때 문서 메타데이터가 임베딩 API로 전송되는 텍스트에 포함되도록 해요. 이 메서드는 벡터 스토어가 의존하는 배치 임베딩 경로에서 사용돼요.

일반적으로 임베딩은 숫자 벡터 형식의 임베딩을 나타내는 부동소수점 리스트를 반환해요.

embedForResponse 메서드는 임베딩에 대한 추가 정보를 포함할 수 있는 더 포괄적인 출력을 제공해요.

dimensions 메서드는 개발자가 임베딩 벡터의 크기를 빠르게 파악할 수 있는 편리한 도구로, 임베딩 공간을 이해하고 이후 처리 단계에 중요해요.

EmbeddingRequest

EmbeddingRequest는 텍스트 객체 목록과 선택적 임베딩 요청 옵션을 받는 ModelRequest예요. 다음 목록은 생성자와 다른 유틸리티 메서드를 제외한 EmbeddingRequest 클래스의 축약 버전이에요.

public class EmbeddingRequest implements ModelRequest<List<String>> {
	private final List<String> inputs;
	private final EmbeddingOptions options;
	// other methods omitted
}

EmbeddingResponse

EmbeddingResponse 클래스의 구조는 다음과 같아요.

public class EmbeddingResponse implements ModelResponse<Embedding> {

	private List<Embedding> embeddings;
	private EmbeddingResponseMetadata metadata = new EmbeddingResponseMetadata();
	// other methods omitted
}

EmbeddingResponse 클래스는 AI 모델의 출력을 보관하며, 각 Embedding 인스턴스는 단일 텍스트 입력의 결과 벡터 데이터를 포함해요.

EmbeddingResponse 클래스는 또한 AI 모델 응답에 대한 메타데이터인 EmbeddingResponseMetadata를 담고 있어요.

Embedding

Embedding은 단일 임베딩 벡터를 나타내요.

public class Embedding implements ModelResult<float[]> {
	private float[] embedding;
	private Integer index;
	private EmbeddingResultMetadata metadata;
	// other methods omitted
}

사용 가능한 구현 (Available Implementations)

내부적으로 다양한 EmbeddingModel 구현은 서로 다른 저수준 라이브러리와 API를 사용해서 임베딩 작업을 수행해요. 다음은 EmbeddingModel 구현 중 일부예요.

  • Spring AI OpenAI Embeddings
  • Spring AI Ollama Embeddings
  • Spring AI Transformers (ONNX) Embeddings
  • Spring AI PostgresML Embeddings
  • Spring AI Bedrock Cohere Embeddings
  • Spring AI Bedrock Titan Embeddings
  • Spring AI VertexAI Embeddings
  • Spring AI Mistral AI Embeddings

더 알아보기 (Learn more)