🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Human-in-the-Loop 인간 개입 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 1. · 65 Views

Human-in-the-Loop 인간 개입 완벽 가이드

LangGraph에서 AI 에이전트의 중요한 도구 실행 전에 인간의 승인을 받는 Human-in-the-Loop 패턴을 학습합니다. 민감한 작업의 안전성을 확보하고 실수를 방지하는 핵심 기술입니다.


목차

  1. HumanInTheLoopMiddleware_설정
  2. interrupt_on_도구_지정
  3. Approve_Edit_Reject_결정
  4. 승인_워크플로우_구현
  5. 도구_실행_전_승인_패턴
  6. 체크포인터_필수_설정

1. HumanInTheLoopMiddleware 설정

김개발 씨는 최근 AI 에이전트를 개발하고 있습니다. 에이전트가 데이터베이스를 삭제하거나 이메일을 보내는 작업을 자동으로 수행하는데, 문득 불안해졌습니다.

"만약 AI가 실수로 중요한 데이터를 날려버리면 어떡하지?"

Human-in-the-Loop은 한마디로 AI가 중요한 작업을 수행하기 전에 사람의 승인을 받는 패턴입니다. 마치 은행에서 큰 금액을 송금할 때 한 번 더 비밀번호를 확인하는 것과 같습니다.

이 패턴을 적용하면 AI의 실수로 인한 치명적인 결과를 방지할 수 있습니다.

다음 코드를 살펴봅시다.

from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import StateGraph, START, END
from langgraph.types import interrupt

# 체크포인터 설정 - Human-in-the-Loop의 필수 요소
checkpointer = MemorySaver()

# 그래프 빌더 생성
builder = StateGraph(State)

# 노드 추가
builder.add_node("agent", agent_node)
builder.add_node("human_review", human_review_node)

# 그래프 컴파일 시 체크포인터 연결
graph = builder.compile(checkpointer=checkpointer)

김개발 씨는 입사 6개월 차 주니어 개발자입니다. 요즘 한창 LangGraph로 AI 에이전트를 만드는 프로젝트에 참여하고 있습니다.

에이전트는 사용자의 요청에 따라 이메일을 보내고, 파일을 삭제하고, 데이터베이스를 수정하는 등 다양한 작업을 수행합니다. 어느 날, 테스트 중에 에이전트가 실수로 중요한 고객 데이터를 삭제해버렸습니다.

다행히 테스트 환경이라 복구할 수 있었지만, 만약 운영 환경이었다면 큰 사고가 날 뻔했습니다. 선배 개발자 박시니어 씨가 다가와 말했습니다.

"이런 위험한 작업은 Human-in-the-Loop 패턴을 적용해야 해요." 그렇다면 Human-in-the-Loop이란 정확히 무엇일까요? 쉽게 비유하자면, Human-in-the-Loop은 마치 은행의 이중 확인 시스템과 같습니다.

계좌에서 100만 원 이상을 송금하려고 하면 은행에서 "정말 보내시겠습니까?"라고 한 번 더 확인합니다. 이처럼 AI 에이전트도 위험한 작업을 수행하기 전에 사람에게 "이 작업을 실행해도 될까요?"라고 물어보는 것입니다.

이 패턴이 없던 시절에는 어땠을까요? AI 에이전트가 자율적으로 모든 결정을 내렸습니다.

대부분은 문제가 없지만, 가끔 잘못된 판단으로 돌이킬 수 없는 실수를 저질렀습니다. 데이터베이스 전체 삭제, 잘못된 사람에게 기밀 이메일 전송, 중요한 파일 덮어쓰기 같은 사고가 발생할 수 있었습니다.

바로 이런 문제를 해결하기 위해 Human-in-the-Loop 패턴이 등장했습니다. 이 패턴을 적용하면 위험한 작업 전에 반드시 사람의 승인을 받습니다.

승인을 받기 전까지 에이전트는 대기 상태에 머물고, 사람이 "승인" 또는 "거부"를 결정합니다. 위의 코드를 살펴보겠습니다.

먼저 MemorySaver를 임포트합니다. 이것은 에이전트의 상태를 저장하는 체크포인터입니다.

Human-in-the-Loop이 동작하려면 에이전트가 중간에 멈췄다가 나중에 다시 시작할 수 있어야 하기 때문에 체크포인터는 필수입니다. StateGraph를 생성하고 필요한 노드들을 추가합니다.

