LangGraph와 Elasticsearch로 휴먼 인 더 루프 에이전트 구축하기

LangGraph와 Elasticsearch를 사용하여 인간이 의사결정 과정에 참여하여 맥락적 공백을 채우고 도구 호출을 실행 전에 검토하는 휴먼 인 더 루프 에이전트를 구축하는 방법을 알아보세요.

Agent Builder는 현재 기술 미리보기 버전으로 제공됩니다. Elastic Cloud 체험판으로 시작한 뒤, Agent Builder 문서를 여기에서 확인하세요.

이 문서에서는 LangGraph와 Elasticsearch를 결합하여 HITL(휴먼 인 더 루프) 애플리케이션을 구축하는 방법을 살펴봅니다. 이러한 접근 방식을 통해 AI 시스템은 사용자를 의사결정 과정에 직접 참여시켜 더욱 안정적이고 맥락에 맞는 상호작용을 할 수 있습니다. 컨텍스트 기반 시나리오를 사용해 실제 예제를 구현하여 LangGraph 워크플로우가 어떻게 Elasticsearch와 통합되어 데이터를 검색하고, 사용자 입력을 처리하고, 정제된 결과를 생성하는지를 보여드리겠습니다.

요건

  • NodeJS 버전 18 이상
  • OpenAI API 키
  • Elasticsearch 8.x+ 배포

LangGraph를 생산 HITL 시스템에 사용하는 이유

이전 문서에서는 LLM과 조건부 엣지를 사용하여 자동으로 의사결정을 내리고 결과를 표시하는 RAG 시스템을 구축하는 데 있어 LangGraph와 그 이점에 대해 소개했습니다. 때로는 시스템이 처음부터 끝까지 자율적으로 작동하는 것이 아니라 사용자가 실행 루프 내에서 옵션을 선택하고 의사 결정을 내리기를 원할 때가 있습니다. 이 개념은 휴먼 인 더 루프라고 합니다.

휴먼 인 더 루프 또는 인 더 루프

이는 실제 사람이 AI 시스템과 상호 작용하여 더 많은 컨텍스트를 제공하고, 응답을 평가하고, 응답을 편집하고, 추가 정보를 요청하는 등의 작업을 수행할 수 있는 AI 개념입니다. 이는 규정 준수, 의사 결정 또는 콘텐츠 생성 등 오류 허용 오차가 낮은 시나리오에서 매우 유용하며, LLM 출력의 신뢰성을 개선하는 데 도움이 됩니다.

일반적인 예는 코딩 어시스턴트가 터미널에서 특정 명령을 실행할 권한을 요청하거나 코딩을 시작하기 전에 승인할 단계별 사고 과정을 보여 주는 경우입니다.

Elasticsearch와 LangGraph의 상호 작용 방식

LangChain은 전체 텍스트 또는 시맨틱 검색을 실행하는 데 유용한 전체 텍스트 또는 시맨틱 검색을 실행하는 데 유용한 LangGraph 애플리케이션 내에서 Elasticsearch를 벡터 저장소로 사용하고 쿼리를 수행할 수 있게 해주며, LangGraph는 특정 워크플로우, 도구 및 상호 작용을 정의하는 데 사용됩니다. 또한 HITL을 사용자와의 추가적인 상호 작용 계층으로 추가합니다.

실용적인 구현: 휴먼 인 더 루프

변호사가 최근에 수임한 사건에 대해 궁금한 점이 있는 경우를 가정해 보겠습니다. 적절한 도구가 없다면 그는 법률 조항과 판례를 일일이 검색하고, 전문을 읽은 다음, 그것들이 자신의 상황에 어떻게 적용되는지 해석해야 할 것입니다. 그러나 LangGraph와 Elasticsearch를 사용하면 법률 판례 데이터베이스를 검색하고 변호사가 제공한 구체적인 세부 사항과 맥락을 통합한 판례 분석을 생성하는 시스템을 구축할 수 있습니다.

