langchain 공부

langchain LCEL 인터페이스

필만이 2024. 8. 2. 16:25

LCEL 사용예

from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser

# ChatOpenAI 모델을 인스턴스화합니다.
model = ChatOpenAI()
# 주어진 토픽에 대한 농담을 요청하는 프롬프트 템플릿을 생성합니다.
prompt = PromptTemplate.from_template("{topic} 에 대하여 3문장으로 설명해줘.")
# 프롬프트와 모델을 연결하여 대화 체인을 생성합니다.
chain = prompt | model | StrOutputParser()

LCEL 종류 및 기능

동기 메소드(마지막에 한꺼번에 출력함)

stream: 응답의 청크를 스트리밍합니다.

  • 개념 : 이 함수는 chain.stream 메서드를 사용하여 주어진 토픽에 대한 데이터 스트림을 생성하고, 이 스트림을 반복하여 각 데이터의 내용(content)을 즉시 출력합니다. end="" 인자는 출력 후 줄바꿈을 하지 않도록 설정하며, flush=True 인자는 출력 버퍼를 즉시 비우도록 함

  • 코드 예

# chain.stream 메서드를 사용하여 '멀티모달' 토픽에 대한 스트림을 생성하고 반복합니다.
for token in chain.stream({"topic": "멀티모달"}):
    # 스트림에서 받은 데이터의 내용을 출력합니다. 줄바꿈 없이 이어서 출력하고, 버퍼를 즉시 비웁니다.
    print(token, end="", flush=True)
출력
멀티모달은 여러 가지 다른 형태의 커뮤니케이션 수단을 통해 정보를 전달하고 상호작용하는 기술을 의미합니다. 예를 들어 음성, 텍스트, 이미지, 동영상 등 다양한 매체를 활용하여 사용자와 상호작용할 수 있습니다. 멀티모달 기술은 사용자 경험을 향상시키고 정보 전달의 효율성을 높이는데 도움을 줄 수 있습니다.

invoke: 입력에 대해 체인을 호출합니다.

  • 개념 : chain 객체의 invoke 메서드는 주제를 인자로 받아 해당 주제에 대한 처리를 수행

  • 코드 예

# chain 객체의 invoke 메서드를 호출하고, 'ChatGPT'라는 주제로 딕셔너리를 전달합니다.
chain.invoke({"topic": "ChatGPT"})
출력
'ChatGPT는 OpenAI에서 개발한 대화형 인공지능 모델로, 다양한 주제에 대한 대화를 자연스럽게 이어나갈 수 있습니다. 사용자들은 ChatGPT를 통해 질문에 답변을 받거나 대화를 이어가며 새로운 정보를 습득할 수 있습니다. 또한 ChatGPT는 사용자의 입력을 학습하여 점차적으로 더욱 유창하고 자연스러운 대화를 제공합니다.'

batch: 입력 목록에 대해 체인을 호출합니다.

  • 개념 : 함수 chain.batch는 여러 개의 딕셔너리를 포함하는 리스트를 인자로 받아, 각 딕셔너리에 있는 topic 키의 값을 사용하여 일괄 처리를 수행

  • 코드 예 1

# 주어진 토픽 리스트를 batch 처리하는 함수 호출
chain.batch([{"topic": "ChatGPT"}, {"topic": "Instagram"}])
출력
['ChatGPT는 인공지능 챗봇으로 자연어 처리 기술을 사용하여 대화를 수행합니다. 사용자들과 자연스럽게 상호작용하며 다양한 주제에 대해 대화할 수 있습니다. ChatGPT는 정보 제공, 질문 응답, 상담 및 엔터테인먼트 등 다양한 용도로 활용될 수 있습니다.', 'Instagram은 사진과 동영상을 공유하고 다른 사람들과 소통하는 소셜 미디어 플랫폼이다. 해시태그를 통해 관심사나 주제별로 사진을 검색하고 팔로워들과 소통할 수 있다. 인기 있는 인플루언서나 브랜드가 활발하게 활동하는 플랫폼으로 세계적으로 인기가 높다.']
  • 코드 예2