마지막으로 compile 메서드를 호출할 때 체크포인터를 연결합니다. 이렇게 하면 그래프가 언제든지 중간에 멈추고 상태를 저장할 수 있게 됩니다.

실제 현업에서는 결제 처리, 데이터 삭제, 외부 API 호출 등 민감한 작업에 이 패턴을 적용합니다. 특히 금융 서비스나 의료 서비스처럼 실수가 큰 피해로 이어질 수 있는 분야에서 필수적으로 사용됩니다.

주의할 점도 있습니다. 모든 작업에 인간 승인을 요구하면 에이전트의 자율성이 떨어지고 사용자 경험이 나빠집니다.

따라서 정말 중요한 작업에만 선별적으로 적용해야 합니다.

실전 팁

💡 - 체크포인터 없이는 Human-in-the-Loop이 동작하지 않으니 반드시 설정하세요

  • 프로덕션 환경에서는 MemorySaver 대신 PostgresSaver나 SQLiteSaver를 사용하세요

2. interrupt on 도구 지정

김개발 씨는 Human-in-the-Loop의 기본 개념을 이해했습니다. 하지만 새로운 고민이 생겼습니다.

"모든 도구 실행마다 승인을 받으면 너무 번거롭지 않을까? 위험한 도구만 선별해서 승인을 받을 순 없을까?"

interrupt_on 설정은 특정 도구가 호출될 때만 실행을 중단하고 인간 승인을 요청하는 기능입니다. 마치 공항 보안검색대에서 모든 짐을 열어보는 게 아니라 X-ray에서 의심스러운 물건이 발견됐을 때만 정밀 검사를 하는 것과 같습니다.

이렇게 하면 효율성과 안전성을 동시에 확보할 수 있습니다.

다음 코드를 살펴봅시다.

from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import MemorySaver

# 위험한 도구 목록 정의
sensitive_tools = ["delete_database", "send_email", "transfer_money"]

# 에이전트 생성 시 interrupt_before 설정
agent = create_react_agent(
    model=llm,
    tools=tools,
    checkpointer=MemorySaver(),
    # 민감한 도구 실행 전에 중단
    interrupt_before=["tools"]
)

# 또는 특정 도구만 지정하여 중단
def should_interrupt(tool_call):
    return tool_call["name"] in sensitive_tools

김개발 씨의 에이전트에는 10가지 이상의 도구가 있습니다. 날씨 조회, 계산기, 검색 같은 안전한 도구도 있고, 데이터베이스 삭제, 이메일 전송, 송금 같은 위험한 도구도 있습니다.

모든 도구 실행마다 승인을 받으면 사용자가 지쳐버릴 것입니다. 박시니어 씨가 해결책을 알려줬습니다.

"interrupt_before 옵션을 사용하면 원하는 시점에만 실행을 중단할 수 있어요." interrupt_on 설정은 마치 병원의 응급실 분류 시스템과 같습니다. 모든 환자를 똑같이 대하지 않고, 위급한 환자는 즉시 의사가 확인하고 경미한 환자는 순서대로 처리합니다.

AI 에이전트도 마찬가지입니다. 위험한 도구는 반드시 인간이 확인하고, 안전한 도구는 자동으로 실행합니다.

코드를 살펴보겠습니다. 먼저 sensitive_tools 리스트에 위험한 도구의 이름을 정의합니다.

delete_database, send_email, transfer_money처럼 실수하면 큰 피해가 발생하는 도구들입니다. create_react_agent 함수를 호출할 때 interrupt_before 파라미터를 설정합니다.

여기에 "tools"를 지정하면 도구 실행 노드에 진입하기 전에 그래프 실행이 중단됩니다. 더 세밀한 제어가 필요하다면 should_interrupt 함수를 만들어 조건부로 중단 여부를 결정할 수 있습니다.

이 함수는 도구 호출 정보를 받아서 민감한 도구인지 확인하고 True 또는 False를 반환합니다. 실무에서는 도구의 위험도를 등급으로 분류하기도 합니다.

예를 들어 빨간색 도구는 항상 승인 필요, 노란색 도구는 특정 조건에서만 승인 필요, 초록색 도구는 자동 실행 같은 방식입니다. 주의할 점이 있습니다.

