Spring AI Introduction - thought-corner/backend-roadmap GitHub Wiki

Spring AI๋ž€ ๋ฌด์—‡์ผ๊นŒ?

  • ์ž๋ฐ”, ์Šคํ”„๋ง ๊ฐœ๋ฐœ์ž๊ฐ€ ChatGPT, Claude, Gemini ๊ฐ™์€ AI ๋ชจ๋ธ๋“ค์„ ์Šคํ”„๋ง์„ ํ™œ์šฉํ•˜์—ฌ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ์Šคํ”„๋ง ๊ณต์‹ ํ”„๋ ˆ์ž„์›Œํฌ
  • Spring AI์˜ ํ•ต์‹ฌ ์—ญํ• ์€ AI ๋ชจ๋ธ๋“ค๊ณผ ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค๋ฅผ ๋งค๋„๋Ÿฝ๊ฒŒ ์—ฐ๊ฒฐํ•˜๋Š” ์ค‘๊ฐ„๋‹ค๋ฆฌ(์ธํ„ฐํŽ˜์ด์Šค) ์—ญํ• 
    • ํŒŒ์ด์ฌ๊ณผ์˜ ์—ญํ•  ๋ถ„๋‹ด : AI ๋ชจ๋ธ์˜ ํ•™์Šต ๋ฐ ์ƒ์„ฑ์€ ํŒŒ์ด์ฌ์ด ์ฃผ๋„ํ•˜์ง€๋งŒ, ์ด๋ฏธ ์™„์„ฑ๋œ AI ๋ชจ๋ธ์„ ์‹ค์ œ ์„œ๋น„์Šค(์›น, ์•ฑ)์— ๋ถ™์ด๊ณ  ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ๋ฐฑ์—”๋“œ์˜ ์˜์—ญ์ด๋‹ค.
    • ๋ณต์žกํ•œ ํ†ต์‹  ์ฝ”๋“œ ์ œ๊ฑฐ : ๊ธฐ์กด์—๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ HTTP ์š”์ฒญ ์ฝ”๋“œ๋ฅผ ์งœ์„œ AI API๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ–ˆ์œผ๋‚˜, Spring AI๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์ด๋ฅผ ๋‚ด๋ถ€์ ์œผ๋กœ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค.

์ผ๋ฐ˜ API ํ˜ธ์ถœ vs Spring AI ์ฐจ์ด์ 

  • ์ผ๋ฐ˜ API ํ˜ธ์ถœ(์ง์ ‘ ์—ฐ๋™)
    • ๋†’์€ ์ข…์†์„ฑ : OpenAI, ๊ตฌ๊ธ€, ์•คํŠธ๋กœํ”ฝ ๋“ฑ AI ๋ชจ๋ธ ์ œ๊ณต์‚ฌ๋งˆ๋‹ค API ๋ฌธ์„œ์™€ ์š”์ฒญ ์‘๋‹ต ๊ตฌ์กฐ๊ฐ€ ์ œ๊ฐ๊ฐ์ด๋‹ค.
    • ์œ ์ง€๋ณด์ˆ˜ ์ง€์˜ฅ : ChatGPT๋ฅผ ์“ฐ๋‹ค๊ฐ€ ๋น„์šฉ์ด๋‚˜ ์„ฑ๋Šฅ ๋ฌธ์ œ๋กœ Claude ๋ชจ๋ธ๋กœ ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด, ๊ธฐ์กด์— ์งœ๋†“์€ ์ž๋ฐ” ํ†ต์‹  ์ฝ”๋“œ๋ฅผ ์ „๋ถ€ ๊ฐˆ์•„์—Ž๊ณ  ์ƒˆ๋กœ ์ž‘์„ฑํ•ด์•ผํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  • Spring AI(ํ”„๋ ˆ์ž„์›Œํฌ ํ™œ์šฉ)
    • ์ถ”์ƒํ™” ์ œ๊ณต : AI ๋ชจ๋ธ ์ข…๋ฅ˜์— ์ƒ๊ด€์—†์ด ๊ฐœ๋ฐœ์ž๋Š” Spring AI๊ฐ€ ์ œ๊ณตํ•˜๋Š” ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค(ChatModel)๋งŒ ํ™œ์šฉํ•˜์—ฌ ์ฝ”๋”ฉํ•˜๋ฉด ๋œ๋‹ค.
    • ์œ ์—ฐํ•œ ๋Œ€์ฒ˜ : AI ๋ชจ๋ธ์„ ๋ณ€๊ฒฝํ•  ๋•Œ ์ž๋ฐ” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ๋‹จ ํ•œ ์ค„๋„ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ , ์„ค์ • ํŒŒ์ผ์˜ ์˜ต์…˜๋งŒ ๋ฐ”๊พธ๋ฉด ์ฆ‰์‹œ ์ „ํ™˜ ๊ฐ€๋Šฅํ•˜๋‹ค.

