랭체인 프로그래밍: 개념과 응용 – 004

템플릿은 일정한 형식을 유지하며 반복적인 작업을 쉽게 처리할 수 있게 해줍니다. 예를 들어, 문서 작성 템플릿을 사용하면 매번 새로운 문서를 작성할 때마다 기본적인 레이아웃과 스타일이 동일하게 유지되며, 그 안에 내용만 바꾸면 됩니다.

프롬프트를 작성하다보면 많은 부분이 같고 일부분은 다른 것들이 등장합니다. 이럴 때, 고정된 부분은 그대로 유지하고 변경 부분만 상황에 맞게 교체하는 방식으로 템플릿을 활용할 수 있습니다.

프롬프트는 지시 문자열이니, 생성 지시에서 고정 부분과 변경 부분을 구분해서 변경 부분을 대체할 수 있으면 됩니다. 이러 필요가 있을 때 사용할 수 있는 문자열 다루는 기술이 ‘문자열 포맷팅과 변수 대체’입니다.

 

LangChain에서는 프롬프트 템플릿을 문자열 포맷팅과 변수 대체를 구현한 PromptTemplate로 지원합니다.

어떤 포맷팅을 사용해야 할까요? 고정된 부분과 변경될 부분을 구분해야 합니다. 고정 부분은 고정된 문자열로 작성하면 되고, 변경 부분은 변수로 지정합니다.

  • 변수를 다른 문자열과 구분하기 위해서 구분자를 사용합니다.
    • {} 중괄호를 사용해 변수 위치 표시
      • 예: "안녕하세요, {name}님"
  • 변경 부분이 결정된다는 것은 변수 값이 설정된다는 것입니다. 변수 값이 설정되면 변수 부분을 변수 값으로 대체해 전체 문장을 완성합니다.
    • .format() 메서드나 f-스트링이나 딕셔너리 매핑을 사용합니다.
      • template = “안녕하세요, {name}님. {age}세이시군요.”
      • result1 = template.format(name=”김철수”, age=30)
      • result2 = template.format(name=”이영희”, age=25)


    •  

LangChain의 PromptTemplate은 단순한 문자열 포맷팅을 넘어, LLM과의 상호작용을 더욱 정교하고 체계적으로 만들어주는 고급 도구입니다.

 

f-스트링(f-string)은 Python 3.6부터 도입된 문자열 포맷팅 방식으로, 문법이 간단하고 가독성이 뛰어난 것이 특징입니다. f-스트링은 문자열 앞에 f 또는 F를 붙이고 중괄호 {}안에 변수나 표현식을 직접 작성하여, 해당 값으로 문자열을 동적으로 생성하는 기능을 제공합니다.

기본 사용법:

  1. 변수 사용:

  1. 표현식 사용:

  1. 포맷 지정: f-스트링을 사용할 때, 데이터의 형식을 지정할 수 있습니다. 예를 들어, 소수점 이하 자리수를 조정할 수 있습니다.

장점:

  • 가독성: 변수를 문자열에 바로 삽입할 수 있어 코드가 더 직관적이고 읽기 쉬워집니다.
  • 성능: f-스트링은 다른 문자열 포맷팅 방법에 비해 성능이 우수합니다.
  • 유연성: 다양한 표현식을 직접 사용할 수 있어 코드 작성이 간결해집니다.

 

 

PromptTemplate

  • PromptTemplate.from_template
    • 프롬프트 템플릿 문자열로 부터 PromptTemplate을 생성한다.
    • invoke
      • 변수 값들로 프롬프트 템플릿의 가변 부분을 채워 프롬프트를 완성합니다.
        • 이 템플릿은 {role}{question} 자리 표시자를 포함하여, 런타임 시 실제 값을 동적으로 삽입할 수 있도록 합니다.

      •  

랭체인은 생생성형 AI 애플리케이션 개발 프레임워크로서, 구성 요소들을 단순히 기능 단위로 제공하는 것을 넘어, 구성 요소들의 역할 자체를 추상화하여 더욱 유연하고 확장 가능한 아키텍처를 제공합니다. 즉, 특정 기능을 수행하는 구체적인 구성 요소가 아니라, 그 기능이라는 역할 자체를 정의하고, 그 역할을 수행하는 다양한 구현체를 지원합니다.