interrupt_before와 interrupt_after를 혼동하지 마세요. before는 도구 실행 전에 중단하고, after는 도구 실행 후에 중단합니다.

대부분의 경우 실행 전에 승인을 받는 것이 안전합니다. 이미 실행된 작업은 되돌리기 어렵기 때문입니다.

실전 팁

💡 - 도구 위험도를 등급화하여 관리하면 유지보수가 편리합니다

  • interrupt_before는 실행 전, interrupt_after는 실행 후 중단입니다

3. Approve Edit Reject 결정

김개발 씨는 이제 에이전트가 위험한 작업 전에 멈추도록 설정했습니다. 그런데 새로운 궁금증이 생겼습니다.

"사용자가 승인할 때 단순히 '예/아니오'만 선택하는 건가요? 좀 더 세밀한 제어는 없나요?"

Human-in-the-Loop에서 사용자는 세 가지 결정을 내릴 수 있습니다. Approve는 제안된 작업을 그대로 승인하는 것이고, Edit는 내용을 수정해서 승인하는 것이며, Reject는 작업을 완전히 거부하는 것입니다.

마치 문서 결재 시스템에서 승인, 수정 요청, 반려를 선택하는 것과 같습니다.

다음 코드를 살펴봅시다.

from langgraph.types import Command

# 사용자 결정에 따른 처리
def handle_human_decision(decision: str, tool_call: dict, modified_args: dict = None):
    if decision == "approve":
        # 원래 도구 호출 그대로 실행
        return Command(resume=tool_call)

    elif decision == "edit":
        # 수정된 인자로 도구 호출 실행
        edited_call = {**tool_call, "args": modified_args}
        return Command(resume=edited_call)

    elif decision == "reject":
        # 도구 실행 취소, 에이전트에 피드백 전달
        return Command(resume={"rejected": True, "reason": "사용자가 거부함"})

김개발 씨는 이메일 발송 에이전트를 테스트하고 있었습니다. 에이전트가 "홍길동님에게 프로젝트 보고서를 보내시겠습니까?"라고 물었습니다.

그런데 받는 사람 이메일 주소가 잘못되어 있었습니다. 단순히 "예"라고 하면 잘못된 주소로 발송되고, "아니오"라고 하면 작업 자체가 취소됩니다.

박시니어 씨가 설명했습니다. "Human-in-the-Loop은 세 가지 선택지를 제공해요.

승인, 수정, 거부입니다." 이것은 마치 회사의 전자결재 시스템과 같습니다. 부장님이 기안 문서를 받았을 때 그대로 승인할 수도 있고, 일부 내용을 수정해서 승인할 수도 있고, 아예 반려할 수도 있습니다.

AI 에이전트의 작업도 마찬가지 방식으로 처리됩니다. Approve는 가장 간단한 결정입니다.

에이전트가 제안한 작업이 완벽하게 맞을 때 사용합니다. "네, 그대로 실행해주세요"라고 말하는 것과 같습니다.

Edit는 작업 내용을 수정하고 싶을 때 사용합니다. 예를 들어 에이전트가 "10만 원을 송금합니다"라고 했는데 금액이 틀렸다면, "5만 원으로 수정해서 송금해주세요"라고 할 수 있습니다.

이때 수정된 인자를 함께 전달합니다. Reject는 작업을 완전히 취소합니다.

에이전트가 잘못된 판단을 했거나 상황이 바뀌어서 더 이상 그 작업이 필요 없을 때 사용합니다. 거부 사유를 함께 전달하면 에이전트가 그 정보를 바탕으로 다른 방법을 시도할 수 있습니다.

코드에서 Command 객체는 그래프에 명령을 전달하는 역할을 합니다. resume 파라미터에 승인할 내용이나 수정된 내용을 담아서 전달합니다.

거부할 때는 rejected 플래그와 함께 사유를 전달합니다. 실무에서는 이 세 가지 옵션을 UI로 깔끔하게 보여주는 것이 중요합니다.

사용자가 각 옵션의 의미를 명확히 이해하고 올바른 결정을 내릴 수 있어야 합니다.

실전 팁

💡 - 거부 시 사유를 명확히 전달하면 에이전트가 더 나은 대안을 제시할 수 있습니다

  • 수정 옵션을 제공할 때는 어떤 항목을 수정할 수 있는지 명확히 안내하세요