chain.batch(
    [
        {"topic": "ChatGPT"},
        {"topic": "Instagram"},
        {"topic": "멀티모달"},
        {"topic": "프로그래밍"},
        {"topic": "머신러닝"},
    ],
    config={"max_concurrency": 3},
)
['ChatGPT는 인공지능 챗봇으로, 자연어 처리 기술을 사용하여 대화 상대와 상호작용합니다. 사용자의 질문에 응답하고 대화를 이어가며 다양한 주제에 대해 대화할 수 있습니다. ChatGPT는 사용자와 자연스럽게 대화를 나누는 데 도움을 줄 뿐만 아니라 정보를 제공하고 문제 해결을 돕기도 합니다.', 'Instagram은 사진과 동영상을 공유하고 다른 사람들과 소통할 수 있는 소셜 미디어 플랫폼이다. 다양한 필터와 편집 기능을 제공하여 사용자가 쉽게 멋진 사진을 업로드할 수 있으며 해시태그를 통해 관심사에 맞는 콘텐츠를 찾을 수 있다. 인기 있는 인플루언서들의 활동과 광고가 많이 이루어지는 플랫폼이기도 하다.', '멀티모달은 여러 가지의 다른 형태의 정보를 함께 제공하거나 처리하는 기술이다. 이는 텍스트, 이미지, 음성, 비디오 등 여러 형태의 데이터를 통합하여 효과적으로 전달하고 상호작용할 수 있게 한다. 멀티모달은 사용자 경험을 향상시키고 정보를 보다 쉽게 이해하고 활용할 수 있도록 도와준다.', '프로그래밍은 컴퓨터에게 실행할 작업을 지시하는 일종의 커뮤니케이션 방법이다. 이를 위해 프로그래머가 사용하는 언어는 컴퓨터가 이해할 수 있는 형태여야 하며, 문법과 로직을 통해 원하는 결과를 얻을 수 있다. 프로그래밍을 통해 소프트웨어를 개발하고 문제를 해결하는 등 다양한 분야에서 활용할 수 있다.', '머신러닝은 컴퓨터 시스템이 데이터에서 학습하고 패턴을 발견하여 예측하거나 결정을 내리는 인공지능의 한 분야입니다. 이를 통해 컴퓨터는 사람의 개입 없이 스스로 학습하고 문제를 해결할 수 있습니다. 머신러닝은 이미지 및 음성 인식, 자율 주행 자동차, 헬스케어 등 다양한 분야에서 활용되고 있습니다.']

비동기 메소드(완성되는 순서로 출력)

async stream: 비동기 스트림

  • 개념 : 함수 chain.astream은 비동기 스트림을 생성하며, 주어진 토픽에 대한 메시지를 비동기적으로 처리. 비동기 for 루프(async for)를 사용하여 스트림에서 메시지를 순차적으로 받아오고, print 함수를 통해 메시지의 내용(s.content)을 즉시 출력합니다. end=""는 출력 후 줄바꿈을 하지 않도록 설정하며, flush=True는 출력 버퍼를 강제로 비워 즉시 출력되도록 함

  • 사용 예

# 비동기 스트림을 사용하여 'YouTube' 토픽의 메시지를 처리합니다.
async for token in chain.astream({"topic": "YouTube"}):
    # 메시지 내용을 출력합니다. 줄바꿈 없이 바로 출력하고 버퍼를 비웁니다.
    print(token, end="", flush=True)
YouTube 는 동영상을 공유하고 시청할 수 있는 온라인 동영상 플랫폼이다. 누구나 자신의 동영상을 업로드하여 다른 사람들과 공유할 수 있고, 영상 콘텐츠를 시청하며 다양한 정보나 즐길거리를 찾을 수 있다. 또한 유명한 크리에이터들의 영상을 통해 엔터테인먼트와 정보를 얻을 수 있다.

async invoke: 비동기 호출

  • 개념 : chain 객체의 ainvoke 메서드는 비동기적으로 주어진 인자를 사용하여 작업을 수행

  • 사용 예

# 비동기 체인 객체의 'ainvoke' 메서드를 호출하여 'NVDA' 토픽을 처리합니다.
my_process = chain.ainvoke({"topic": "NVDA"})

# 비동기로 처리되는 프로세스가 완료될 때까지 기다립니다.
await my_process
출력
'NVDA는 엔비디아의 주식 코드로, 미국의 반도체 기업인 엔비디아(NVIDIA)의 주식을 말합니다. 엔비디아는 그래픽 처리 유닛(GPU)을 전문으로 하는 기업으로, 인공지능, 가상현실, 자율주행차 등 다양한 분야에서 기술을 제공하고 있습니다. NVDA 주식은 기술 산업의 성장과 함께 높은 수익을 창출하고 있습니다.'

async batch: 비동기 배치

  • 개념 : 함수 abatch는 비동기적으로 일련의 작업을 일괄 처리

  • 사용 예