이러한 역할 중심의 추상화는 다음과 같은 이점을 제공합니다.

  • 유연성 향상: 새로운 구성 요소나 기술이 등장하더라도, 기존의 역할 정의를 변경할 필요 없이 새로운 구현체를 추가하기만 하면 됩니다. 이는 LangChain 기반 애플리케이션의 유지보수 및 확장성을 크게 향상시킵니다.
  • 재사용성 증대: 특정 역할을 수행하는 구성 요소는 여러 애플리케이션에서 재사용될 수 있습니다. 이는 개발 시간을 단축하고 코드 중복을 줄이는 데 기여합니다.
  • 개발 편의성 증대: 개발자는 구체적인 구현에 대한 세부 사항에 신경 쓰지 않고, 역할에 집중하여 애플리케이션을 설계할 수 있습니다. 이는 개발의 복잡성을 줄이고 생산성을 높입니다.

 

랭체인은 역할 중심의 추상화를 넘어 역할들에 대한 추상화도 진행했습니다.  프롬프트 템플릿 역할을 PromptTemplate으로 모델 클라이언트의 역할을 OpenAI, ChatOpenAI로 정의했고, 프롬프트 템플릿도 모델 클라이언트도 그 자체가 의미 있는 것이 아니라 실행되어 의미 있는 결과를 리턴해야 하는 것으로 추상화해 보면 같은 것으로 볼 수 있습니다. 실행해야 하는 것 Runnable로 볼 수 있다는 것입니다.

 

랭체인은 단순히 구성 요소의 역할을 추상화하는 것을 넘어, 역할들에 대한 추상화도 진행했습니다.

  • 실행 가능성(Runnable)
    •  PromptTemplate는 프롬프트를 생성하는 역할을 하고, OpenAIChatOpenAI는 LLM을 호출하는 역할을 하지만, 둘 모두 입력을 받아 출력을 생성하는 실행 가능한(Runnable) 객체로 볼 수 있습니다. 이러한 관점에서 invoke 메서드는 이러한 다양한 Runnable 객체들을 일관되게 호출하고 결과를 얻기 위한 표준화된 인터페이스 역할을 합니다.
      • 입력을 받아 출력하는 경우를 좀 더 꼼꼼하게 살펴보겠습니다.
        • 하나의 입력이 아니라 여러 입력이 있을 수도 있습니다.
          • invoke를 하나의 입력을 받는 것으로 batch를 여러 입력을 받는 것으로 합니다.
        • 전체 출력이 모두 만들어진다음에 리턴할 수도 있지만 처리하는 만큼씩 리턴할 수도 있습니다.
          • 처리하는 만큼 리턴하는 것을 stream이라 합니다.
    • 랭체인에서는 역할들의 추상화에는 명시적인 인터페이스를 정의하지 않고, 선언적인 방식을 사용합니다.
      • Runnable을 예로 들면, 다음과 같이 말할 수 있는 것입니다.
        • 이런 것들은 Runnable이라고 하는데, Runnable한 것들은 invoke, batch, stream을 할 수 있습니다. 당신이 만든 클래스에 이런 함수를 같으면 이렇게 처리될 것입니다.
      • LangChain Expression Language (LCEL)은 LangChain 구성 요소들을 결합하기 위한 선언형 언어입니다. LangChain은 LCEL 구성을 최적화된 실행 계획으로 컴파일합니다. 이 계획에는 자동 병렬 처리, 스트리밍, 추적 및 비동기 지원이 포함됩니다.
      • LCEL은 구성 요소들의 연결 방식과 실행 순서를 명시적으로 정의하는 방식으로, 명령형 방식보다 더욱 간결하고 가독성이 높은 코드를 작성할 수 있게 해줍니다. 또한, LCEL은 자동으로 병렬 처리, 스트리밍, 비동기 지원 등을 제공하여 개발 효율성을 높입니다. 명령형 방식과 달리 스트리밍이나 비동기 처리를 위해 함수를 수정할 필요가 없다는 장점이 있습니다. 복잡한 작업의 경우, LCEL을 사용하면 코드의 가독성과 유지보수성을 크게 향상시킬 수 있습니다.
About the Author
(주)뉴테크프라임 대표 김현남입니다. 저에 대해 좀 더 알기를 원하시는 분은 아래 링크를 참조하세요. http://www.umlcert.com/kimhn/

Leave a Reply

*