여행 관리 앱 개발 일지

Spring AI 공식 문서 정리

쥐4 2024. 11. 24. 23:32


Chat Model API는 개발자에게 AI 기반 채팅 완료 기능을 애플리케이션에 통합할 수 있는 기능을 제공합니다. GPT(Generative Pre-trained Transformer)와 같은 사전 훈련된 언어 모델을 활용하여 자연어로 사용자 입력에 대해 인간과 유사한 응답을 생성합니다.

API는 일반적으로 AI 모델에 프롬프트 또는 부분 대화를 보내는 방식으로 작동하며, AI 모델은 훈련 데이터와 자연어 패턴에 대한 이해를 기반으로 대화의 완료 또는 지속을 생성합니다. 완료된 응답은 애플리케이션으로 반환되며, 애플리케이션은 이를 사용자에게 표시하거나 추가 처리에 사용할 수 있습니다.

Spring AI Chat Model API는 다양한 AI 모델과 상호 작용하기 위한 간단하고 이식 가능한 인터페이스로 설계되어 개발자가 최소한의 코드 변경으로 다른 모델 간에 전환할 수 있습니다. 이 디자인은 Spring의 모듈화 및 상호 호환성 철학과 일치합니다.

또한 입력 캡슐화를 위한 프롬프트 및 출력 처리를 위한 ChatResponse와 같은 동반 클래스의 도움으로 Chat Model API는 AI 모델과의 통신을 통합합니다. 요청 준비 및 응답 구문 분석의 복잡성을 관리하여 직접적이고 단순화된 API 상호 작용을 제공합니다.

사용 가능한 구현 섹션에서 사용 가능한 구현에 대한 자세한 내용을 확인하고 채팅 모델 비교 섹션에서 자세한 비교를 확인할 수 있습니다.

========================================================================

즉, AI 모델에 프롬프트 혹은 부분 대화를 보내 응답을 받아오는 형식으로 개발이 가능하다는 것 같다.

동작 흐름에 대해 알아보자.

 

프롬프트

AI 모델이 특정 출력을 생성하도록 안내하는 역할을 갖는다.

ex) chat gpt의 대화상자에 입력되는 텍스트

이 텍스트는 단순히 문자열만 포함하는 것이 아니라고 한다.

즉, AI 모델에 요청을 하기 위한 템플릿을 만들고, 그 템플릿에 대화상자의 텍스트를 넣음으로 요청을 보내면, gpt의 AI 모델이 응답을 해주는것.-> 이 템플릿 + 부가정보 + 사용자가 입력할 정보가 프롬프트인 것 같다.

프롬프트 템플릿을 만드는 것은 굉장히 중요하다.

프롬프트 템플릿

전통적 텍스트 기반 템플릿 엔진을 사용한다고 한다.

Tell me a {adjective} joke about {content}.

->이 템플릿에 사용자는 adjective에 funny, content에 computer를 넣는다.

-> AI 모델에 요청을 보낸다.

-> Why don't computers ever get tired? They have plenty of cache! 라는 응답이 온다.

-> 이때, 자바 개발자는 DTO 템플릿을 사용해 AI 모델의 응답을 가공해야 할 것 같다.

 

토큰

토큰 == 돈(???) == 사용된 토큰 수 

영어에서 토큰 하나는 대략 단어의 75%에 해당 -> 90만 단어(n * 75% = 90만) => 120만 토큰

즉, 개발자는 가난하기 때문에 적은 가격으로 ai를 사용할 수 있어야 한다.

-> 데이터를 요약하고, AI 모델의 제한 토큰에 맞춰 요청을 보내야 한다.

스프링 AI는 이 작업을 도와준다고 한다. 

 

AI 모델의 응답

AI 모델의 응답은 기본 문자열 형태로 반환된다.

JSON 형식으로 제공! 이라는 내용을 프롬프트에 포함시켜도 문자열이다. 그저 문자열로 JSON 형식을 흉내낼 뿐...

즉, "인덱스를 달아줘!", "해시 형태로 반환해줘!"라는 조건을 포함시켜 받은 문자열 응답을 서버 내에서 변환시켜줘야 한다.

 

 

채팅 클라이언트 API

기본 예제

@RestController
class MyController {

    private final ChatClient chatClient;

    public MyController(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder.build();
    }

    @GetMapping("/ai")
    String generation(String userInput) {
        return this.chatClient.prompt()
            .user(userInput)
            .call()
            .content();
    }
}

 

1. ChatClient를 생성 후 prompt에 user의 input을 넣어줌

2. call() : AI 모델에 요청

3. content() : AI 모델에서 응답을 받아옴(String)

 

요청 프롬프트

응답 매핑해서 가져오기

record ActorFilms(String actor, List<String> movies) {}
ActorFilms actorFilms = chatClient.prompt()
    .user("Generate the filmography for a random actor.")
    .call()
    .entity(ActorFilms.class);

<단일 엔티티 매핑>

List<ActorFilms> actorFilms = chatClient.prompt()
    .user("Generate the filmography of 5 movies for Tom Hanks and Bill Murray.")
    .call()
    .entity(new ParameterizedTypeReference<List<ActorFilms>>() {});

<제네릭 매핑>

 

단일 엔티티 매핑 흐름

-> chatClient.prompt()로 ChatClientRequestSpec을 반환

<DefaultChatClient의 prompt()>
<DefaultChatClientRequestSpec>

 

 

-> chatClientRequestSpec.user(String {message})로 CatClientRequestSpec에 set

<DefaultChatClientRequestSpec의 user()>

스프링 AI에서는 외부 데이터, Consumer(텍스트가 아닌 미디어), text를 요청으로 받을 수 있도록 지원하는 것 같다.

 

 

-> chatClientRequestSpec.call()로 CallResponseSpec 반환

<DefaultChatClientRequestSpec의 call()>
<DefaultCallResponseSpec의 생성자>

 

 

-> CallResponseSpec.entity()로 <T> T entity 반환

<DefaultCallResponseSpec의 entity()>

BeanOutputConverter : 리플랙션 등을 이용해 set으로 값 세팅

StructuredOutputConverter: 생성자를 이용해 세팅 후 객체 생성

<실질적으로 모델 AI의 API를 사용하는 메서드>

 

이따 계속