4. 승인 워크플로우 구현

김개발 씨는 Approve, Edit, Reject의 개념을 이해했습니다. 이제 실제로 이것을 구현해야 합니다.

"전체 승인 흐름을 어떻게 코드로 작성하지? 에이전트가 멈추고, 사용자가 결정하고, 다시 실행되는 과정이 머릿속에 그려지지 않아요."

승인 워크플로우는 크게 세 단계로 구성됩니다. 첫째, 에이전트가 민감한 작업에 도달하면 interrupt로 실행을 중단합니다.

둘째, 시스템이 사용자에게 승인을 요청하고 결정을 기다립니다. 셋째, 사용자의 결정을 받아 Command로 그래프를 재개합니다.

마치 놀이공원의 놀이기구가 안전바를 확인한 후에야 출발하는 것과 같습니다.

다음 코드를 살펴봅시다.

from langgraph.types import interrupt, Command

def sensitive_tool_node(state):
    tool_call = state["pending_tool_call"]

    # 인간 승인 요청 - 여기서 그래프 실행이 중단됨
    decision = interrupt({
        "action": "tool_approval",
        "tool_name": tool_call["name"],
        "tool_args": tool_call["args"],
        "message": f"'{tool_call['name']}' 도구를 실행할까요?"
    })

    # 재개 후 이 지점부터 실행됨
    if decision.get("approved"):
        result = execute_tool(tool_call)
        return {"result": result}
    else:
        return {"result": "사용자가 거부했습니다"}

김개발 씨는 종이에 워크플로우를 그려보기로 했습니다. 박시니어 씨가 옆에서 설명을 덧붙입니다.

"승인 워크플로우는 마치 릴레이 경주와 같아요. 첫 번째 주자가 바통을 들고 달리다가 특정 지점에서 멈춥니다.

심판이 확인한 후에야 다음 주자가 바통을 받아 달릴 수 있죠." 첫 번째 단계는 중단입니다. 에이전트가 민감한 도구를 호출하려고 할 때, interrupt 함수가 실행됩니다.

이 함수는 현재 상태를 저장하고 그래프 실행을 멈춥니다. 중요한 것은 어떤 작업을 하려고 했는지에 대한 정보를 함께 전달하는 것입니다.

두 번째 단계는 대기입니다. 그래프가 중단된 동안 시스템은 사용자에게 승인 요청을 보여줍니다.

"delete_database 도구를 실행할까요? 대상: users 테이블"처럼 구체적인 정보를 함께 보여줘야 사용자가 올바른 결정을 내릴 수 있습니다.

세 번째 단계는 재개입니다. 사용자가 결정을 내리면 Command 객체를 통해 그래프를 다시 시작합니다.

이때 중요한 점은 그래프가 중단된 지점부터 이어서 실행된다는 것입니다. 처음부터 다시 시작하는 것이 아닙니다.

코드를 자세히 살펴보겠습니다. interrupt 함수는 딕셔너리를 인자로 받습니다.

이 딕셔너리에는 승인 요청에 필요한 모든 정보를 담습니다. 도구 이름, 인자, 사용자에게 보여줄 메시지 등입니다.

interrupt가 호출되면 그래프는 즉시 멈춥니다. 그리고 이 딕셔너리 정보가 호출자에게 반환됩니다.

호출자는 이 정보를 바탕으로 사용자 인터페이스를 구성합니다. 사용자가 결정을 내리면 **Command(resume=...)**을 사용해 그래프를 재개합니다.

resume에 전달된 값은 interrupt 함수의 반환값이 됩니다. 따라서 재개 후에는 decision 변수에 사용자의 결정이 담겨 있습니다.

주의할 점이 있습니다. interrupt 후에 그래프를 재개하려면 반드시 같은 thread_id를 사용해야 합니다.

thread_id가 다르면 새로운 실행으로 인식되어 중단 지점을 찾을 수 없습니다.

실전 팁

💡 - interrupt에 전달하는 정보는 사용자가 결정을 내리기에 충분해야 합니다

  • 재개 시 반드시 동일한 thread_id를 사용하세요

5. 도구 실행 전 승인 패턴

김개발 씨는 기본적인 승인 워크플로우를 이해했습니다. 이제 실제 프로젝트에 적용할 차례입니다.

