강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

이성규님의 프로필 이미지
이성규

작성한 질문수

AI 에이전트로 구현하는 RAG 시스템(w. LangGraph)

섹션 5, 사용자 정의 조건부 엣지 관련 질문입니다.

작성

·

88

·

수정됨

0

from langgraph.graph import MessagesState, StateGraph, START, END
from langchain_core.messages import HumanMessage, SystemMessage
from langgraph.prebuilt import ToolNode
from IPython.display import Image, display

# LangGraph MessagesState 사용
class GraphState(MessagesState):
    pass

# 노드 구성 
def call_model(state: GraphState):
    system_message = SystemMessage(content=system_prompt)
    messages = [system_message] + state['messages']
    response = llm_with_tools.invoke(messages)
    return {"messages": [response]}

def should_continue(state: GraphState):
    last_message = state["messages"][-1]
    # 도구 호출이 있으면 도구 실행 노드로 이동
    if last_message.tool_calls:
        return "execute_tools"
    # 도구 호출이 없으면 답변 생성하고 종료 
    return END

# 그래프 구성
builder = StateGraph(GraphState)
builder.add_node("call_model", call_model)
builder.add_node("execute_tools", ToolNode(tools))

builder.add_edge(START, "call_model")
builder.add_conditional_edges(
    "call_model", 
    should_continue,
    {
        "execute_tools": "execute_tools",
        END: END
    }
)
builder.add_edge("execute_tools", "call_model")

graph = builder.compile()

# 그래프 출력 
display(Image(graph.get_graph().draw_mermaid_png()))
# 그래프 실행
inputs = {"messages": [HumanMessage(content="스테이크 메뉴의 가격은 얼마인가요?")]}
messages = graph.invoke(inputs)

위 코드는 강사님께서 제공해주신 코드를 가져온 것입니다.

제가 궁금한 것은 Tool 노드를 사용하고 다시 call_model 노드로 왔을 때 SytemMessage가 중복되지 않을까? 라는 생각을 했습니다.

 

예를 들어 message : [유저 인풋] 가 처음으로 그래프에 들어오게된다면

def call_model(state: GraphState):
    system_message = SystemMessage(content=system_prompt)
    messages = [system_message] + state['messages']
    response = llm_with_tools.invoke(messages)
    return {"messages": [response]}

message : SystemMessage + [유저 인풋]

이 될것입니다.

그 이후 response를 호출하여

message : SystemMessage + [유저 인풋] + toolMessage

이 되어 상태를 업데이트 하고,

 

그리고 tool 콜이 있어서 툴노드를 마무리 한 이후 돌아왔을 땐 GraphState에 있는 message는 SystemMessage + [유저 인풋] + toolMessage + [툴이보낸 메세지] 일테니

call model 노드에서

SystemMessage + SystemMessage + [유저 인풋] + toolMessage + [툴이보낸 메세지]

가 적용되어 툴 콜 할때마다 SytemMessage가 쌓이는 구조가 되지 않을까 생각이 들었는데 맞을까요?

 

 

답변 1

0

판다스 스튜디오님의 프로필 이미지
판다스 스튜디오
지식공유자

안녕하세요! 좋은 질문입니다.

우려하신 부분은 이해가 됩니다. 그러나 이 코드에서는 시스템 메시지가 중복되어 쌓이지 않습니다.

  1. call_model 함수 내부를 보면:

    def call_model(state: GraphState):
        system_message = SystemMessage(content=system_prompt)
        messages = [system_message] + state['messages']
        response = llm_with_tools.invoke(messages)
        return {"messages": [response]}
    
  2. 중요한 부분은 return {"messages": [response]} 입니다. 이 부분이 상태를 어떻게 업데이트하는지가 중요합니다.

  3. MessagesState는 메시지 배열을 관리하는 특별한 상태 클래스인데, return {"messages": [response]} 코드는 기존 메시지를 대체하지 않고 추가합니다.

  4. 하지만 system_message는 매번 함수 호출시 새로 생성되어 임시로 메시지 목록에 추가되고, 상태에는 중복 저장되지 않습니다.

  5. 최종 상태에 저장된 messages 속성의 목록을 확인해보시면 됩니다.



    감사합니다.

     

이성규님의 프로필 이미지
이성규

작성한 질문수

질문하기