다중 에이전트, 여러개의 에이전트를 활용하는 방법론이다.
여러개의 에이전트를 사용하면 이를 관리하는 관리자 supervisor를 사용하는 경우도 많아서 관련된 글도 찾았다.
그리고 에이전트의 핵심은 LLM이 알아서 도구를 사용하는 점에 있기에 이에 대해서도 간략하게 찾아보았다.
보통 langchain이나 langgraph의 creat_react_agent를 많이 사용하게 되어서 이와 관련된 글들도 모았다.
Multi-Agent and Supervisor
LangChain Multi-Agent Tutorial: 링크
LangChain Multi-Agent Supervisor: 링크
LangGraph Supervisor Github: 링크
'멀티 에이전트 시스템'에 대한 참고자료 7選: 링크
IBM 멀티에이전트 시스템이란 무엇인가요?: 링크
계층적 멀티 에이전트 팀(Hierarchical Multi-Agent Teams) 랭체인 노트 위키독스: 링크
Multi-Agent Supervisor in LangGraph: 링크
Building Multi-Agents Supervisor System from Scratch with LangGraph & Langsmith Medium: 링크
Tools
ToolNode 랭체인 노트 위키독스: 링크
LangChain Tools Documentation: 링크
Tools in LangChain Kr 위키독스: 링크
Tool binding with LLM in LangChain Kr 위키독스: 링크
Handoffs
Handoffs란 그래프에서 노드로 표기되는 에이전트들의 의사소통이다.
다음 노드로의 목적지와 정보가 주된 내용이다.
- destination: target agent to navigate to (e.g., name of the node to go to)
- payload: information to pass to that agent (e.g., state update)
아래는 custom handoff_tool 함수의 예시다.
from typing import Annotated
from langchain_core.tools import tool, InjectedToolCallId
from langgraph.prebuilt import create_react_agent, InjectedState
from langgraph.graph import StateGraph, START, MessagesState
from langgraph.types import Command
def create_handoff_tool(*, agent_name: str, description: str | None = None):
name = f"transfer_to_{agent_name}"
description = description or f"Transfer to {agent_name}"
@tool(name, description=description)
def handoff_tool(
state: Annotated[MessagesState, InjectedState],
tool_call_id: Annotated[str, InjectedToolCallId],
) -> Command:
tool_message = {
"role": "tool",
"content": f"Successfully transferred to {agent_name}",
"name": name,
"tool_call_id": tool_call_id,
}
return Command(
goto=agent_name,
update={"messages": state["messages"] + [tool_message]},
graph=Command.PARENT,
)
return handoff_tool
tool_message를 파이썬의 기본 dict 형태로 설정하고 있는데, Gemini한테 시켜서 아래와 같이 ToolMessage 객체로 변경하였다.
HumanMessage나 AIMessage, SystemMessage와 일관된 형태로 처리하기 위해서다.
또한 이런식으로 처리하면 어떤 메시지인지 isinstance()로 구분하기도 쉽다.
from langchain_core.messages import ToolMessage
tool_message = ToolMessage(
content=f"Successfully transferred to {agent_name}",
name=name, # ToolMessage에서는 tool_call_id 대신 name을 사용하거나,
# LangGraph의 InjectedToolCallId를 사용하는 경우 다르게 처리될 수 있습니다.
# 여기서는 `tool_call_id`가 ToolMessage의 일부가 아닌, tool_call_result의 일부입니다.
# LangGraph의 Command update context에서는 dict 형태의 메시지가 필요할 수 있으므로,
# 이 부분을 LangGraph의 메시지 처리 방식에 맞게 조정해야 합니다.
# LangGraph의 StateGraph는 내부적으로 BaseMessage 인스턴스를 기대합니다.
tool_call_id=tool_call_id # ToolMessage의 constructor에 tool_call_id를 직접 넣을 수도 있습니다.
)
Handoffs in LangGraph Documentation: 링크
Build multi-agent system LangGraph Documentation: 링크
LangChain ReAct
[LangChain] AgentExecutor와 ReAct 블로그: 링크
LangChain의 create_react_agnet를 LangSmith로 이해: 링크
LangChain의 agents 항목의 react Github: 링크
LangGraph ReAct
LangGraph로 ReAct 에이전트 만들기: 링크
LangGraph ReAct Agent Template Github: 링크
LangGraph의 prebuilt 항목의 create_react_agent Github: 링크
'AI Codes > LangChain & MCP & Agent' 카테고리의 다른 글
Agent의 평가와 function calling 관련 글 모음 (1) | 2025.05.28 |
---|---|
Streamlit으로 음악 추천을 위한 챗봇 구현 (2) | 2025.05.16 |
Chainlit 리서치 및 튜토리얼 적용 결과 (3) | 2025.05.14 |
LLM으로 테이블과 차트 생성 (2) | 2025.05.08 |
금융 PDF에서 Figure와 Table 추출하기 (0) | 2025.05.02 |