goodbye

패스트캠퍼스 환급챌린지 46일차 : 테디노트의 RAG 비법노트 강의 후기 본문

Lecture/패스트캠퍼스

패스트캠퍼스 환급챌린지 46일차 : 테디노트의 RAG 비법노트 강의 후기

goodbye 2025. 8. 15. 01:14

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다

https://fastcampus.info/4n8ztzq

 

(~6/20) 50일의 기적 AI 환급반💫 | 패스트캠퍼스

초간단 미션! 하루 20분 공부하고 수강료 전액 환급에 AI 스킬 장착까지!

fastcampus.co.kr

 

패스트캠퍼스 환급챌린지 46일차!


1) 공부 시작 시간 인증

 

2) 공부 종료 시간 인증

 

3) 강의 수강 클립 인증

 

4) 학습 인증샷

5) 학습통계

 


Today I Learned

개별 관리자가 관리하는 별도의 전문 상담원 팀을 만들고, 팀을 관리하는 최상위 관리자를 지정할 수 있습니다.

from typing import Literal
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.types import Command
model = ChatOpenAI()

# define team 1 (same as the single supervisor example above)

def team_1_supervisor(state: MessagesState) -> Command[Literal["team_1_agent_1", "team_1_agent_2", END]]:
    response = model.invoke(...)
    return Command(goto=response["next_agent"])

def team_1_agent_1(state: MessagesState) -> Command[Literal["team_1_supervisor"]]:
    response = model.invoke(...)
    return Command(goto="team_1_supervisor", update={"messages": [response]})

def team_1_agent_2(state: MessagesState) -> Command[Literal["team_1_supervisor"]]:
    response = model.invoke(...)
    return Command(goto="team_1_supervisor", update={"messages": [response]})

team_1_builder = StateGraph(Team1State)
team_1_builder.add_node(team_1_supervisor)
team_1_builder.add_node(team_1_agent_1)
team_1_builder.add_node(team_1_agent_2)
team_1_builder.add_edge(START, "team_1_supervisor")
team_1_graph = team_1_builder.compile()

# define team 2 (same as the single supervisor example above)
class Team2State(MessagesState):
    next: Literal["team_2_agent_1", "team_2_agent_2", "__end__"]

def team_2_supervisor(state: Team2State):
    ...

def team_2_agent_1(state: Team2State):
    ...

def team_2_agent_2(state: Team2State):
    ...

team_2_builder = StateGraph(Team2State)
...
team_2_graph = team_2_builder.compile()

# define top-level supervisor

builder = StateGraph(MessagesState)
def top_level_supervisor(state: MessagesState) -> Command[Literal["team_1_graph", "team_2_graph", END]]:
    # you can pass relevant parts of the state to the LLM (e.g., state["messages"])
    # to determine which team to call next. a common pattern is to call the model
    # with a structured output (e.g. force it to return an output with a "next_team" field)
    response = model.invoke(...)
    # route to one of the teams or exit based on the supervisor's decision
    # if the supervisor returns "__end__", the graph will finish execution
    return Command(goto=response["next_team"])

builder = StateGraph(MessagesState)
builder.add_node(top_level_supervisor)
builder.add_node("team_1_graph", team_1_graph)
builder.add_node("team_2_graph", team_2_graph)
builder.add_edge(START, "top_level_supervisor")
builder.add_edge("team_1_graph", "top_level_supervisor")
builder.add_edge("team_2_graph", "top_level_supervisor")
graph = builder.compile()

사용자 정의 다중 에이전트 워크플로

이 아키텍처에서는 개별 에이전트를 그래프 노드로 추가하고, 사용자 지정 워크플로에서 에이전트가 미리 호출되는 순서를 정의합니다. LangGraph에서는 워크플로를 두 가지 방법으로 정의할 수 있습니다.

  • 명시적 제어 흐름(일반 간선) : LangGraph에서는 일반 그래프 간선을 통해 애플리케이션의 제어 흐름(즉, 에이전트 간 통신 순서)을 명시적으로 정의할 수 있습니다 . 이는 위 아키텍처의 가장 결정론적인 변형으로, 다음에 어떤 에이전트가 호출될지 항상 미리 알 수 있습니다.
  • 동적 제어 흐름(명령) : LangGraph에서는 LLM이 애플리케이션 제어 흐름의 일부를 결정하도록 할 수 있습니다. 이는 를 사용하여 구현할 수 있습니다. Command 이러한 특수한 사례 중 하나는 슈퍼바이저 도구 호출 아키텍처입니다. 이 경우, 슈퍼바이저 에이전트를 구동하는 도구 호출 LLM이 도구(에이전트) 호출 순서를 결정합니다.
from langchain_openai import ChatOpenAI
from langgraph.graph import StateGraph, MessagesState, START

model = ChatOpenAI()

def agent_1(state: MessagesState):
    response = model.invoke(...)
    return {"messages": [response]}

def agent_2(state: MessagesState):
    response = model.invoke(...)
    return {"messages": [response]}

builder = StateGraph(MessagesState)
builder.add_node(agent_1)
builder.add_node(agent_2)
# define the flow explicitly
builder.add_edge(START, "agent_1")
builder.add_edge("agent_1", "agent_2")

Communication and state management

다중 에이전트 시스템을 구축할 때 가장 중요한 것은 에이전트 간의 통신 방식을 파악하는 것입니다.

상담원이 소통하는 일반적이고 일반적인 방법은 메시지 목록을 활용하는 것입니다. 이 경우 다음과 같은 질문이 제기됩니다.