"도구가 여러 개인데, 각 도구마다 승인 로직을 따로 만들어야 하나요? 더 깔끔한 방법이 있을 것 같은데..."

도구 실행 전 승인 패턴은 도구 노드에 진입하기 직전에 일괄적으로 승인을 처리하는 구조입니다. 마치 공항에서 탑승 게이트에 들어가기 전에 모든 승객의 탑승권을 확인하는 것과 같습니다.

개별 도구마다 승인 로직을 넣지 않고, 중앙에서 일괄 처리하므로 코드가 깔끔해집니다.

다음 코드를 살펴봅시다.

from langgraph.prebuilt import create_react_agent, ToolNode
from langgraph.checkpoint.memory import MemorySaver

# 민감한 도구 정의
sensitive_tool_names = {"delete_file", "send_email", "execute_query"}

# 도구 승인 노드
def tool_approval_node(state):
    tool_calls = state["messages"][-1].tool_calls

    for call in tool_calls:
        if call["name"] in sensitive_tool_names:
            decision = interrupt({
                "tool": call["name"],
                "args": call["args"]
            })
            if not decision.get("approved"):
                return {"messages": [AIMessage(content="작업이 취소되었습니다")]}

    return state  # 승인됨, 도구 실행 진행

# 그래프에 승인 노드 추가
builder.add_node("tool_approval", tool_approval_node)
builder.add_edge("agent", "tool_approval")
builder.add_edge("tool_approval", "tools")

김개발 씨는 처음에 각 도구 함수 안에 승인 로직을 넣으려고 했습니다. 그런데 도구가 15개나 되다 보니 코드가 반복되고 관리가 어려웠습니다.

박시니어 씨가 더 좋은 방법을 알려줬습니다. "중앙 집중식 승인 패턴을 사용하세요.

도구 노드 앞에 승인 노드를 하나 두는 거예요." 이 패턴은 마치 회사의 보안 게이트와 같습니다. 직원들이 각 층마다 출입 카드를 찍는 게 아니라, 건물 입구에서 한 번만 확인합니다.

마찬가지로 에이전트가 도구를 실행하려고 할 때, 도구 노드에 들어가기 전에 승인 노드를 거치도록 합니다. 코드를 살펴보겠습니다.

먼저 sensitive_tool_names에 승인이 필요한 도구들을 집합으로 정의합니다. 집합을 사용하면 검색 속도가 빠릅니다.

tool_approval_node 함수가 승인을 담당합니다. 이 함수는 상태에서 마지막 메시지의 tool_calls를 확인합니다.

각 도구 호출에 대해 민감한 도구인지 확인하고, 민감한 도구라면 interrupt를 호출해 승인을 요청합니다. 사용자가 거부하면 "작업이 취소되었습니다"라는 메시지를 반환하고 도구 실행 없이 종료됩니다.

승인되면 원래 상태를 그대로 반환하고 다음 노드인 도구 노드로 진행합니다. 그래프 구성에서 중요한 점은 edge 연결 순서입니다.

agent 노드에서 바로 tools 노드로 가는 것이 아니라, 중간에 tool_approval 노드를 거치도록 합니다. 이렇게 하면 모든 도구 호출이 승인 노드를 통과하게 됩니다.

이 패턴의 장점은 확장성입니다. 새로운 민감한 도구가 추가되면 sensitive_tool_names에만 추가하면 됩니다.

도구 함수 자체를 수정할 필요가 없습니다. 또한 승인 로직을 변경할 때도 한 곳만 수정하면 됩니다.

실무에서는 이 패턴에 로깅 기능을 추가하기도 합니다. 누가 언제 어떤 도구 실행을 승인했는지 기록해두면 나중에 감사 추적에 유용합니다.

실전 팁

💡 - 민감한 도구 목록은 설정 파일로 분리하면 관리가 편리합니다

  • 승인 내역을 로깅해두면 보안 감사에 도움이 됩니다

6. 체크포인터 필수 설정

김개발 씨가 드디어 Human-in-the-Loop을 구현했습니다. 그런데 테스트 중에 이상한 에러가 발생했습니다.

"interrupt를 호출했는데 'Checkpointer is required' 에러가 나요. 분명히 코드는 맞는 것 같은데..."

체크포인터는 Human-in-the-Loop의 핵심 인프라입니다. 에이전트가 중단될 때 현재 상태를 저장하고, 재개될 때 그 상태를 복원하는 역할을 합니다.

