02-langchain-체인

2024. 1. 10. 19:11langchain

!python3 -m venv langchain
!source langchain/bin/activate
In [ ]:
!pip install -qU langchain openai  

체인 시작하기

체인은 LangChain의 핵심입니다. 이는 단순히 특정 순서로 실행되는 구성 요소 체인입니다.

이러한 체인 중 가장 간단한 것은 LLMChain입니다. 이는 사용자의 입력을 받아 체인의 첫 번째 요소(PromptTemplate)에 전달하여 입력을 특정 프롬프트로 형식화하는 방식으로 작동합니다. 그러면 형식이 지정된 프롬프트가 체인의 다음(그리고 마지막) 요소인 LLM으로 전달됩니다.

In [ ]:
import inspect
import re

from getpass import getpass
from langchain import OpenAI, PromptTemplate
from langchain.chains import LLMChain, LLMMathChain, TransformChain, SequentialChain
from langchain.callbacks import get_openai_callback

이 노트북을 실행하려면 OpenAI LLM을 사용해야 합니다. 여기에서는 전체 노트북에 사용할 LLM을 설정합니다. 메시지가 표시되면 openai api 키를 입력하기만 하면 됩니다.

In [ ]:
OPENAI_API_KEY = getpass()
In [ ]:
llm = OpenAI(
    temperature=0, 
    openai_api_key=OPENAI_API_KEY
    )

우리가 사용할 추가 유틸리티는 각 호출에서 사용하는 토큰 수를 알려주는 아래 함수입니다. 이는 API(예: 에이전트)를 여러 번 호출할 수 있는 보다 복잡한 도구를 사용함에 따라 점점 더 중요해지는 좋은 방법입니다. 예상치 못한 지출을 피하기 위해 우리가 지출하는 토큰 수를 면밀히 통제하는 것이 매우 중요합니다.

In [ ]:
def count_tokens(chain, query):
    with get_openai_callback() as cb:
        result = chain.run(query)
        print(f'Spent a total of {cb.total_tokens} tokens')

    return result

체인이란 무엇인가요?

정의: 체인은 이 lib의 기본 구성 요소 중 하나입니다.

체인의 공식적인 정의는 다음과 같습니다.

체인은 기본 체인일 수도 있고 다른 체인일 수도 있는 링크로 구성됩니다. 기본 요소는 prompt, llms, utils 또는 기타 체인일 수 있습니다.

따라서 체인은 기본적으로 특정 프리미티브 조합을 사용하여 입력을 처리하는 pipeline입니다. 직관적으로 보면 '단계'라고 생각하면 됩니다. 입력에 대해 특정 작업 집합을 수행하고 결과를 반환합니다. LLM을 통한 프롬프트 기반 전달부터 텍스트에 Python 함수를 적용하는 것까지 무엇이든 될 수 있습니다.

체인은 유틸리티 체인, 일반 체인, 결합 문서 체인의 세 가지 유형으로 나뉩니다. 이번 판에서는 세 번째 부분이 너무 구체적이기 때문에 처음 두 가지 부분에 초점을 맞추겠습니다.

  • Utility Chains: 일반적으로 매우 좁은 목적으로 LLM에서 특정 답변을 추출하는 데 사용되며 즉시 사용할 수 있는 체인입니다.
  • Generic Chains: 다른 체인의 빌딩 블록으로 사용되지만 자체적으로는 사용할 수 없는 체인입니다.

Utility Chains

LLMMathChain은 llms에 수학을 수행하는 기능을 제공합니다. 어떻게 작동하는지 살펴보겠습니다!

In [ ]:
llm_math = LLMMathChain(llm=llm, verbose=True)

count_tokens(llm_math, "13의 .3432제곱은 무엇인가요?")

체인은 자연어로 질문을 받아 LLM으로 보냈습니다. llm은 우리에게 답변을 제공하기 위해 체인이 컴파일한 Python 코드를 반환했습니다. 몇 가지 질문이 생깁니다. llm은 우리가 Python 코드를 반환하기를 원한다는 것을 어떻게 알았습니까?

Prompt 입력

입력은 더 넓은 컨텍스트에 삽입되어 우리가 보내는 입력을 해석하는 방법에 대한 정확한 지침을 제공합니다. 이를 프롬프트라고 합니다. 이 체인의 프롬프트가 무엇인지 살펴보겠습니다!

In [ ]:
print(llm_math.prompt.template)
In [ ]:
# 우리가 묻는 질문만 받도록 프롬프트를 설정했습니다.
prompt = PromptTemplate(input_variables=['question'], template='{question}')
llm_chain = LLMChain(prompt=prompt, llm=llm)

# 우리는 내용 없이 LLM에 답변을 요청합니다.

count_tokens(llm_chain, "What is 13 raised to the .3432 power?")

통찰력: 프롬프트를 지능적으로 사용하면 LLM이 특정 상황에서 작동하도록 명시적이고 의도적으로 프로그래밍하여 일반적인 함정을 피하도록 할 수 있습니다.
이 체인의 또 다른 흥미로운 점은 llm을 통해 입력을 실행할 뿐만 아니라 나중에 Python 코드를 컴파일한다는 것입니다. 이것이 어떻게 작동하는지 정확히 살펴보겠습니다.

In [ ]:
print(inspect.getsource(llm_math._call))

따라서 여기서는 llm이 Python 코드를 반환하면 Python REPL* 시뮬레이터를 사용하여 이를 컴파일한다는 것을 알 수 있습니다.

*Python REPL(Read-Eval-Print Loop)은 Python 코드를 한 줄씩 실행하기 위한 대화형 셸입니다.