또한, 보다 복잡한 에이전트를 다루거나 개별 에이전트 상태를 다중 에이전트 시스템 상태와 분리하려는 경우 다른 상태 스키마를 사용해야 할 수도 있습니다 .

핸드오프 대 도구 호출

에이전트 간에 전달되는 "페이로드"는 무엇입니까? 위에서 설명한 대부분의 아키텍처에서 에이전트는 핸드오프를 통해 통신 하고 그래프 상태를 핸드오프 페이로드의 일부로 전달합니다. 구체적으로, 에이전트는 그래프 상태의 일부로 메시지 목록을 전달합니다. 도구 호출 기능을 사용하는 슈퍼바이저 의 경우 , 페이로드는 도구 호출 인수입니다.

에이전트 간 메시지 전달

에이전트가 소통하는 가장 일반적인 방법은 공유 상태 채널, 일반적으로 메시지 목록을 이용하는 것입니다. 이는 에이전트가 공유하는 상태에 항상 하나 이상의 채널(키)이 있다고 가정합니다(예: messages). 공유 메시지 목록을 통해 소통할 때는 추가적으로 고려해야 할 사항이 있습니다. 에이전트가 자신의 사고 과정 전체 이력을 공유 해야 할까요, 아니면 최종 결과 만 공유해야 할까요 ?

전체 사고 과정 공유

에이전트는 자신의 사고 과정(즉, "스크래치패드")에 대한 전체 기록을 다른 모든 에이전트와 공유할 수 있습니다. 이 "스크래치패드"는 일반적으로 메시지 목록 처럼 보입니다 . 전체 사고 과정을 공유하는 것의 이점은 다른 에이전트가 더 나은 결정을 내리고 시스템 전체의 추론 능력을 향상시키는 데 도움이 될 수 있다는 것입니다. 단점은 에이전트의 수와 복잡성이 증가함에 따라 "스크래치패드"가 빠르게 커지고 메모리 관리를 위한 추가적인 전략이 필요할 수 있다는 것입니다 .

최종 결과만 공유합니다

에이전트는 각자의 개인 "스크래치패드"를 가지고 최종 결과만 나머지 에이전트와 공유 할 수 있습니다. 이 방식은 에이전트가 많거나 에이전트가 더 복잡한 시스템에 더 적합할 수 있습니다. 이 경우, 서로 다른 상태 스키마를 가진 에이전트를 정의해야 합니다 .

도구라고 불리는 에이전트의 경우, 슈퍼바이저는 도구 스키마를 기반으로 입력을 결정합니다. 또한, LangGraph는 런타임에 개별 도구에 상태를 전달할 수 있으므로, 필요한 경우 하위 에이전트가 상위 상태에 접근할 수 있습니다.

메시지에 에이전트 이름 표시

특정 AI 메시지가 어떤 에이전트로부터 왔는지 나타내는 것은 특히 긴 메시지 기록의 경우 유용할 수 있습니다. OpenAI와 같은 일부 LLM 제공업체는 name메시지에 매개변수를 추가하는 기능을 지원합니다. 매개변수를 사용하여 메시지에 에이전트 이름을 첨부할 수 있습니다. 이 기능이 지원되지 않는 경우, 메시지 내용에 에이전트 이름을 수동으로 삽입하는 것을 고려해 볼 수 있습니다(예: <agent>alice</agent><message>message from alice</message>.

메시지 기록에서 핸드오프 표현

핸드오프는 일반적으로 LLM이 전용 핸드오프 도구 를 호출하여 수행됩니다. 이는 도구 호출을 포함하는 AI 메시지 로 표현되며, 이 메시지는 다음 상담원(LLM)에게 전달됩니다. 대부분의 LLM 제공업체는 해당 도구 메시지 없이 도구 호출을 포함하는 AI 메시지를 수신하는 것을 지원하지 않습니다 .

따라서 두 가지 옵션이 있습니다.

  1. 메시지 목록에 추가 도구 메시지를 추가합니다(예: "에이전트 X에게 성공적으로 전송됨").
  2. 도구 호출로 AI 메시지를 제거합니다.

실제로 대부분의 개발자는 옵션 (1)을 선택합니다.

하위 에이전트에 대한 상태 관리

일반적으로 여러 상담원이 공유 메시지 목록에서 소통하지만, 최종 메시지만 목록에 추가하는 방식이 사용됩니다 . 즉, 중간 메시지(예: 도구 호출)는 이 목록에 저장되지 않습니다.

나중에 이 특정 하위 에이전트가 호출될 때 해당 메시지를 다시 전달할 수 있도록 이러한 메시지를 저장하려면 어떻게 해야 할까요 ?

이를 달성하기 위한 두 가지 높은 수준의 접근 방식이 있습니다.

  1. 이러한 메시지는 공유 메시지 목록에 저장하되, 하위 에이전트 LLM으로 전달하기 전에 목록을 필터링합니다. 예를 들어, 다른
  2. 에이전트 의 모든 도구 호출을 필터링하도록 선택할 수 있습니다 .
  3. 하위 에이전트의 그래프 상태에 각 에이전트(예: )에 대한 별도의 메시지 목록을 저장합니다 alice_messages
  4. . 이는 메시지 내역이 어떻게 표시되는지에 대한 "보기"입니다.

다양한 상태 스키마 사용

에이전트는 다른 에이전트와 다른 상태 스키마를 가져야 할 수 있습니다. 예를 들어, 검색 에이전트는 쿼리와 검색된 문서만 추적하면 됩니다. LangGraph에서는 이를 구현하는 두 가지 방법이 있습니다.

Comments