체크포인터 없이는 interrupt가 동작하지 않습니다. 마치 게임의 세이브 포인트가 없으면 중간에 게임을 끄고 나중에 이어서 할 수 없는 것과 같습니다.

다음 코드를 살펴봅시다.

from langgraph.checkpoint.memory import MemorySaver
from langgraph.checkpoint.sqlite import SqliteSaver
from langgraph.checkpoint.postgres import PostgresSaver

# 개발용: 메모리 체크포인터 (서버 재시작 시 초기화됨)
memory_checkpointer = MemorySaver()

# 프로덕션용: SQLite 체크포인터
sqlite_checkpointer = SqliteSaver.from_conn_string("checkpoints.db")

# 대규모 서비스용: PostgreSQL 체크포인터
postgres_checkpointer = PostgresSaver.from_conn_string(
    "postgresql://user:pass@localhost/mydb"
)

# 그래프 컴파일 시 체크포인터 연결 - 필수!
graph = builder.compile(checkpointer=memory_checkpointer)

# 실행 시 thread_id 지정 - 필수!
config = {"configurable": {"thread_id": "user-123-session-456"}}
result = graph.invoke(input_state, config)

김개발 씨는 에러 메시지를 보고 당황했습니다. 분명히 interrupt 함수를 올바르게 호출했는데 왜 체크포인터가 필요하다고 하는 걸까요?

박시니어 씨가 차근차근 설명했습니다. "Human-in-the-Loop이 동작하려면 상태를 저장하고 복원할 수 있어야 해요.

체크포인터가 바로 그 역할을 합니다." 쉽게 비유하자면, 체크포인터는 게임의 세이브 시스템과 같습니다. RPG 게임을 하다가 보스 앞에서 저장하고 식사를 하러 갑니다.

돌아와서 게임을 다시 켜면 보스 앞에서 시작할 수 있습니다. 세이브 시스템이 없다면?

처음부터 다시 시작해야 합니다. AI 에이전트도 마찬가지입니다.

에이전트가 민감한 작업 앞에서 멈추고 사용자의 승인을 기다립니다. 사용자가 5분 후에 승인을 하면 에이전트는 멈춘 지점부터 이어서 실행해야 합니다.

이것이 가능하려면 멈출 때의 상태를 어딘가에 저장해야 합니다. LangGraph는 세 가지 체크포인터를 제공합니다.

MemorySaver는 가장 간단한 체크포인터입니다. 상태를 메모리에 저장합니다.

설정이 쉽고 빠르지만, 서버가 재시작되면 모든 데이터가 사라집니다. 개발과 테스트 환경에서 사용하기 좋습니다.

SqliteSaver는 SQLite 데이터베이스에 상태를 저장합니다. 서버가 재시작되어도 데이터가 유지됩니다.

소규모 프로덕션 환경이나 단일 서버 구성에서 적합합니다. PostgresSaver는 PostgreSQL 데이터베이스를 사용합니다.

여러 서버가 같은 데이터베이스를 공유할 수 있어서 대규모 분산 시스템에 적합합니다. 고가용성이 필요한 프로덕션 환경에서 권장됩니다.

코드에서 주목할 점이 또 있습니다. 그래프를 실행할 때 반드시 thread_id를 지정해야 합니다.

thread_id는 각 대화 세션을 구분하는 식별자입니다. 같은 thread_id로 그래프를 실행하면 이전 상태를 이어받습니다.

다른 thread_id를 사용하면 새로운 세션으로 시작합니다. 흔히 하는 실수 중 하나는 thread_id를 항상 같은 값으로 고정하는 것입니다.

이렇게 하면 서로 다른 사용자의 대화가 섞여버립니다. 반드시 사용자별, 세션별로 고유한 thread_id를 사용해야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 체크포인터를 추가하고 thread_id를 올바르게 설정하자 에러가 사라졌습니다.

"아, 체크포인터가 이렇게 중요한 거였군요!"

실전 팁

💡 - 개발 환경에서는 MemorySaver, 프로덕션에서는 PostgresSaver를 사용하세요

  • thread_id는 사용자와 세션을 조합해서 고유하게 생성하세요

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#LangGraph#HumanInTheLoop#interrupt#Checkpoint#AgentSafety#AI,LLM,Python,LangChain

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스