14. 대화형 API와 보완형 API

LLM 시대, LangChain(랭체인)으로 배우는 AI 소프트웨어 개발

by AI개발자
gaebalai-blog_ai-v3-1.jpg

(1) 대화형 API와 보완형 API

LLM을 애플리케이션에 통합하여 사용할 때 API를 통해 언어모델과 상호작용합니다. 이 글을 쓰는 시점에ㅔ서 주요 API에는 대화형 API(Chat API, Conversation API)와 보완형 API(Completion API)의 2가지 유형이 있습니다.


① 대화형 API

대화형 API는 OpenAI의 ChatGPT와 같은 자연스러운 대화를 실현하도록 설계된 인터페이스입니다. 대화형 LLM과 멀티모달 LLM의 대부분은 이 대화형 API를 통해 활용됩니다. 대화형 API의 LLM은 사용자와 AI어시스턴트가 번갈아 메시지를 교환하여 대화의 맥락을 이해하고 적절한 응답을 생성합니다.


대화형 API는 메시지 목록을 프롬프트로 입력하여 다음 응답 메시지를 생성합니다. 예를 들어, 다음과 같은 메시지 목록을 입력해 봅시다.

llm-langchain72-14.png

이 프롬프트는 2개의 사용자 메시지와 하나의 보조 메시지로 구성됩니다. 사용자는 처음에 가장 오래된 프로그래밍 언어를 어시스턴트에게 묻습니다. 어시스턴트는 대답이 'FORTRAN'임을 반환하고 사용자는 개발자를 계속 묻습니다. 대화형 API에 대해 이러한 메시지 목록을 프롬프트로 입력하면 출력으로 다음과 같은 응답메시지를 얻을 수 있습니다.

llm-langchain72-15.png

사용자의 두번째 질문 '누가 개발했습니까?'에서는 목적어인 'FORTRAN'이 생략되었습니다. 그러나, LLM은 대화의 맥락에서 목적어가 'FORTRAN'임을 이해하고 답변합니다.

이러한 방식으로 대화형 API를 사용하면 사용자는 LLM과 자연스러운 상호작용을 수행하고 다양한 작업을 요청할 수 있습니다. 대화의 맥락을 유지하면서 사용자의 질문과 요청에 적절한 응답을 생성할 수 있으므로 다양한 응용프로그램에 적용할 수 있습니다.


② 보완형 API

보완형 API는 주어진 텍스트 다음에 자연어 텍스틀르 예측하는 인터페이스입니다. 사전 학습된 언어모델의 대부분은 이 보완적인 API를 통해 이용됩니다. 사전학습된 언어모델은 주어진 프롬프트의 컨텍스트를 이해하고 컨텍스트 뒤에오는 텍스트를 생성합니다. 예를 들어, 다음과 같은 문장을 프롬프트로 사용하는 경우를 생각해 봅시다.

llm-langchain72-16.png

이것을 프롬프트로 API에 입력하고 최대 256개의 토큰의 텍스트를 생성하도록 지정하면 다음과 유사한 출력이 생성됩니다.

llm-langchain72-17.png

이 출력결과는 gpt-4.5-instruct에서 파라미터로 temperature=0, max_length=256을 지정하여 얻을 것입니다. 여기에서는 temperature를 0으로 설정하고 창의성을 억제하고 있기 때문에, 누구나가 잘 아는 내용이 생성되고 있는 것을 알 수 있습니다.

보완형 API는 OpenAI API등에서는 이미 레거시 취급이 되고 있어 최근 모델에서는 대화형 API만이 제공되고있습니다. 이런 이유로 이 강좌에서는 주로 대화형 API를 사용하여 설명합니다.

llm-langchain72-18.png

이 프롬프트에서는 LLM에 대해 이야기를 이어 가르쳐 주었으면 하는 취지를 명시적으로 전하고 있습니다.



(2) 각종 언어모델 API의 공통점

언어모델 API는 OpenAI API와 Gemini API를 비롯한 다양한 것들을 사용할 수 있습니다. 또한, 앞으로도 API는 늘어날 것으로 예상됩니다. 이번에는 OpenAI API와 같은 개별 API를 설명하기 전에 각 API에 대한 공통점을 설명합니다. 역러 언어모델 API의 공통점을 알면 언어 모델의 본질을 이해하는데 도움이 됩니다. 또한 향후 나올 언어모델의 API도 동일한 공통점을 가질 것으로 예상됩니다.

이 문서에서는 다음 API를 다룹니다.


OpenAI API