변호사가 법률 질문을 제출하는 순간부터 워크플로우가 시작됩니다. 시스템은 Elasticsearch에서 벡터 검색을 수행하여 가장 관련성이 높은 판례를 검색한 후 자연어를 사용해 변호사가 선택할 수 있도록 제시합니다. 선택 후 LLM은 분석 초안을 생성하고 정보가 완전한지 확인합니다. 이 시점에서 워크플로우는 두 가지 경로 중 하나를 따를 수 있습니다. 모든 것이 명확하다면 최종 분석을 생성하기 위해 직접 진행하고, 그렇지 않다면 변호사에게 명확화를 요청하기 위해 일시 중지합니다. 누락된 컨텍스트가 제공되면 시스템은 설명을 고려하여 분석을 완료하고 반환합니다.

다음은 LangGraph에서 생성한 그래프로, 개발이 완료되었을 때 앱의 최종 모습을 보여줍니다. 각 노드는 도구 또는 기능을 나타냅니다.

데이터 세트

이 예제에 사용되는 데이터 세트는 다음과 같습니다. 이 데이터 세트는 서비스 지연과 관련된 사례, 법원의 판결 이유 및 최종 결과를 설명하는 법적 판례 모음입니다.

데이터 수집 및 인덱스 설정

인덱스 설정 및 데이터 수집 로직은 dataIngestion.ts 파일에 정의되어 있으며, 여기서 인덱스 생성을 처리하는 함수를 선언합니다. 이 설정은 Elasticsearch용 LangChain 벡터 저장소 인터페이스와 호환됩니다.

참고: 매핑 설정은 dataIngestion.ts 파일에도 포함되어 있습니다.

패키지 설치 및 환경 변수 설정

기본 설정으로 Node.js 프로젝트를 초기화합니다.

  • @elastic/elasticsearch: Node.js용 Elasticsearch 클라이언트입니다. 연결, 인덱스 생성 및 쿼리 실행에 사용됩니다.
  • @langchain/community: ElasticVectorSearch 스토어를 비롯한 커뮤니티 지원 도구에 대한 통합을 제공합니다.
  • @langchain/core: 체인, 프롬프트, 유틸리티와 같은 LangChain의 핵심 구성 요소입니다.
  • @langchain/langgraph: 그래프 기반 오케스트레이션을 추가하여 노드, 엣지 및 상태 관리를 포함하는 워크플로우를 지원합니다.
  • @langchain/openai: LangChain을 통해 OpenAI 모델(LLM 및 임베딩)에 대한 액세스를 제공합니다.
  • dotenv:.env 파일에서 process.env로 환경 변수를 로드합니다.
  • tsx: TypeScript 코드를 실행하는 데 유용한 도구입니다.

콘솔에서 다음 명령어를 실행하여 모든 항목을 설치하세요.

.env 파일을 생성하여 환경 변수를 설정합니다.

타입 안전성과 더 나은 개발자 경험을 제공하기 때문에 TypeScript를 사용하여 코드를 작성할 것입니다. main.ts라는 이름의 TypeScript 파일을 만들고 다음 섹션의 코드를 삽입합니다.

패키지 가져오기

main.ts 파일에서 필요한 모듈을 가져오고 환경 변수 구성을 초기화하는 것으로 시작합니다. 여기에는 핵심 LangGraph 구성 요소, OpenAI 모델 통합, Elasticsearch 클라이언트가 포함됩니다.

또한 DataingEstion.ts 파일에서 다음을 가져옵니다.

  • ingestData: 인덱스를 생성하고 데이터를 수집하는 함수입니다.
  • Document 및 DocumentMetadata: 데이터셋 문서 구조를 정의하는 인터페이스입니다.

Elasticsearch 벡터 저장소 클라이언트, 임베딩 클라이언트 및 OpenAI 클라이언트

이 코드는 벡터 저장소, 임베딩 클라이언트 및 OpenAI 클라이언트 하나를 초기화합니다.

애플리케이션 워크플로우 상태 스키마는 노드 간 통신에 도움이 됩니다.

상태 객체에서는 사용자의 쿼리, 쿼리에서 추출된 개념, 검색된 법적 판례 및 감지된 모호성을 노드를 통해 전달합니다. 또한 사용자가 선택한 판례, 그 과정에서 생성된 분석 초안, 모든 설명이 완료된 후 최종 분석도 추적합니다.

노드

