LangGraph: Basic ChatBot

김지우·2025년 1월 18일

목차
1. 정리 배경
2. 상태(State) 정의
3. 노드(Node) 정의
4. 그래프(Graph) 정의, 노드 추가
5. 그래프 엣지 추가 및 컴파일
6. 그래프 시각화
7. 그래프 실행
8. 결론


1. 정리 배경

그렇다면 LangGraph를 활용해 간단한 챗봇부터 만들어 돌려보고 정리하며 숙달시킬 목적이다. 다음 글은 테디 노트의 유료강의를 공부하며 정리하는 것이고, 글의 내용이 부실하다고 생각하신다면 테디노트 유료강의를 구매하여 들으시면 됩니다.

2. 상태(State) 정의

from typing import Annotated, TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages


class State(TypedDict):
    # 메시지 정의(list type 이며 add_messages 함수를 사용하여 메시지를 추가)
    messages: Annotated[list, add_messages]

우선 작업을 하기 위해서는 상태를 정의해야 한다. 클래스를 만들고, TypedDict를 상속 받는다. Annotated와 add_messages를 사용해 메시지를 지속적으로 리스트에 추가할 수 있도록 한다.(챗봇이니까요)

3. 노드(Node) 정의

from langchain_openai import ChatOpenAI

# LLM 정의
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)


# 챗봇 함수 정의
def chatbot(state: State):
    # 메시지 호출 및 반환
    return {"messages": [llm.invoke(state["messages"])]}

두번째는 노드를 정의한다. 일단 ChatBot이고 LLM을 활용할 것이기 때문에, LLM을 호출한다. 노드의 경우 파이썬 함수를 통해 만들어지고, 보통 input도 output도 State다. 다면 여기서는 State에 message만 있기 때문에 다음과 같은 형태로 반환해도 문제는 없다.

4. 그래프(Graph) 정의, 노드 추가

# 그래프 생성
graph_builder = StateGraph(State)

# 노드 이름, 함수 혹은 callable 객체를 인자로 받아 노드를 추가
graph_builder.add_node("chatbot", chatbot)

그래프는 StateGraph를 이용해 정의하고, add_node를 통해 만들어둔 노드를 추가한다.

5. 그래프 엣지 추가 및 컴파일

# 시작 노드에서 챗봇 노드로의 엣지 추가
graph_builder.add_edge(START, "chatbot")
# 그래프에 엣지 추가
graph_builder.add_edge("chatbot", END)

# 그래프 컴파일
graph = graph_builder.compile()

그래프의 시작점과 끝점을 정의한다. 그리고 그래프를 실행할 수 있도록 컴파일 한다.

6. 그래프 시각화

from langchain_teddynote.graphs import visualize_graph

# 그래프 시각화
visualize_graph(graph)

그래프 시각화의 경우 테디 노트님의 코드를 그대로 썼지만 다른 시각화 방법이 있는지 찾아보고 직접 만들어 봐야 할 것 같다

7. 그래프 실행

question = "2024년  한국에서 인기 있었던 유명 걸그룹 TOP 10 추천해줘"

# 그래프 이벤트 스트리밍
for event in graph.stream({"messages": [("user", question)]}):
    # 이벤트 값 출력
    for value in event.values():
        print("Assistant:", value["messages"][-1].content)
        
=====결과=======
1. **BLACKPINK** - 글로벌 인기를 끌고 있는 걸그룹으로, 계속해서 새로운 음악과 활동으로 주목받고 있습니다.
2. **TWICE** - 오랜 시간 동안 사랑받아온 그룹으로, 다양한 콘셉트와 음악으로 팬들을 사로잡고 있습니다.
3. **IVE** - 최근 데뷔한 그룹으로, 강력한 퍼포먼스와 매력적인 음악으로 빠르게 인기를 얻고 있습니다.
4. **NewJeans** - 신선한 이미지와 독창적인 음악으로 많은 사랑을 받고 있는 신예 그룹입니다.
5. **LE SSERAFIM** - 강렬한 콘셉트와 뛰어난 실력으로 주목받고 있는 그룹입니다.
6. **(G)I-DLE** - 독창적인 음악과 강한 개성으로 많은 팬층을 형성하고 있습니다.
7. **aespa** - 메타버스와 결합된 독특한 콘셉트로 인기를 끌고 있는 그룹입니다.
8. **STAYC** - 밝고 경쾌한 음악으로 많은 사랑을 받고 있는 신예 그룹입니다.
9. **MOMOLAND** - 히트곡을 여러 곡 보유하고 있으며, 여전히 많은 팬들에게 사랑받고 있습니다.
10. **WJSN (Cosmic Girls)** - 다양한 음악 스타일과 매력적인 비주얼로 꾸준한 인기를 얻고 있는 그룹입니다.