Gemini API

Anthropic API


이러한 API는 언어모델을 활용하기 위한 인터페이슨라는 점에서 동일하며 여러 측면에서 공통적입니다. 이후 주로 공통되는 항목을 설명하는 것과 동시에 상세한 API마다의 차이에 대해서도 언급합니다.


① 요청 및 응답 흐름

대규모 연산 리소스가 필요한 LLM은 OpenAI 및 Google과 같은 API공급자의 서버에서 운영됩니다. 사용자는 HTTP프로토콜을 기반으로 하는 웹API를 사용하여 각 API공급자의 LLM에 액세스하게 됩니다. 파라미터수가 적은 모델이라면 로컬PC에서도 실행시킬 수있습니다. 그러나, 최첨단 및 최고성능 모델은 항상 서버에서 작동해야 합니다.

llm-langchain73.png 요청 및 응답 흐름

위 그림에서 볼 수 있듯이, 요청과 응답흐름은 기본적으로 HTTP 프로토콜을 사용하여 JSON(JavaScript Object Notation)형식으로 데이터를 교환하는 점에서 공통적입니다. 구체적으로는 다음과 같은 단계에서 API와의 통신이 이루어집니다.


애플리케이션은 API제공자가 지정하는 엔드포인트URL에 HTTP POST메소드를 사용하여 요청을 전송합니다. 요청에는 API키를 통한 자격증명과 LLM에 대한 프롬프트(메시지 목록)가 포함됩니다.

서버가 요청을 받으면 자격증명을 확인하고 프롬프트를 LLM에 전달하여 처리를 수행합니다.

LLM은 프롬프트에 따라 처리를 수행하고 결과를 API서버로 리턴합니다.

API서버는 LLM에서 받은 결과를 JSON형식으로 성형하고 HTTP응답으로 사용자에게 반환합니다.

애플리케이션은 API에서 리턴된 응답을 구문분석으로 애플리케이션 특정처리에 사용합니다.


이러한 방식으로 요청 및 응답 교환을 통해 사용자는 LLM처리 결과를얻을 수 있습니다. API를 통한 액세스를 통해 사용자는 LLM을 직접 운영하지 않고도 언어처리기능을 쉽게 사용할 수 있습니다.

참고로 웹API를 통하 OpenAI API를 사용하는 Python프로그램의 예가 아래와 같이 나옵니다. 이 프로그램은 requests 모듈을 사용하여 HTTP요청을 보내거나 JSON데이터를 명시적으로 조작합니다. 그러나 실제 응용프로그램에서 이러한 처리를 작성하는 것은 적을 수 있습니다. 이는 API공급자가 좀 더 추상적인 Python 모듈을 통해 API를 제공하기 떄문입니다. API 공급자가 제공하는 전용 Python 라이브러리를 사용하는 것으로 보다 간간하게 LLM을 조작하는 것이 가능합니다.

참고로 API공급자에 의한 전용 라이브러리의 제공이 없는 프로그래밍 언어를 사용하는 경우 아래와 같은 프로그램을 작성할 필요가 있습니다.


웹API를 통한 OpenAI API 사용예시 (src/api/http_openai.py)

llm-langchain74.png


② API키로 인증

언어모델 API를 사용하려면 API공급자가 발행하는 API키가 필요합니다. API키는 일반적으로 사용자 및 프로젝트별로 발행됩니다. 이러한 자격증명은 요청 시 HTTP헤더에 포함되어 API서버로 전달됩니다.

API키는 사용자 또는 조직의 관리자가 API공급자에 등록하여 얻을 수 있는 문자열입니다. 키에는 무료플랜 및 유료플랜과 같은 사용자의 계약 플랜에 따라 권한이 부여됩니다. API키는 사용자와 프로젝트를 식별하고 사용가능한 리소스를 제어하는데 사용됩니다.

API키를 사용한 인증은 다음과 같은 이점이 있습니다.


사용자나 프로젝트를 식별하고 적절한 권한 제어를 할 수 있음

API의 무단 사용을 방지할 수 있음

사용자나 프로젝트별 사용 토큰수와 요금을 알 수 있음


그러나 API키는 기밀정보이므로 적절하게 관리해야 합니다. 이러한 자격증명이 유출되면 사기 이용 위험이 높아집니다. API키는 환경변수나 안전한 스토리지에 저장하고 소스코드에 하드코딩하는 것은 피해야 합니다.


③ Python으로 API라이브러리 제공