searchPrecedents: 이 노드는 사용자의 입력에 따라 Elasticsearch 벡터 저장소에서 유사성 검색을 수행합니다. 이 기능은 일치하는 문서를 최대 5개까지 검색하여 사용자가 검토할 수 있도록 인쇄합니다.

precedentSelection: 이 노드를 사용하면 사용자가 자연어를 사용하여 근접 검색에서 검색된 사용 사례 중 질문과 가장 잘 일치하는 사용 사례를 선택할 수 있습니다. 이 시점에서 애플리케이션은 워크플로우를 중단하고 사용자 입력을 기다립니다.

selectPrecedent: 이 노드는 검색된 문서 중 하나를 선택할 수 있도록 해석할 사용자 입력을 검색된 문서와 함께 전송합니다. LLM은 사용자의 자연어 입력으로부터 추론한 문서를 나타내는 숫자를 반환함으로써 이 작업을 수행합니다.

createDraft: 이 노드는 사용자가 선택한 판례를 기반으로 초기 법적 분석을 생성합니다. LLM을 사용하여 선택된 판례가 변호사의 질문에 어떻게 적용되는지 평가하고, 시스템이 진행하기에 충분한 정보를 가지고 있는지 결정합니다.

판례를 바로 적용할 수 있는 경우, 노드는 초안 분석 결과를 생성하고 올바른 경로를 따라 최종 노드로 이동합니다. LLM이 모호성, 예를 들어 정의되지 않은 계약 조건, 누락된 타임라인 세부 사항 또는 불명확한 조건을 감지하면 명확화가 필요함을 나타내는 플래그와 함께 제공되어야 하는 구체적인 정보 목록을 반환합니다. 이 경우 모호성으로 인해 그래프의 왼쪽 경로가 선택됩니다.

그래프가 취할 수 있는 두 가지 경로는 다음과 같습니다.

왼쪽 경로에는 설명을 처리하는 추가 노드가 포함되어 있습니다.

requestClarification: 이 노드는 초안 분석에 필수 컨텍스트가 부족하다고 시스템이 식별하면 두 번째 휴먼 인 더 루프 단계를 트리거합니다. 워크플로우가 중단되고 사용자에게 이전 노드에서 감지한 누락된 계약 세부 정보를 명확히 해달라는 메시지가 표시됩니다.

generateFinalAnalysis: 이 노드는 선택한 판례와 필요한 경우 사용자가 제공한 추가 컨텍스트를 결합하여 최종 법률 분석을 생성합니다. 이전 HITL 단계에서 수집한 설명을 사용하여, LLM은 판례의 추론, 사용자가 제공한 계약 세부 정보 및 위반이 발생했는지 여부를 결정하는 조건을 종합합니다.

이 노드는 법적 해석과 실용적인 권장 사항을 통합한 완전한 분석을 출력합니다.

그래프 작성:

그래프에서 조건부 엣지가 "최종" 경로를 선택하는 조건을 정의한다는 것을 볼 수 있습니다. 위에서 살펴본 바와 같이, 이제 결정은 초안 분석에서 추가 설명이 필요한 모호성을 발견했는지 여부에 따라 달라집니다.

모두 합쳐서 실행:

스크립트 실행:

모든 코드가 할당되었으므로 터미널에 다음 명령어를 입력하여 main.ts 파일을 실행합니다.

스크립트가 실행되면, "반복되는 지연 패턴이 각 개별 지연이 경미하더라도 침해에 해당하는가?"라는 질문이 Elasticsearch로 전송되어 근접 검색을 수행하게 되며, 인덱스에서 얻은 결과가 표시됩니다. 앱은 쿼리와 일치하는 여러 관련 판례를 감지하여 실행을 일시정지하고 사용자에게 어떤 법적 판례가 가장 적합한지 명확히 설명하도록 요청합니다.

이 애플리케이션의 흥미로운 점은 자연어를 사용하여 하나의 옵션을 선택할 수 있고, LLM이 사용자의 입력을 해석하여 올바른 선택을 결정할 수 있다는 점입니다. "Case H" 텍스트를 입력하면 어떻게 되는지 살펴봅시다.

