작성
·
70
·
수정됨
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
안녕하세요! 좋은 질문입니다.
우려하신 부분은 이해가 됩니다. 그러나 이 코드에서는 시스템 메시지가 중복되어 쌓이지 않습니다.
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]}
중요한 부분은 return {"messages": [response]}
입니다. 이 부분이 상태를 어떻게 업데이트하는지가 중요합니다.
MessagesState는 메시지 배열을 관리하는 특별한 상태 클래스인데, return {"messages": [response]}
코드는 기존 메시지를 대체하지 않고 추가합니다.
하지만 system_message
는 매번 함수 호출시 새로 생성되어 임시로 메시지 목록에 추가되고, 상태에는 중복 저장되지 않습니다.
최종 상태에 저장된 messages
속성의 목록을 확인해보시면 됩니다.
감사합니다.