Langchain은 language model 기반의 application 을 개발하기 위한 framework로 두가지 특성을 가지고 있습니다.
Langchain은 이름 말그대로 chain처럼 각 component 들을 엮어 하나의 어플리케이션을 만들 수 있는 프레임워크로, 아주 쉽고 빠르게 LM Application을 개발할 수 있습니다.
Langchain 프레임워크를 통해 LM에 대한 지식이 없더라도 기존의 LM 들을 활용하여 쉽게 챗봇이나 QA봇을 만들 수 있습니다.
서버 개발 세상에서 JavaEE가 어려워 전문가의 영역으로만 느껴졌던 BackEnd 개발이 spring framework의 등장을 통해 웹 개발이 쉬워진 것이 Language Modeling 세상에도 등장했다고 보시면 될 것 같습니다.
AWS에서는 위와 같이 lanchain lambda를 이용해 생성형 AI workflow를 구성하기도 합니다. (링크)
pip install langchain
OpenAI와 함께 사용하고 싶다면, openai 도 함께 설치 후 환경 설정을 해주세요.
pip install openai
export OPENAI_API_KEY="<openai key>"
# 혹은 아래와 같이 api key를 설정해도 됨
from langchain.llms import OPENAI
llm = OPENAI(openai_api_key="...")
langchain 에서 가장 중요한것은 모듈들 입니다. 이 모듈들을 어떻게 엮냐에 따라 다양한 기능의 어플리케이션이 탄생하게 됩니다.
1) Model I/O
2) Data connection
3) Chains
4) Agents
5) Memory
6) Callbacks
이제 본격적으로 OpenAI 기반의 챗봇을 하나 만들어 보면서 위 모듈들에 대해 하나하나 알아보겠습니다.
챗봇을 만들 수 있는 방법은 정말 다양합니다.
어떻게 Langchain에서 모듈들이 chain으로 엮이는지 먼저 볼게요.
langchain의 llms 모듈은 말그대로 LM 모델을 연결(Wrapping) 해주는 역할을 합니다.
OpenAI, Cohere, Anthropic을 포함하여 Custom LM 까지 이 모듈을 이용해 Langchain의 chain 들과 연결할 수 있습니다.
from langchain.llms import OpenAI
llm = OpenAI(temperature=0.9)
llm.predict("대한민국 수도는 어디야?")
>> \n\n대한민국 수도는 서울입니다.'
langchain의 chat_models는 앞선 llms 보다 더 추상적인 wrapping class 입니다.
말그대로 chat을 위해 위의 llm을 감싸서 일관된 형태(스키마)의 메세지들을 주고 받을 수 있도록 했다고 보시면 됩니다.
from langchain.chat_models import ChatOpenAI
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
chat = ChatOpenAI(temperature=0.9)
chat.predict_messages([HumanMessage(content="이 문장을 영어로 번역해줘. 난 프로그래밍 공부를 열심히 할거야")])
여기서 AIMessage, HumanMessage, SystemMessage가 등장하는데 각각의 역할을 다음과 같습니다.
SystemMessage : 시스템 (bot) 에게 보내는 메세지로 보통 역할을 부여하는 데 쓰입니다.
AIMessage : Bot이 답한 답변으로, openai의 api는 사실 session이 없기 때문에 api를 던질 때 앞선 질> 문에 대한 답변을 이 메세지를 통해 content에 붙여줌으로써 히스토리를 관리함.
HumanMessage : Human (사용자)가 묻고자 하는 메세지
Langchain에서는 이 message들을 템플릿화해서 더 쉽게 쓸 수 있도록 MessageTemplate 들도 제공하고 있습니다. 템플릿을 사용하면 아래와 같이, 코드를 더 깔끔하게 비슷한 메세지들을 반복적으로 던질 수 있게 됩니다.
위에서 체인을 만들어서 run 함수를 통해 쉽게 챗봇을 만드는걸 봤으면, 이번엔 Agent 를 이용해 이렇게 얻은 대답들을 이용해 좀 더 Agent 스러운 챗봇을 만들어 보겠습니다.
LLM에서 얻은 응답을 이용해서 저희만의 서비스를 한번 만들어볼게요.
이 때, 필요한 것이 바로 Tool 이라는 개념입니다.
LLM이 아이언맨 가슴에 있는 팔라듐 이었다면, Tool은 이 팔라듐의 힘을 이용한 수트라고 볼 수 있어요.
이 Tool은 Google 검색, DB, 다른 chain 등 다양한 형태가 될 수 있습니다.
이 툴들을 이용해 최종적으로 우리가 원하는 챗봇을 만들어봅시다!
아, 우리는 예제에서는 google search api를 쓸거라 세팅부터..
SERAPI Key 발급 방법
https://serpapi.com 들어가서 가입부터 합니다. 조금 귀찮습니다.. ㅎ
견디는 자에게 복이 있나니, API Key Get..!
https://serpapi.com/dashboard
pip install google-search-results
# https://serpapi.com
export SERPAPI_API_KEY="<sepapi key>"
아쉽게도 우리의 openai 가 아주 많이 뱉는 말이 있습니다.
이 친구의 기억은 21년 9월까지에 머물러 있어, 실시간을 들어오는 오늘 날씨나 보지못한 것에 대한 Factual 한 정보는 알 수가 없습니다.
하지만, Langchain의 Agent의 모듈을 이용하면 실시간 정보를 가져와 사용자에게 뿌려줄 수 있습니다.
from langchain.agents import AgentType, initialize_agent, load_tools
from langchain.llms import OpenAI
llm = OpenAI(temperature=0)
tools = load_tools(["serpapi", "llm-math"], llm=llm)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("오늘 대한민국 가장 높은 기온이 몇도야?")
위 처리 과정을 자세히보면
저의 결과에서는 첫 Observation 결과가 시원찮았는지 Action Input에 "exact"라는 단어를 붙여서 한번 더 제대로 searching 한 후에야 만족하고 최종 Answer를 생성해 냅니다.
LLM과 외부 모듈들이 role play를 하면서 자기들끼리 소통한다고 생각하면 쉬울 것 같기도하네요.
google-search-api 하나 뿐만 아니라 math api도 함께 사용할 수 있답니다.
위와 같은 Agent를 우리는 Action Agent 라 부릅니다.
step 마다의 다음 action을 결정하는 로직의 action agent 말고, 처음부터 모든 action들의 sequence를 결정하고 수행하는 Plan-and-execute agent 도 있는데 이건 Sequence가 복잡하거나 현재상태에서 다음 step을 결정하기가 쉽지 않은 경우 사용합니다. (ex. BabyAGI BabyAGI 설명 )
사실 간단한 챗이야 괜찮지만, 실제로 현업에서 "사용자가 구매 상품에 QnA 등록 시, 답변도 해주고 history DB에도 저장하고 user 정보도 update하고.." 이런 specific하고 복잡한 flow를 가진 처리 logic이 있을 경우 Plan-and-execute agent를 통해 처리하게 될거에요.
우리는 "간단한" 챗봇이니 Action Agent만 볼게요..!
이렇게 다양한 외부 모듈을 붙여서 최종 답을 찾는 과정에 사용되는 ReAct라는 프레임워크가 있는데요, 무지성으로 사용하셔도 되긴하지만 궁금해하실 수도 있으니 간단히 짚고 넘어가자면..
일단 React.js 아닙니다! ^0^
ReAct는 (논문링크) LLM과 외부 knowledge을 아주 잘 모듈화한 아키텍처로 이해하시면 될 것 같아요.
우리가 앞에서 한 것 처럼 Action / Action Input / Observation / Thought 와 같이 LLM과 외부 Knowledge Module간의 커뮤니케이션을 Symbolic 화 하고, 이 커뮤니케이션을 N번 반복해나가면서 최종 정답을 찾는 과정입니다.
자세한건 논문 참고 ㄱㄱ
AgentType 을 보면 감이 오시겠지만, 우리는 다양한 종류의 Agent를 langchain을 통해 만들 수 있습니다.
방금 저희가 만든 대한민국 날씨 챗봇처럼 사용자의 input으로부터 zero-shot으로 정답을 찾는 AgentType 으로 가장 많이 쓰입니다.
여러 multi input에 대해 처리할 수 있도록 도와주는 agent입니다.
OpenAPI 모델에서는 사용자가 api를 이용해 fine-tune 할 수 있는데 그걸 활용한 agent 입니다.
말그대로 대화를 위한 Agent로, Tool 사용뿐만 아니라 memory를 사용해 앞선 대화의 history를 기억하는 agent 입니다.
Intermediate Answer Tool을 활용해서 말그대로 factual 한 QA를 처리하는 Agent 입니다.
이름에서도 느낌 오죠? 문서들을 임베딩해서 저장해놓은 Document store과 상호작용해서 검색하고 조회하는 agent 입니다.
각 AgentType 들에 대해 다음시간에 예제들을 통해서 더 멋진 챗봇을 만들어봅시다.
저도 개발자인데 같이 교류 많이 해봐요 ㅎㅎ! 서로 화이팅합시다!