해결된 질문
작성
·
74
0
3.7 찐 Multi-Agent System (feat. create_react_agent) 에 구현하신 def supervisor_node안에
messages = [
{"role": "system", "content": system_prompt},
] + state["messages"]
해당 소스 Message에 system을 이렇게 선언하는게 맞는지 이해가 가질 않습니다. 선생님 설명에서는 analyst_node안에 invoke할 때 supervisor_node안에 넣었던 systemprompt는 불필요해서 아래 소스처럼
result = analyst_chain.invoke({'messages': state['messages'][1:]})
[1:]를 하신다고 설명하셨는데 analyst_node 안에서 state['messages']를 print함수로 확인해 봤더니 systemmessage가 들어있지 않았습니다. messagestatas에 messages에 system메세지를 추가하기 위해서 고민하다 systemMessage를 넣었더니 선생님 설명대로 됐지만 무슨 차이인지 잘 모르겠습니다. 아마 예상하기에는 MessageState가 SystemMessage, AIMessage, HumanMessage 밖에 허용을 안 하는 것 같은데 맞나요? 어떤게 올바른 방법인가요?
messages = [
SystemMessage(content=system_prompt),
] + state["messages"]
답변 2
0
안녕하세요, 좋은 질문 감사합니다! 질문에 대해 답변을 드려보자면,
system_prompt
에 작성된 내용을 보시면, supervisor를 타겟으로 node간의 소통을 관제하는 내용
만 작성된 내용이기 때문에 굳이 다른 node들에서 사용될 필요가 없어서 supervisor에서만 리스트를 확장하는 식으로 LLM을 호출한다고 보시면 됩니다. supervisor는 우리가 에이전트를 통해서 받고자하는 답변을 생성한다기 보다는, 다음에 어떤 노드를 호출할지만 결정하기 때문입니다.
analyst_node에서 확인하신 부분은 저도 검증해보니 system message는 빠져있네요. 제가 설명을 잘못한 것 같은데, 각 node들의 결과만 analyst_node
로 전달하면서 토큰을 아끼는 절차 정도로 봐주시면 될 것 같습니다.
MessagesState
는 List[AnyMessage]
의 형태이기 때문에 말씀하신 SystemMessage
, HumanMessage
, AIMessage
외 추가로 ToolMessage
를 받을 수 있습니다.
혹시 제가 질문을 제대로 이해하지 못해서 설명이 부족하거나 추가로 설명이 필요한 부분이 있으시면 말씀해주세요!
노드 결정 로직은 LLM이 판단하는 부분이기 때문에 정확하게 이러한 방식으로 이루어집니다
라고 말씀드리기는 어렵지만. 대략적으로 아래와 같은 흐름으로 이루어집니다
LLM은 주어진 메시지를 읽고, 사용자 질문이 해결되었는지 또는 해결하기 위해 추가 정보가 필요한지 판단합니다.
저희가 state["messages"]
에 담은 이력이 여기에 해당합니다.
만약 질문이 명확히 해결되지 않은 경우:
LLM은 다음으로 호출할 적합한 노드를 제안합니다.
랭그래프의 경우 Command(goto=goto)
에 해당합니다
만약 질문이 해결된 경우:
LLM은 "FINISH"
라는 명령어를 사용하여 대화를 종료하도록 안내할 수 있습니다.
랭그래프의 경우 Command(goto=goto)
에 해당합니다
따라서 "유사도" 확인이라기 보다는 맥락을 파악해서 결정한다고 보시는 편이 맞습니다. 추가로 궁금한 점이 있으시면 말씀해주세요!
선생님 답변 너무 감사드립니다.! message에서 궁금한게 하나 더 있어 여쭤보겠습니다.
아래소스에 각각 3개의 node의 return command에서 AIMessag를 사용하는게 아니라 HummanMessage를 사용하여 MessagesStatus를 Update하는 이유는 supervisor_node에서 LLM이 사용자 질문이 해결했는지 판단해야 하는데 이때 AIMessage를 만나면 Finish하기 때문에 맞나요?
return Command(
update={'messages': [HumanMessage(content=result['messages'][-1].content, name='company_research')]},
goto='supervisor'
)
네네 생각하시는 방향이 맞습니다. AIMessage
의 content
가 비어있으면서 tool_calls
가 있으면, 다음에 도구를 호출하는데, AIMessage
에 content
가 담겨있으면 말씀하신대로 에이전트가 호출을 멈춰버리는 경우가 종종 있습니다.
그리고 이건 질문해주셔서 저도 방금 발견한건데, 예전에는 AIMessage
가 메세지 리스트에 연속으로 있으면 에러가 났었거든요, 그래서 그걸 방지하기 위한 목적도 있었는데, 이건 이제 사라진 것 같습니다. 수강하시다가 또 궁금하신 부분이 있으시면 언제든지 질문해주세요!
0
안녕하세요, 인프런 AI 인턴입니다. sangin1.park님.
LangGraph를 활용한 AI Agent 개발에서 supervisor_node
함수에 메시지를 추가하는 방법에 대한 질문을 주셨군요. 해당 함수에서는 SystemMessage
를 사용하여 시스템의 맥락 설정을 위한 메시지를 추가하고 있습니다.
SystemMessage
와 Message
의 차이:
SystemMessage
: 시스템의 프롬프트 메시지를 나타내기 위해 사용되는 것입니다. 주로 초기 설정이나 맥락을 지정할 때 사용합니다.코드에서의 적용:
messages = [SystemMessage(content=system_prompt)] + state["messages"]
: 이 코드 구문은 시스템 메시지를 SystemMessage
객체로 추가한 후 나머지 상태 메시지를 이어붙입니다. 이 방식은 시스템 안내와 사용자 메시지를 구분하여 처리가 가능합니다.analyst_chain.invoke({'messages': state['messages'][1:]})
: 이 부분은 이미 시스템 메시지가 포함되어 있는 전체 메시지 리스트에서 첫 번째 시스템 메시지를 제외한 후 다른 메시지만 처리하기 위해 사용됩니다.왜 이렇게 구현되었는가:
MessageState
는 초기에 시스템 메시지를 가질 수 있도록 설계되어 있습니다. 만약 시스템 메시지가 필요 없이 사용자나 에이전트의 대화만을 다루고 싶다면 state['messages'][1:]
을 사용해 불필요한 시스템 메시지를 배제할 수 있습니다.이 구조는 원하는 대화 흐름을 제어하고, 특정 상황에서 시스템의 초기 안내를 제외한 대화만을 분석하도록 할 때 유용합니다.
다음 URL에서 유사한 논의 또는 설명이 진행된 게시물을 확인하실 수 있습니다:
- LangGraph에서 시스템 메시지 활용 방법
- 프롬프트에 다양한 메시지를 추가하는 방법
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
답변감사합니다!
"supervisor는 우리가 에이전트를 통해서 받고자하는 답변을 생성한다기 보다는, 다음에 어떤 노드를 호출할지만 결정하기 때문입니다." 라는 문에서 여쭤볼게 하나 더 있습니다.! LLM이 직접 노드를 결정하는건 이해가 되는데 어떻게 노드를 결정하는지 여쭤보고 싶습니다. 제가 이해한 내용으론 별도의 프롬프트 가이드가 없어도 LLM자체적으로 messages안 질문과 답변을 확인하고 답변이 충족한다고 생각되면 FINISH를 하는 거라고 이해를 했습니다. 즉 systemprompt는 llm retrun에 대한 가이드만 제공하는 것 이고, llm에 messages를 넘겨주면 llm이 messages의 human, ai message 등 을 prompt엔 없지만 자동으로 유사도를 확인해서 node를 결정하는게 맞는지 궁금합니다.