여기서 주목해야 할점은 2가지야. 첫번째는 인풋으로 State와 똑같은 Dict으로 메시지를 받았다는 것이고, 두번째는 Stream이라는 메소드로 결과를 도출했는데, 글자가 하나씩 나오는 느낌으로 보이는 것이 아니라 모든 결과가 한번에 나왔다는 것이다.

왜냐하면 그래프에서 Stream은 글자를 하나씩 보여주는 효과를 보여주겠다는 것이 아니라 그래프 안의 Node가 여러번 시행될 때, 각 노드의 결과를 순서대로 보여주겠다는 것이다.

다만 여기서는 노드가 1개고 1번만 시행되기 때문에 결과가 한번에 나온다.

invoke로도 결과를 도출할 수 있는데, 그것은 다음과 같이 동작한다.

result = graph.invoke({"messages": [("user", question)]})
print(result)
======결과=====
이 리스트는 시간이 지나면서 변동이 있을 수 있으며, 각 그룹의 활동에 따라 인기도가 달라질 수 있습니다.
{'messages': [HumanMessage(content='2024년  한국에서 인기 있었던 유명 걸그룹 TOP 10 추천해줘', additional_kwargs={}, response_metadata={}, id='7a1e3751-aa10-44a8-becd-d756d968b891'), AIMessage(content='2024년 한국에서 인기 있었던 유명 걸그룹 TOP 10을 추천해드릴게요. 이 리스트는 2023년까지의 트렌드와 활동을 바탕으로 한 예측입니다.\n\n1. **BLACKPINK** - 글로벌 인기를 끌고 있는 걸그룹으로, 계속해서 새로운 음악과 활동으로 주목받고 있습니다.\n2. **TWICE** - 오랜 시간 동안 사랑받아온 그룹으로, 다양한 콘셉트와 음악으로 팬들을 사로잡고 있습니다.\n3. **IVE** - 최근  
데뷔한 그룹으로, 강력한 퍼포먼스와 매력적인 음악으로 빠르게 인기를 얻고 있습니다.\n4. **NewJeans** - 신선한 이미지와 독창적인 음악으로 많은 사랑을 받고 있는 신예 그룹입니다.\n5. **LE SSERAFIM** - 강렬한 콘셉트와 뛰어난 실력으로 주목받고 있는 그룹입니다.\n6. **(G)I-DLE** - 독창적인 
음악과 강한 개성으로 많은 팬층을 형성하고 있습니다.\n7. **aespa** - 메타버스와 결합된 독특한 콘셉트로 인기를 끌고 있는 그룹입니다.\n8. **STAYC** - 밝고 경쾌한 음악으로 많은 사랑을 받고 있는 신예 그룹입니다.\n9. **MOMOLAND** - 히트곡으로 많은 인기를 얻었던 그룹으로, 여전히 활발한 활
동을 이어가고 있습니다.\n10. **WJSN (Cosmic Girls)** - 다양한 음악 스타일과 매력적인 비주얼로 꾸준한 인기를 얻고 있는 그룹입니다.\n\n이 리스트는 시간이 지나면서 변동이 있을 수 있으니, 최신 정보를 확인하는 것도 좋습니다!', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 387, 'prompt_tokens': 26, 'total_tokens': 413, 'completion_tokens_details': {'accepted_prediction_tokens': 0, 'audio_tokens': 0, 'reasoning_tokens': 0, 'rejected_prediction_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0}}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_72ed7ab54c', 'finish_reason': 'stop', 'logprobs': None}, id='run-904f3344-3781-499f-b10b-02fd02fd6b8b-0', usage_metadata={'input_tokens': 26, 'output_tokens': 387, 'total_tokens': 413, 'input_token_details': {'audio': 0, 'cache_read': 0}, 'output_token_details': {'audio': 0, 'reasoning': 0}})]}

8. 결론

다음 게시물을 통해서 LangGraph의 그래프를 만드는 연습과 과정을 공부할 수 있었다.
상태 정의 - 노드 정의 - 그래프 생성과 노드 추가 - 시작과 끝을 정의하고 엣지 추가 - 그래프 컴파일 - 그래프 시각화 - 그래프 실행으로 작동할 수 있다.

profile
프로그래밍 기록 + 공부 기록

0개의 댓글