VectorStore Interface

/**
 * The {@code VectorStore} interface defines the operations for managing and querying
 * documents in a vector database. It extends {@link DocumentWriter} to support document
 * writing operations. Vector databases are specialized for AI applications, performing
 * similarity searches based on vector representations of data rather than exact matches.
 * This interface allows for adding, deleting, and searching documents based on their
 * similarity to a given query.
 */
public interface VectorStore extends DocumentWriter, VectorStoreRetriever {

	default String getName() {
		return this.getClass().getSimpleName();
	}

	/**
	 * Adds list of {@link Document}s to the vector store.
	 * @param documents the list of documents to store. Throws an exception if the
	 * underlying provider checks for duplicate IDs.
	 */
	void add(List<Document> documents);

	@Override
	default void accept(List<Document> documents) {
		add(documents);
	}

	/**
	 * Deletes documents from the vector store.
	 * @param idList list of document ids for which documents will be removed.
	 */
	void delete(List<String> idList);

	/**
	 * Deletes documents from the vector store based on filter criteria.
	 * @param filterExpression Filter expression to identify documents to delete
	 * @throws IllegalStateException if the underlying delete causes an exception
	 */
	void delete(Filter.Expression filterExpression);

	/**
	 * Deletes documents from the vector store using a string filter expression. Converts
	 * the string filter to an Expression object and delegates to
	 * {@link #delete(Filter.Expression)}.
	 * @param filterExpression String representation of the filter criteria
	 * @throws IllegalArgumentException if the filter expression is null
	 * @throws IllegalStateException if the underlying delete causes an exception
	 */
	default void delete(String filterExpression) {
		SearchRequest searchRequest = SearchRequest.builder().filterExpression(filterExpression).build();
		Filter.Expression textExpression = searchRequest.getFilterExpression();
		Assert.notNull(textExpression, "Filter expression must not be null");
		this.delete(textExpression);
	}

	/**
	 * Returns the native client if available in this vector store implementation.
	 *
	 * Note on usage: 1. Returns empty Optional when no native client is available 2. Due
	 * to Java type erasure, runtime type checking is not possible
	 *
	 * Example usage: When working with implementation with known native client:
	 * Optional<NativeClientType> client = vectorStore.getNativeClient();
	 *
	 * Note: Using Optional<?> will return the native client if one exists, rather than an
	 * empty Optional. For type safety, prefer using the specific client type.
	 * @return Optional containing native client if available, empty Optional otherwise
	 * @param <T> The type of the native client
	 */
	default <T> Optional<T> getNativeClient() {
		return Optional.empty();
	}

	/**
	 * Builder interface for creating VectorStore instances. Implements a fluent builder
	 * pattern for configuring observation-related settings.
	 *
	 * @param <T> the concrete builder type, enabling method chaining with the correct
	 * return type
	 */
	interface Builder<T extends Builder<T>> {

		/**
		 * Sets the registry for collecting observations and metrics. Defaults to
		 * {@link ObservationRegistry#NOOP} if not specified.
		 * @param observationRegistry the registry to use for observations
		 * @return the builder instance for method chaining
		 */
		T observationRegistry(ObservationRegistry observationRegistry);

		/**
		 * Sets a custom convention for creating observations. If not specified,
		 * {@link DefaultVectorStoreObservationConvention} will be used.
		 * @param convention the custom observation convention to use
		 * @return the builder instance for method chaining
		 */
		T customObservationConvention(VectorStoreObservationConvention convention);

		/**
		 * Sets the batching strategy.
		 * @param batchingStrategy the strategy to use
		 * @return the builder instance for method chaining
		 */
		T batchingStrategy(BatchingStrategy batchingStrategy);

		/**
		 * Builds and returns a new VectorStore instance with the configured settings.
		 * @return a new VectorStore instance
		 */
		VectorStore build();

	}

}
โš ๏ธ **GitHub.com Fallback** โš ๏ธ