대부분의 API공급자는 Python을 포함한 여러 프로그래밍 언어에서 사용할 수 있는 API 클라이언트 라이브러리를 제공합니다. 예를 들어, OpenAI는 Python의 openai 패키지를 통해 GPT모델에 액세스하는 방법을 제공합니다. 개발자는 이러한 라이브러리를 사용하여 HTTP요청을 작성하고 응답을 쉽게 얻을 수 있습니다.

또한, 이러한 라이브러리는 공통적으로 API키를 환경변수에서 자동으로 읽어 HTTP요청에 사용합니다. 이를 통해 개발자는 API키를 소스코드에 직접 쓰지 않고도 자격증명을 안전하게 사용할 수 있습니다. 설정해야 할 환경변수는 API마다 다르지만, API공급자의 이름을 대문자로 한 것에 API_KEY를 연결해 환경변수를 명명하는 것이 관례가 되고 있습니다. 아래 표는 API별 환경변수를 보여줍니다.

llm-langchain74-1.png

API 공급자에서 제공하는 라이브러리는 API의 엔드포인트 URL, 인증, 요청 파라미터등의 세부사항을 추상화하고 개발자가 직접 LLM기능을 활용할 수 있도록 설계되었습니다.

여기에서는 참고로 아래 코드에서 Python라이브러리에 의한 OpenAI API의 이용예시를 나타냅니다. 웹API를 직접 사용했던 코드와 비교하면 처리가 간소화되었음을 확인할 수 있어야 합니다. 예를 들어 이전 코드에서는 명시적으로 JSON데이터를 다루고 있었지만 아래 코드에서는 그럴 필요가 없습니다.


Python 라이브러리를 통한 OpenAI API사용 예시(src/api/python_openai.py)

llm-langchain74-2.png

④ 언어모델의 제어 파라미터

언어모델 API는 언어모델의 동작을 제어하기 위한 파라미터를 제공합니다. 파라미터를 조정하면 생성되는 텍스트의 특성을 변경할 수 있습니다. 각 모델에서 공통되는 파라미터에는 다음과 같은 것이 있습니다.


temperature (온도)

top-p

최대 토큰 수

정지 시퀀스


이 파라미터는 용도에 따라 다음 2가지로 크게 나뉩니다.


토큰 예측: Transformer기반 LLM은 컨텍스트에서 다음 토큰의 확률 분포를 계산합니다. 그런 다음 temperature, top-p등의 파라미터를 사용하여 이 확률분포에서 다음 토큰을 샘플링합니다.

길이제어: 최대 토큰 수는 모델이 생성하는 전체길이를 제한하는 역할을 합니다. 모델이 텍스트를 생성할 때 최대 토큰 수로 설정된 상한에 도달하거나 정지 시퀀스가 나타나면 생성 프로세스가 중지됩니다.


이러한 파라미터는 API를 요청할 때 지정합니다. 목적에 따라 적절한 파라미터를 설정해야 합니다.


▣ temperature(온도)

temperature는 생성되는 텍스트의 창의성에 영향을 미치는 음이 아닌 실수 파라미터입니다. 주로 0이상 1이하의 범위로 설정됩니다. 낮게 설정하면 생성되는 텍스트는 보다 확정적이고 일관성이 있는 것이 됩니다. 0을 설정하면 매번 동일한 결과를 얻을 수 있습니다. 한편, 높게 설정하면 생성되는 텍스트는 보다 다양성이 풍부한 것이 됩니다. 1보다 큰 값도 설정할 수 있지만, 생성되는 텍스트의 랜덤성이 증가하기 떄문에 의미가 없는 문장을 얻을 수 있을 가능성이 높아집니다.


낮게 설정해야 하는 경우의 예는 프롬프트에서 제공한 최신 정보에서 뉴스기사를 생성하는 것입니다. temperature를 낮게 설정하면 사실에 따라일관성 기사를 생성할 수 있습니다. 한편 높게 설정하는 경우의 예로서는 새로운 이야기의 생성을 생각할 수 있습니다. temperature를 높게 설정하면 상상력이 풍부하고 다양성이 있는 이야기를 생성할 수 있습니다.


▣ 최대 토큰수

최대 토큰수는 언어모델이 생성하는 텍스트의 최대 길이를 제어하는 파라미터입니다. 이 파라미터는 토큰 수로 지정되어 생성되는 텍스트가 지정된 길이를 초과하지 않도록 합니다.