# 주어진 토픽에 대해 비동기적으로 일괄 처리를 수행합니다.
my_abatch_process = chain.abatch(
    [{"topic": "YouTube"}, {"topic": "Instagram"}, {"topic": "Facebook"}]
)
# 비동기로 처리되는 일괄 처리 프로세스가 완료될 때까지 기다립니다.
await my_abatch_process
['YouTube는 동영상 공유 플랫폼으로 사용자들이 영상을 업로드하고 시청할 수 있는 서비스입니다. 다양한 콘텐츠를 제공하며 사용자는 무료로 영상을 시청할 수 있습니다. 유명한 유튜버들이 활동하고 수익을 창출할 수 있는 플랫폼으로도 알려져 있습니다.', '인스타그램은 사진과 동영상을 공유하는 소셜 미디어 플랫폼으로, 사용자들은 다양한 필터와 효과를 이용해 자신의 콘텐츠를 멋지게 꾸밀 수 있습니다. 또한 팔로워들과 소통하고, 다른 사용자의 게시물을 좋아하거나 댓글을 남기며 커뮤니케이션을 할 수 있습니다. 인스타그램은 비즈니스나 개인 브랜딩에도 활용되며, 많은 사람들이 일상 속 소소한 순간부터 특별한 순간까지를 공유하고 있습니다.', 'Facebook은 미국의 소셜 네트워크 서비스로, 사용자들이 커뮤니케이션하고 정보를 공유할 수 있는 플랫폼이다. 현재 전 세계적으로 약 30억 명 이상의 사용자가 활동하고 있으며, 광고 및 비즈니스 활동에도 널리 활용되고 있다. 또한 개인정보 보호 문제와 가짜 뉴스 등 여러 논란을 빚어왔으나, 여전히 많은 사람들이 이용하고 있는 대표적인 SNS 서비스이다.']

Parallel: 병렬성

  • 개념 : RunnableParallel을 사용할 때(자주 사전 형태로 작성됨), 각 요소를 병렬로 실행

  • 사용 예 : langchain_core.runnables 모듈의 RunnableParallel 클래스를 사용하여 두 가지 작업을 병렬로 실행하는 예시를 보여줌. ChatPromptTemplate.from_template 메서드를 사용하여 주어진 country에 대한 수도 와 면적 을 구하는 두 개의 체인(chain1, chain2)을 만듭니다. 이 체인들은 각각 model과 파이프(|) 연산자를 통해 연결됩니다. 마지막으로, RunnableParallel 클래스를 사용하여 이 두 체인을 capital와 area이라는 키로 결합하여 동시에 실행할 수 있는 combined 객체를 생성

from langchain_core.runnables import RunnableParallel

# {country} 의 수도를 물어보는 체인을 생성합니다.
chain1 = (
    PromptTemplate.from_template("{country} 의 수도는 어디야?")
    | model
    | StrOutputParser()
)

# {country} 의 면적을 물어보는 체인을 생성합니다.
chain2 = (
    PromptTemplate.from_template("{country} 의 면적은 얼마야?")
    | model
    | StrOutputParser()
)

# 위의 2개 체인을 동시에 생성하는 병렬 실행 체인을 생성합니다.
combined = RunnableParallel(capital=chain1, area=chain2)

# chain1 를 실행합니다.
chain1.invoke({"country": "대한민국"})

출력
'대한민국의 수도는 서울이다.'

# chain2 를 실행합니다.
chain2.invoke({"country": "미국"})

출력
'미국의 면적은 약 9,826,675 제곱 킬로미터입니다.'

# 병렬 실행 체인을 실행합니다.
combined.invoke({"country": "대한민국"})

출력
{'capital': '대한민국의 수도는 서울입니다.', 'area': '대한민국의 면적은 약 100,363.4 제곱 킬로미터 입니다.'}

배치에서의 병렬 처리

  • 병렬 처리는 다른 실행 가능한 코드와 결합될 수 있다.
# 배치 처리를 수행합니다.
chain1.batch([{"country": "대한민국"}, {"country": "미국"}])

출력
['대한민국의 수도는 서울이에요.', '미국의 수도는 워싱턴 D.C.입니다.']

# 배치 처리를 수행합니다.
chain2.batch([{"country": "대한민국"}, {"country": "미국"}])

출력
['대한민국의 총 면적은 약 100,363 제곱킬로미터 입니다.', '미국의 면적은 약 9,834,000km² 입니다.']

# 주어진 데이터를 배치로 처리합니다.
combined.batch([{"country": "대한민국"}, {"country": "미국"}])

출력
[{'capital': '대한민국의 수도는 서울이다.', 'area': '대한민국의 면적은 약 100,363km² 입니다.'}, {'capital': '미국의 수도는 워싱턴 D.C.입니다.', 'area': '미국의 면적은 약 9,833,520 km² 입니다.'}]