이 모델은 사용자의 설명을 받아 워크플로우에 통합하여 충분한 컨텍스트가 제공되면 최종 분석을 진행합니다. 이 단계에서는 이전에 감지된 모호성을 활용하여 초안 분석에서 법적 해석에 의미 있는 영향을 미칠 수 있는 누락된 계약 세부 사항을 강조 표시합니다. 이러한 '누락된 정보' 항목은 신뢰할 수 있는 최종 의견을 도출하기 전에 불확실성을 해소하기 위해 어떤 설명이 필요한지 판단하는 데 도움이 됩니다.

사용자는 다음 입력에 설명을 요청한 내용을 포함해야 합니다. "계약서에는 기간 없이 ‘신속한 배송’이 요구됩니다. 6개월 동안 2-4일의 지연이 8번 발생했습니다. 3번의 고객 마감일을 놓쳐 50,000달러의 손실이 발생했습니다. 공급업체에 통보했지만 패턴은 계속되었습니다."로 시도해 보겠습니다.

이 출력은 워크플로우의 마지막 단계로, 모델이 선택한 판례(사례 H)와 변호사의 설명을 통합하여 완전한 법률 분석을 생성하는 과정을 보여줍니다. 이 시스템은 지연 패턴이 위반에 해당하는 이유를 설명하고, 이러한 해석을 뒷받침하는 요인을 간략하게 설명하며, 실질적인 권장 사항을 제공합니다. 전반적으로, 이 출력은 HITL 명확화가 어떻게 모호성을 해소하고 모델이 타당한 맥락에 맞는 법적 의견을 도출할 수 있도록 하는지를 보여줍니다.

기타 실제 시나리오

Elasticsearch, LangGraph, 휴먼 인 더 루프 등을 사용하는 이러한 종류의 애플리케이션은 다른 종류의 앱에서도 유용하게 사용될 수 있습니다.

  • 도구 호출을 실행하기 전에 검토합니다. 예를 들어, 금융 거래에서는 주문이 입력되기 전에 인간이 매수/매도 주문을 승인합니다.
  • 필요에 따라 추가 매개변수를 제공합니다. 예를 들어, 고객 지원 분류 과정에서 AI가 고객 문제에 대해 여러 가지 가능한 해석을 제시할 때 상담원이 올바른 문제 범주를 선택하는 경우에 유용합니다.

그리고 휴먼 인 더 루프가 판도를 바꾸는 요소가 될 많은 사용 사례들이 발견되어야 합니다.

결론

LangGraph와 Elasticsearch를 사용하면 자체적으로 결정을 내리고 선형 워크플로우로 작동하거나 한 경로 또는 다른 경로를 선택하는 조건을 가진 에이전트를 구축할 수 있습니다. 휴먼 인 더 루프를 통해 에이전트는 실제 사용자를 의사 결정 과정에 참여시켜 문맥상의 공백을 메우고 내결함성이 중요한 시스템에 대한 확인을 요청할 수 있습니다.

이 접근 방식의 장점 중 하나는 Elasticsearch 기능을 사용하여 대규모 데이터 세트를 필터링한 다음 LLM을 사용하여 사용자가 선택한 단일 문서를 가져올 수 있다는 것입니다. Elasticsearch만 사용하면 이 마지막 단계는 훨씬 더 까다로울 것입니다. 왜냐하면 인간이 자연어를 사용하여 결과를 언급할 수 있는 방법이 많기 때문입니다.

이 접근 방식은 전체 데이터 세트가 아닌 최종 결정을 내리는 데 필요한 정보만 LLM에 전송하므로 시스템의 속도와 토큰 효율을 유지합니다. 동시에 사용자의 의도를 매우 정확하게 감지하고 원하는 옵션이 선택될 때까지 반복합니다.

관련 콘텐츠

최첨단 검색 환경을 구축할 준비가 되셨나요?

충분히 고급화된 검색은 한 사람의 노력만으로는 달성할 수 없습니다. Elasticsearch는 여러분과 마찬가지로 검색에 대한 열정을 가진 데이터 과학자, ML 운영팀, 엔지니어 등 많은 사람들이 지원합니다. 서로 연결하고 협력하여 원하는 결과를 얻을 수 있는 마법 같은 검색 환경을 구축해 보세요.

직접 사용해 보세요