최대 토큰수의 주요 목적은 낭비적으로 긴 토큰열을 생성하여 계산자원이 소모되는 것을 방지하는 것입니다. 최대 토큰수의 값은 언어모델에 주어진 프롬프트와 독립적으로 작동합니다. 즉, 프롬프트의 내용에 관계없어 최대 토큰수로 지정된 길이를 초과하는 텍스트는 생성되지 않습니다.


최대 토큰수를 사용할 때 문장이 중간에 끊어질 수 있다는 점에 유의해야 합니다. 이 때문에 많은 경우 프롬프트 중에 길이를 지정하는 편이 자연스러운 텍스트의 생성에 적합합니다. 프롬프트에서 '100단어 정도로 요약해 주세요'와 같이 길이를 유연하게 지정할 수 있습니다. 언어모델은 이 지침을 이해하고 컨텍스트에 따라 자연스러운 구분으로 텍스트를 생성하려고 합니다.


다만, 출력 텍스트의 최대 길이를 엄밀하게 제어할 필요가 있는 경우나, 계산자원에 제약이 있는 경우에는 최대 토큰수가 유효합니다. 프롬프트와 최대 토큰수를 조합하여 사용하면 출력 텍스트의 길이를 제어하면서 품질을 유지할 수 있습니다.


▣ 정지시퀀스

언어 모델 API를 사용할 때 정지시퀀스를 설정하여 생성되는 응답을 유연하게 제어할 수 있습니다. 정지시퀀스는 언어모델이 생성하는 응답 중 지정된 문자열이 나타나는 시점에서 생성을 중단하는 기능입니다. 이렇게하면 필요한 정보만 생성됩니다. 성취하고 쓸데없는 계산을 피할 수 있는 경우가 있습니다.


정지시퀀스의 실용적인 사용장면으로는 이전에 소개한 ReAct의 구현이 생각됩니다. 구체적으로는 ReAct의 Observation이후 쓸데없는 생성을 중지하기 위해 정지시퀀스를 설정합니다. Few-Shot 프롬프트를 사용한 ReAct구현에서 추론(Thought), 행동(Action), 관측(Observation)을 예시로 줍니다. LLM은 예시와 마찬가지로 추론, 행동, 관측을 출력하지만, 관측은 LLM의 호출자로 대체하기 떄문에 필요하지 않습니다.


예를 들어, ReAct에서 LLM에 도구를 사용하여 실시간으로 도시의 날씨를 대답하는 경우를 생각해 봅시다. Few-Shot프롬프트의 ReAct에서 사용하는 프롬프트 중 일부는 다음과 같습니다.

llm-langchain74-3.png

이 프롬프트에서 LLM은 Examples와 마찬가지로 Thought이후의 텏스트를 생성합니다. 그러나, Observation이후에는 실제로 LLM이 생성한 것을 그대로 이용하는 것이 아니라, LLM호출측에서 날씨를 취득한 결과로 대체해야 합니다. 따라서, Observation 이후를 LLM에 생성할 필요가 없습니다. 이 경우, 정지시퀀스를 설정하여 Observation이후의 생성을 중지할 수 있습니다. 정지시퀀스로 'Observation:'을 지정하면 이전 프롬프트에 대한 응답은 다음과 같습니다.

llm-langchain74-4.png

한편, 정지시퀀스가 지정되어 있지 않은 경우, 예시와 같이 다음과 같은 부분까지 LLM이 출력해 버리는 것이 생각됩니다.

llm-langchain74-54.png

이때 '맑음'은 LLM이 마음대로 추측한 결과이며 실제 날씨가 반영된 것은 아닙니다. 그러나, 정지시퀀스를 지정하면 Action까지의 출력에서 중지할 수 있습니다. 이 결과에 따라 LLM호출자는 다음과 같은 작업을 수행합니다.


Action내용을 분석하고 GetWeather("부산")라는 API요청을 실행하여 부산의 날씨정보를 얻습니다. 여기에서는 흐림이라는 날씨 정보를 얻었다고 가정합니다.

프롬프트에 Observation: 흐림을 추가하고 LLM에 다시 문의합니다.

LLM은 추가된 Observation을 기반으로 나머지 Thought 및 Action을 생성합니다.


이러한 방식으로 정지시퀀스를 활용하면 API요청을 실행하고 응답을 효율적으로 생성할 수 있습니다.



©2024-2025 GAEBAL AI, Hand-crafted & made with Damon Jaewoo Kim.


GAEBAL AI 개발사: https://gaebalai.com

AI 강의 및 개발, 컨설팅 문의: https://talk.naver.com/ct/w5umt5


keyword
이전 14화13. Reflexion