버전 : 1.0.0M5
기본 샘플
OpenAiChatOptions options = OpenAiChatOptions.builder() .model(OpenAiApi.ChatModel.GPT_4_O_MINI)// 모델 설정 .temperature(0.7)// 창의성 조절 .maxTokens(500)// 최대 응답 길이 .topP(0.9)// 다채로운 응답을 위한 설정 .build(); return Map.of( "completion", Objects.requireNonNull(chatClient.prompt() .options(options) .user(request.question()) .call() .content()));
모델 선택
Name of the OpenAI chat model to use. You can select between models such as: gpt-4o, gpt-4o-mini, gpt-4-turbo, gpt-3.5-turbo, and more. See the models page for more information.
SpringBoot 디폴트로 모델 추가
properties : spring.ai.openai.chat.options.model 또는
spring: ai: openai: api-key: ${OPEN_API_KEY} chat: options: model: gpt-4o-mini
프롬프트
역할
모델은 대화 역할에 따라 메세지 범주를 구분함
- User : 사용자 입력 메세지
- 사용자의 질문이나 요청 전달
- AI에게 새로운 정보를 입력하는 경우
- Assistant : AI가 생성한 응답
- AI가 생성한 응답 메세지 - 일반적으로 직접 사용하지 않고 AI가 자동으로 생성하는 메세지에 사용됨
- 이전 AI 응답을 대화 이력(Context)으로 추가할 때, AI의 진행 상태를 기록할 때 사용
- AI가 스스로 역할을 수행하는 멀티턴 대화 시스템을 만들 때 사용
- System : AI 행동 지침
- AI의 행동을 조절한 지침(Instruction) 제공
- 응답 스타일, 제공해야 할 메세지 우선순위, 말투, 톤 등의 행동 가이드 지정
- 예시 : AI가 격식을 차린 문장을 사용하도록 설정하거나 짧게 응답하도록 제한, 또는 특정 스타일을 따르도록 강제 (예: “너는 프로그래밍 강사야.”)
- Tool : AI와 외부 시스템 연동
- AI가 외부 API, 데이터베이스 또는 다른 기능을 호출해야 할 때 사용
- AI가 외부 시스템(날씨 API, 주식 가격, DB 조회 등)과 상호작용할 때/AI가 계산, 검색 등의 기능을 수행할 때 사용
프롬프트 템플릿
public interface PromptTemplateActions extends PromptTemplateStringActions { Prompt create(); Prompt create(ChatOptions modelOptions); Prompt create(Map<String, Object> model); Prompt create(Map<String, Object> model, ChatOptions modelOptions); }
- create();
- 외부 데이터 입력 없이 객체 생성, 정적 또는 미리 정의된 프롬프트에 적합
- create(ChatOptions modelOptions);
- 외부 데이터 입력 없이 채팅 요청에 대한 특정 옵션을 포함하는 객체 생성
- create(Map<String, Object> model);
- 프롬프트 생성 기능 확장, 통적 콘텐츠를 포함하고 Map<String, Object>각 맵 항목이 프롬프트 템플릿의 플레이스홀더이고 연관된 동적 값을 갖도록 함
- create(Map<String, Object> model, ChatOptions modelOptions);
- 프롬프트 생성 기능을 확장하여 동적 콘텐츠를 포함하고, Map<String, Object>각 맵 항목이 프롬프트 템플릿의 플레이스홀더이고 연관된 동적 값과 채팅 요청에 대한 특정 옵션을 포함함
- 예시 (https://github.com/Azure-Samples/spring-ai-azure-workshop/blob/main/2-README-prompt-templating.md )
PromptTemplate promptTemplate = new PromptTemplate("Tell me a {adjective} joke about {topic}"); Prompt prompt = promptTemplate.create(Map.of("adjective", adjective, "topic", topic)); return chatModel.call(prompt).getResult();
효과적인 프롬프트 만들기
- 명확한 지시
- 외부 맥락 : 관련된 배경 정보나 구체적인 지침 포함
- 사용자 입력
- 출력 표시기 : 출력 형식을 지정, 그러나 AI 가 항상 형식을 엄격하게 준수하지 않을 수 있음 유의
토큰
AI 모델이 텍스트를 처리하는데 필수적이며, 단어(우리가 이해하는 대로)를 AI 모델이 처리할 수 있는 형식으로 변환하는 다리 역활
이 변환은 두 단계로 이루어짐
- 단어는 입력 시 토큰으로 변환
- 이 토큰은 출력 시 다시 단어로 변환됨
토큰은 AI 처리에서의 기술적 역할을 넘어, 특히 청구 및 모델 기능과 관련하여 실질적인 의미를 가짐
- 청구: AI 모델 서비스는 종종 토큰 사용량에 따라 청구. 입력(프롬프트)과 출력(응답) 모두 총 토큰 수에 기여하여 더 짧은 프롬프트가 더 비용 효율적
- 모델 제한: 다양한 AI 모델은 다양한 토큰 제한을 가지며, "컨텍스트 창"을 정의. 이는 한 번에 처리할 수 있는 최대 정보량
- 예를 들어, GPT-3의 제한은 4,000개 토큰인 반면, Claude 2 및 Meta Llama 2와 같은 다른 모델은 100,000개 토큰의 제한을 가지고 있으며, 일부 연구 모델은 최대 100만 개의 토큰을 처리할 수 있음.
- 컨텍스트 윈도우: 모델의 토큰 제한은 컨텍스트 윈도우를 결정. 이 제한을 초과하는 입력은 모델에서 처리되지 않음. 처리를 위해 최소한의 효과적인 정보 집합만 보내는 것이 중요
- 예를 들어, "햄릿"에 대해 문의할 때 셰익스피어의 다른 모든 작품에서 토큰을 포함할 필요는 없음.
- 응답 메타데이터: AI 모델의 응답에 대한 메타데이터에는 사용된 토큰 수가 포함되어 있으며, 이는 사용량과 비용을 관리하는 데 중요한 정보임.
임베딩 모델
- 임베딩 모델(text-embedding-ada-002) → 회의록 벡터 변환 후 저장
- GPT-4 → 회의록 내용을 분석하여 요구사항 정리
- 문서를 벡터로 변환해서 DB 저장 → 사용자의 질문을 벡터로 변환한 후, 가장 유사한 문서를 검색 → 검색된 문서를 프롬프트에 추가하여 GPT 모델이 응답 생성
- https://a.wiki.techready.ai/wiki/spaces/SyncFlow/pages/310673415/Embedding+Model
- 예시
// 1. 문서를 임베딩 벡터로 변환
EmbeddingClient embeddingClient = new OpenAiEmbeddingClient(apiKey); List<Double> documentEmbedding = embeddingClient.embed("AI 모델이란 무엇인가?");
// 2. 사용자의 질문도 벡터로 변환 후, DB에서 가장 유사한 문서 찾기
List<Double> queryEmbedding = embeddingClient.embed("OpenAI는 임베딩 모델을 꼭 써야 하나?"); String relevantDocument = searchDatabase(queryEmbedding);
// 유사한 문서 찾기// 3. 찾은 문서를 프롬프트에 추가하여 GPT 모델이 답변 생성
ChatMessage contextMessage = ChatMessage.createSystemMessage("Here is relevant information: " + relevantDocument); ChatMessage userMessage = ChatMessage.createUserMessage("Can I use OpenAI without embeddings?"); String response = chatClient.call(List.of(contextMessage, userMessage)); System.out.println(response);
벡터 DB (Store)
벡터는 토큰을 임베딩한 결과물로 0에서 1 사이의 숫자로 구성된 배열의 형태를 가지며, 이를 저장하는 곳이 바로 벡터 DB 혹은 벡터 Store
- 예시 - chroma local db
- 임베딩 모델을 통해서 Documents를 Vector Store에 저장, 그후에 유사도 검색을 통해서 관련 내용을 검색
@Bean public VectorStore chromaVectorStore(EmbeddingModel embeddingModel, ChromaApi chromaApi) { return ChromaVectorStore.builder(chromaApi, embeddingModel) .collectionName("TestCollection") .initializeSchema(true) .build(); } List<Document> documents = List.of( new Document("Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!! Spring AI rocks!!", Map.of("meta1", "meta1")), new Document("The World is Big and Salvation Lurks Around the Corner"), new Document("You walk forward facing the past and you turn back toward the future.", Map.of("meta2", "meta2")) ); vectorStore.add(documents); List<Document> results = vectorStore.similaritySearch("Spring");
- OpenAI Vector Store
- 파일 기반으로 동작하여 먼저 파일을 업로드하고 Vector Store에 파일을 연결하도록 구성됨
- 하나의 채팅 세션이 아닌 Assistant 기능을 통해서 지속적으로 Knowledge Base 기반의 응답을 하도록 File Search 기능을 제공하는 것이 목적으로 보임
- https://platform.openai.com/docs/api-reference/vector-stores
- https://platform.openai.com/docs/assistants/overview