Notice
Recent Posts
Today
Total
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
관리 메뉴

나름개발블로그

LangChain #4 본문

A/ML

LangChain #4

성남개발자 2024. 6. 10. 18:00

정신없이 지나다가 정리하는게 늦어 졌다. 간단하게 랭체인을 챗봇을 만들어보려고 한다. 튜토리얼에 있는 내용을 직접해보면서 내가 느낀점을 정리한다.

 

llm 은 간단하게 ollama를 이용해 llama3 7b를 이용 하겠다. 다른 llm api를 이용해서 사용해도 무관 하다.

아래 예제는 기존 대화를 심플하게 넣어줘서 응답을 받는 형식의 예제다.

from langchain_community.llms import Ollama
from langchain_core.messages import HumanMessage
from langchain_core.messages import AIMessage

llm = Ollama(temperature=0, model="llama3")
response = llm.invoke(
    [
        HumanMessage(content="Hi! I'm Bob"),
        AIMessage(content="Hello Bob! How can I assist you today?"),
        HumanMessage(content="What's my name?"),
    ]
)

print(response)

위 소스를 보면 모델을 불러오고 , 메시지로 이름을 전달 한 후에 이름을 묻는 형식이다. 대화 내용을 다른 곳에 저장하고 있다라고 가정하면 ( 예를 들면 메모리나 디비) , 저장된 이력을 불러와서 한번에 넣어두면 된다. 랭체인에서는 그런걸 알아서? 편하게 해주는 모듈이 존재한다.

 

아래 예제를 보자 

from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_models import ChatOllama

llm = ChatOllama(temperature=0, model="llama3")
store = {}

def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]


with_message_history = RunnableWithMessageHistory(llm, get_session_history)

config = {"configurable": {"session_id": "abc2"}}

response = with_message_history.invoke(
    [HumanMessage(content="Hi! I'm Bob")],
    config=config,
)

print(response.content)


response = with_message_history.invoke(
    [HumanMessage(content="What's my name?")],
    config=config,
)

print(response.content)

 

처음에는 llm을 선언해준다. 여기서 중요한게 ChatOllama를 import 했다. 그냥 ollama로 해보니 에러를 뱉길래 찾아보니 chat 관련한 llm 객체를 따로 구현 해놓은것을 확인했다. 응닶값의 포맷이 달라서 생기는 에러였다.

다시 소스를 보면 세션 id를 가지고 히스토리를 저장을 한다. 세션 id 에 따라 다른 대화 내용을 저장하고 있다가 응용할 수 있다.

 

추가로 템플릿을 이용한 예제를 보자

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

prompt = ChatPromptTemplate.from_messages(
    [
        (
            "system",
            "You are a helpful assistant. Answer all questions to the best of your ability in {language}.",
        ),
        MessagesPlaceholder(variable_name="messages"),
    ]
)

chain = prompt | llm

with_message_history = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key="messages",
)

response = with_message_history.invoke(
    {"messages": [HumanMessage(content="hi! I'm todd")], "language": "Spanish"},
    config=config,
)

print(response.content)

response = with_message_history.invoke(
    {"messages": [HumanMessage(content="whats my name?")], "language": "Spanish"},
    config=config,
)

print(response.content)

chat template을 가져와서 language 와 messages를 가변으로 만들었다. 템플릿에 지정한 것처럼 언어랑 메시지를 준다. 스페인어로 대답을 하게된다.

 

 

마지막으로 필터링 하는 예제소스를 보자

from langchain_core.runnables import RunnablePassthrough


def filter_messages(messages, k=10):
    return messages[-k:]


chain = (
    RunnablePassthrough.assign(messages=lambda x: filter_messages(x["messages"]))
    | prompt
    | model
)

RunnablePassthrough 를 넣어서 메시지를 10개 안으로 줄여서 집어넣게 만들었다. 여기서 보면 내부를 보지 않아도 어떤식으로 구성 되어있는지 대충 짐작이가는데, 메시지를 저장하고 있다가 llm으로 넘겨주는 사실을 알 수 있다.물론 직접 소스를 확인도 해봣을때 딱 생각한대로 구성이 되어있었다. 이와 같은 기능을 이용하면 다양하게 응용이 가능하다.

 

지금까지 해본것을 api 서버로 잘 엮어보면 간단한 챗봇을 순식간에 만들것이라 생각된다. 유저id 히스토리를 관리해서 다양한 방법으로 응용 가능하다. 예전에 챗봇을 만든다고 학습해보고 그런 기억이 있는데 이제는 그냥 순식간에 만들어버리니 편한 세상이다.

'A > ML' 카테고리의 다른 글

LangChain #3  (0) 2024.05.24
LangChain #2  (2) 2024.05.21
임베딩 / 벡터 db  (0) 2024.05.15
LangChain #1  (0) 2024.05.14
LLM - intro  (0) 2024.05.13
Comments