1일 1개념정리 24.08.09.금 ~
큰 결정에 큰 동기가 따르지 않을 때도 있다. 하지만 큰 결심이 따라야 이뤄낼 수 있다.
무조건 무조건 1일 1개의 개념 정리하기 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#39. LangChain
랭체인이란 무엇인고 ... 예전에 잠깐 언급했었다.
프롬프트 엔지니어링을 할 때 사용하는 기법정도로 소개했는데, 좀 더 깊게 프로젝트에서 사용해야하는 상황이라 공부할겸 정리해보겠다.
LangChain
랭체인은 NLP 개발시 LLM을 쉽게 활용할 수 있게 하는 프레임워크이다. gpt3, gpt4 이런 LLM을 사용할 때 함께 활용된다. 랭체인의 주요 목적은 한마디로 사용자 요구에 따라 맞춤형으로 활용될 수 있도록 설계된 워크플로우를 제공하는 것이다. AI 기반 챗봇, 어시스턴트를 만들거나 자동화 처리, 그리고 문서 요약 및 질의응답 등에 이용될 수 있다.
주요 구성 요소
랭체인의 구성 요소는 보통 체인, 에이전트, 메모리, 프롬프트 템플릿 등으로 나뉜다.
1. Chain : 체인은 여러 자연어 처리 작업들을 연결하는 파이프라인이다. 예를 들어 입력받은 텍스트를 처리하고 결과를 다른 시스템에 전달하는 과정을 체인화할 수 있다. 여기엔 단일 체인과 멀티스텝 체인이 있다.
- 단일 체인 : 하나의 프롬프트나 질문을 모델에 전달하고, 그 결과를 반환하는 단순한 체인이다.
- 멀티 스텝 체인 : 여러 단계의 작업이 포함된 복잡한 워크플로우에 사용된다. 예를 들어 텍스트를 먼저 분석하고 요약하고, 이 요약을 다시 다른 곳에 사용하는 등의 방식이다.
from langchain.chains import SimpleChain, SequentialChain
# 단일 체인
chain = SimpleChain(llm, prompt="What's the capital of France?")
result = chain.run("France")
# 멀티 스텝 체인
seq_chain = SequentialChain(chains=[step1, step2, step3])
result = seq_chain.run(input_data)
2. Agent : 에이전트는 다양한 툴과 상호작용하면서 사용자의 요청에 따라 적절한 동작을 수행하는 시스템인데, 단순히 프롬프트를 처리하는 것을 넘어서, 외부 API와 통신하거나, 파일 시스템, DB 등에 접근하여 필요한 데이터를 얻는다.
# 도구와 에이전트 설정
tools = [search_tool, calculator_tool]
agent = initialize_agent(tools)
# 에이전트를 통해 도구 사용
agent.run("What is the population of Tokyo?")
3. Memory : 메모리는 대화의 문맥을 기억하는 기능을 제공한다. 사실 챗봇같은 곳에선 이게 정말 중요하다. 메모리를 사용하면 사용자의 이전 입력을 기억하고, 이를 바탕으로 일관성 있는 대화를 유지할 수 있다.
- 단기 메모리 : 특정 세션 동안만 정보를 유지하고, 세션이 끝나면 정보가 사라진다.
- 장기 메모리 : 여러 세션에 걸쳐 정보를 유지하여, 사용자가 이전에 했던 질문이나 대화를 기억할 수 있다.
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
memory.save_context({"input": "What is the capital of Japan?"}, {"output": "Tokyo"})
# 대화 중간에 기억을 불러와서 사용할 수 있음
print(memory.load_context())
4. Prompt Template : 프롬프트 템플릿은 프롬프트 엔지니어링을 쉽게 할 수 있도록 도와주는 도구이다. 사용자 입력을 바탕으로 동적으로 프롬프트를 생성하는 데 사용된다. 특정 구조나 패턴을 가진 프롬프트를 미리 정의하고, 필요한 변수에 따라 프롬프트를 유연하게 생성할 수 있다.
from langchain.prompts import PromptTemplate
template = "Translate the following text to {language}: {text}"
prompt = PromptTemplate(input_variables=["language", "text"], template=template)
# 템플릿에 동적 값 채워넣기
formatted_prompt = prompt.format(language="Spanish", text="Hello, how are you?")
print(formatted_prompt)
앞서 3번 메모리를 설명할 때, ConversationBufferMemory에 기억 정보를 저장한다고 말했다. 구체적으로 어떻게 저장될까 ?? 사실 내 제일 큰 관심사는 3번 메모리와 4번 템플릿이다. 이 두개에 대해 자세히 알아보자.
ConversationBufferMemory
1. 저장되는 데이터의 형태 : ConversationBufferMemory는 입출력 쌍을 딕셔너리로 저장한다. 즉 사용자가 질문한 내용과 그에 대한 AI의 응답을 순서대로 기록하는 방식이다. 각 대화는 {"input": 사용자 입력, "output": AI 응답} 형식으로 딕셔너리로 저장된다.
2. 버퍼 : ConversationBufferMemory에서는 대화가 진행될수록 새 대화가 버퍼에 쌓이는 형태로(데이터가 순차적으로 저장되는 형태) 관리된다. 즉 모든 대화가 누적되어 저장되며, 나중에 이 메모리를 불러오면 대화의 흐름 전체를 그대로 확인할 수 있다.
3. 저장 & 로드 방식
- save_context : 사용자의 입력과 AI의 답변을 저장하고, 이는 내부적으로는 딕셔너리로 관리된다.
- load_context : 지금까지 저장된 "모든 대화 기록"이 list 형태로 반환된다. 그니까, list 형식으로 반환되지만 각 element들은 딕셔너리형태의 대화라고 생각하면 된다.
from langchain.memory import ConversationBufferMemory
# 메모리 생성
memory = ConversationBufferMemory()
# 대화 저장: 사용자가 "What is the capital of Japan?"라고 질문하고, 모델이 "Tokyo"라고 답변
memory.save_context({"input": "What is the capital of Japan?"}, {"output": "Tokyo"})
# 저장된 대화 불러오기
print(memory.load_context())
# 실제 저장된 데이터 예시 (딕셔너리 형태)
[
{"input": "What is the capital of Japan?", "output": "Tokyo"},
{"input": "What is the population of Tokyo?", "output": "Around 14 million"},
....
]
Prompt Template
프롬프트 템플릿은 프롬프트 엔지니어링을 효율적으로 수행하기 위한 도구이다. 특정 구조를 미리 정의하고 필요한 변수만 동적으로 삽입하여 프롬프트를 생성하는 방법이다. 즉, 다양한 입력이 들어와도 일정한 형식으로 답변할 수 있다. 사용법 예시를 보자.
먼저 템플릿을 정의하고, 이를 바탕으로 값을 넣어 프롬프트를 생성한다.
from langchain.prompts import PromptTemplate
# 템플릿 정의
template = "Translate the following text to {language}: {text}"
# PromptTemplate 객체 생성
prompt = PromptTemplate(input_variables=["language", "text"], template=template)
# 템플릿에 값을 넣어 완전한 프롬프트 생성
formatted_prompt = prompt.format(language="Spanish", text="Hello, how are you?")
print(formatted_prompt)
더 복잡한 경우 어떻게 할까 ??
from langchain.prompts import PromptTemplate
# 복잡한 템플릿
template = """
You are a {role}. # ex) teacher
Your task is to help the user with {task}.
Please provide a detailed response based on the following context: {context}.
"""
# 템플릿 인스턴스 생성
prompt = PromptTemplate(input_variables=["role", "task", "context"], template=template)
# 변수 입력
formatted_prompt = prompt.format(role="customer service agent", task="resolving an issue",
context="The user has a problem with their internet connection.")
print(formatted_prompt)
이를 통해 일관성, 재사용성, 최적화가 가능하며, 복잡한 자연어 작업에도 쉽게 적용할 수 있다.
'1일 1개념정리 (24년 8월~) > AI' 카테고리의 다른 글
1일1개 (71) - 아임 파인 튜닝 앤유 ? (0) | 2024.10.27 |
---|---|
1일1개 (57) - 생각의 사슬. (이름 간지) (4) | 2024.10.11 |
1일1개 (42) - 랭체인 메모리 관리 모듈 (0) | 2024.09.26 |
1일1개 (9) - 프롬프트 엔지니어링도 언어인가요 (2) | 2024.08.17 |