또한 여기에서 langchain을 특별하게 만드는 핵심 개념인 체인 구성의 첫 번째 예를 볼 수 있습니다. 우리는 호출 시 ('일반 체인')을 초기화하고 사용하는 LLMMathChain를 사용하고 있습니다. 우리는 이러한 구성을 임의의 수만큼 만들 수 있으며 효과적으로 '체인'할 수 있습니다. 매우 복잡하고 사용자 정의 가능한 동작을 달성하기 위해 이러한 체인이 많이 있습니다.LLMChain

유틸리티 체인은 일반적으로 이와 동일한 기본 구조를 따릅니다. 즉, 주어진 쿼리에서 매우 구체적인 유형의 응답을 반환하도록 llm을 제한하는 프롬프트가 있습니다. 우리는 llm에게 SQL 쿼리, API 호출을 생성하고 심지어 즉시 Bash 명령을 생성하도록 요청할 수 있습니다

Generic chains

langchain에는 3개의 일반 체인만 있으며 동일한 예에서 모두 보여 드리겠습니다.

먼저, 텍스트의 간격을 정리하기 위한 사용자 정의 변환 함수를 구축하겠습니다. 그런 다음 이 함수를 사용하여 텍스트를 입력하고 깨끗한 텍스트를 출력으로 기대하는 체인을 구축합니다.

In [ ]:
def transform_func(inputs: dict) -> dict:
    text = inputs["text"]
    
    # replace multiple new lines and multiple spaces with a single one
    text = re.sub(r'(\r\n|\r|\n){2,}', r'\n', text)
    text = re.sub(r'[ \t]+', ' ', text)

    return {"output_text": text}

중요한 것은 체인을 초기화할 때 llm을 인수로 보내지 않는다는 것입니다. 상상할 수 있듯이, LLM이 없으면 이 체인의 능력이 앞서 본 예보다 훨씬 약해집니다. 그러나 이 체인을 다른 체인과 결합하면 매우 바람직한 결과를 얻을 수 있습니다.

In [ ]:
clean_extra_spaces_chain = TransformChain(input_variables=["text"], output_variables=["output_text"], transform=transform_func)
In [ ]:
clean_extra_spaces_chain  # 출처에 보이는 출력과 내용이 다름

체인을 사용하여 입력 텍스트를 정리한 다음 시인이나 경찰관과 같이 입력 내용을 특정 스타일로 바꾸어 표현한다고 가정해 보겠습니다. 이제 우리가 알고 있듯이 TransformChain은 llm을 사용하지 않으므로 스타일 지정은 다른 곳에서 수행해야 합니다. 이것이 바로 우리의 LLMChain가 필요한 곳입니다.

In [ ]:
template = """Paraphrase this text:

{output_text}

In the style of a {style}.

Paraphrase: """
prompt = PromptTemplate(input_variables=["style", "output_text"], template=template)

다음으로 체인을 초기화합니다.

In [ ]:
style_paraphrase_chain = LLMChain(llm=llm, prompt=prompt, output_key='final_output')

템플릿의 입력 텍스트는 'output_text'라고 합니다. 이유를 짐작할 수 있나요? TransformChain의 출력을 LLMChain!에 전달하겠습니다.
마지막으로 두 가지를 결합하여 하나의 통합 체인으로 작동해야 합니다. 이를 위해 세 번째 일반 체인 빌딩 블록인 SequentialChain을 사용합니다.

In [ ]:
sequential_chain = SequentialChain(chains=[clean_extra_spaces_chain, style_paraphrase_chain], input_variables=['text', 'style'], output_variables=['final_output'])
In [ ]:
input_text = """
Chains allow us to combine multiple 


components together to create a single, coherent application. 

For example, we can create a chain that takes user input,       format it with a PromptTemplate, 

and then passes the formatted response to an LLM. We can build more complex chains by combining     multiple chains together, or by 


combining chains with other components.
"""
In [ ]:
count_tokens(sequential_chain, {'text': input_text, 'style': 'a 90s rapper'})

"\n체인을 사용하면 여러 조각을 연결하여 하나의 멋진 앱을 만들 수 있습니다. 마찬가지로 사용자 입력을 받아 PromptTemplate으로 스타일을 지정한 다음 LLM에 전달할 수 있습니다. 여러 체인을 결합하거나 혼합하여 더욱 창의적으로 만들 수 있습니다. 다른 구성 요소와 체인을 연결합니다."

langchain-hub에 대한 참고 사항

langchain-hub은 langchain의 자매 라이브러리로, 여기서 모든 체인, 에이전트 및 프롬프트가 직렬화되어 사용할 수 있습니다.

In [ ]:
from langchain.chains import load_chain

LLMMathChain를 사용하여 이를 수행하는 방법을 살펴보겠습니다.

In [ ]:
llm_math_chain = load_chain('lc://chains/llm-math/chain.json')

일부 구성 매개변수를 변경하려면 어떻게 해야 합니까? 로드한 후에 간단히 재정의할 수 있습니다.

In [ ]:
llm_math_chain.verbose
In [ ]:
llm_math_chain.verbose = False
In [ ]:
llm_math_chain.verbose
In [ ]:
출처 : https://github.com/pinecone-io/examples/blob/master/learn/generation/langchain/handbook/02-langchain-chains.ipynb

'langchain' 카테고리의 다른 글

04-langchain-chat  (0) 2024.01.13
03a-token-counter  (0) 2024.01.12
03-langchain-conversational-memory  (2) 2024.01.11
01-langchain-prompt-templates  (1) 2024.01.09
00-langchain-intro(한글)  (0) 2024.01.08