LangChain - Agent Middleware

TMT

https://blog.langchain.com/agent-middleware/

LangChain은 거의 3년 동안 에이전트 추상화를 제공해 왔습니다. 이제 동일한 핵심 추상화를 가진 에이전트 프레임워크가 아마도 수백 개는 있을 것입니다. 이들은 모두 초기 LangChain 에이전트가 겪었던 동일한 단점을 겪습니다: 필요할 때 개발자에게 컨텍스트 엔지니어링에 대한 충분한 제어 권한을 주지 못해, 개발자들이 사소하지 않은 사용 사례에서는 이 추상화를 졸업하게 만듭니다. LangChain 1.0에서는 우리가 이를 해결한다고 생각하는 새로운 에이전트 추상화(‎⁠Middleware⁠)를 도입합니다.

핵심 에이전트 구성 요소는 매우 간단합니다:

  • 모델
  • 프롬프트
  • 도구 목록

핵심 에이전트 알고리즘도 동일하게 단순합니다. 사용자가 어떤 입력 메시지로 에이전트를 먼저 호출하면, 에이전트는 루프를 실행하며 도구를 호출하고, AI 및 도구 메시지를 상태에 추가하다가, 더 이상 도구를 호출하지 않기로 결정하고 최종적으로 종료합니다.

Image

우리는 2022년 11월에 LangChain에 이 에이전트의 버전을 보유하고 있었고, 지난 3년 동안 수백 개의 프레임워크가 유사한 추상화와 함께 등장했습니다.

동시에, 기본적인 에이전트 추상화를 작동시키는 것은 쉽지만, 이 추상화를 프로덕션에 가져올 만큼 유연하게 만드는 것은 어렵습니다.

이 블로그에서는 다음을 다룹니다:

  1. 왜 이 추상화를 프로덕션에 가져오기 충분히 신뢰할 수 있게 만드는 것이 어려운지
  2. 지난 1년여에 걸친 더 신뢰할 수 있도록 만들기 위한 우리의 여정
  3. 우리가 LangChain 1.0에서 도입하는 새로운 ‎⁠Middleware⁠ 추상화, 이것이 가장 유연하고 합성 가능한 에이전트 추상화라고 생각하는 이유

왜 이 추상화를 프로덕션으로 가져오기 어려운가

그렇다면 왜 여전히 이러한 프레임워크로 신뢰할 수 있는 에이전트를 구축하는 것이 어려울까요? 왜 많은 사람들이 일정 수준의 복잡도에 도달하면 프레임워크를 떠나 맞춤 코드를 선호할까요?

답은 컨텍스트 엔지니어링입니다. 모델에 들어가는 컨텍스트가 그 결과를 결정합니다. 모델(따라서 에이전트)을 더 신뢰할 수 있게 만들기 위해서는 모델에 들어가는 것에 대해 완전한 제어를 하고 싶어집니다. 그리고 이 단순한 에이전트 상태와 단순한 에이전트 루프는 시작하기에 훌륭하지만, 에이전트 성능의 한계를 밀어붙이다 보면 그 일부를 수정하고 싶어질 가능성이 큽니다.

복잡성이 증가함에 따라 더 많은 제어를 하고 싶어질 수 있는 것들이 여러 가지 있습니다:

  1. 에이전트의 “상태”를 메시지 이상으로 조정하고 싶을 수 있습니다
  2. 모델에 정확히 무엇이 들어가는지에 대해 더 많은 제어를 하고 싶을 수 있습니다
  3. 실행되는 단계의 순서에 대해 더 많은 제어를 하고 싶을 수 있습니다

더 신뢰할 수 있도록 만들기 위한 우리의 여정

지난 2년 동안 우리는 에이전트 추상화가 컨텍스트 엔지니어링을 더 잘 지원하도록 작업했습니다. 우리가 한 일들(대략 순서대로):

  • 사용자가 런타임 구성 지정 가능: 연결 문자열 및 읽기 전용 사용자 정보 같은 것을 전달
  • 사용자가 임의의 상태 스키마 지정 가능: 사용자 또는 에이전트가 업데이트할 수 있음
  • 사용자가 문자열이 아닌 프롬프트를 반환하는 함수를 지정 가능: 동적 프롬프트 허용
  • 사용자가 모델에 전달되는 전체 메시지 목록을 완전히 제어하기 위해 메시지 목록을 반환하는 함수를 지정 가능
  • 사용자가 “프리 모델 훅(pre model hook)”을 지정 가능: 모델 호출 전에 단계를 실행하여 상태를 업데이트하거나 다른 노드로 점프. 이는 긴 대화 요약과 같은 것을 가능하게 함.
  • 사용자가 “포스트 모델 훅(post model hook)”을 지정 가능: 모델 호출 후에 단계를 실행하여 상태를 업데이트하거나 다른 노드로 점프. 이는 human-in-the-loop 및 가드레일과 같은 것을 가능하게 함.
  • 각 호출에서 사용할 모델을 반환하는 함수를 사용자가 지정 가능: 동적 모델 스위칭 및 동적 도구 호출을 가능하게 함.

이는 수행되는 컨텍스트 엔지니어링에 대해 높은 수준의 사용자 정의와 제어를 가능하게 했습니다.

하지만 그 결과 에이전트에 많은 수의 파라미터가 생겼습니다. 게다가 이러한 파라미터는 종종 서로 의존성이 있어 조율하기가 어려웠습니다. 또한 이러한 파라미터의 여러 버전을 결합하거나, 시험해 볼 수 있는 완제품 변형을 제공하기도 어려웠습니다.

LangChain 1.0에서 우리가 하는 일

LangChain 1.0에서는 ‎⁠Middleware⁠라는 개념을 도입하여 이 핵심 에이전트 루프를 수정하는 아이디어로 기울입니다.

핵심 에이전트 루프는 여전히 모델 노드와 도구 노드로 구성됩니다. 하지만 이제 미들웨어는 다음을 지정할 수 있습니다:

  • ‎⁠before_model⁠: 모델 호출 전에 실행되며, 상태를 업데이트하거나 다른 노드로 점프할 수 있습니다.
  • ‎⁠after_model⁠: 모델 호출 후에 실행되며, 상태를 업데이트하거나 다른 노드로 점프할 수 있습니다.
  • ‎⁠modify_model_request⁠: 모델 호출 전에 실행되며, 사용자에게 (해당 모델 요청에 한해) 도구, 프롬프트, 메시지 목록, 모델, 모델 설정, 출력 형식, 도구 선택을 수정할 수 있도록 합니다.

에이전트에 여러 미들웨어를 제공할 수 있습니다. 미들웨어는 웹 서버에서처럼 실행됩니다: 모델 호출로 들어가는 경로에서는 순차적으로(‎⁠before_model⁠, ‎⁠modify_model_request⁠), 돌아오는 경로에서는 역순으로(‎⁠after_model⁠) 실행됩니다.

Image

미들웨어는 사용자 정의 상태 스키마와 도구도 지정할 수 있습니다.

우리는 개발자가 시작할 수 있도록 미리 준비된 미들웨어를 제공할 것입니다. 또한 커뮤니티 미들웨어 목록을 유지하여 쉽게 접근할 수 있도록 하겠습니다. 한동안 개발자들은 LangGraph 에이전트에 플러그인할 수 있는 노드 모음(collections)을 요청해 왔습니다. 이것이 바로 그것입니다.

미들웨어는 우리의 다양한 에이전트 추상화를 통합하는 데에도 도움이 될 것입니다. 현재 우리는 supervisor, swarm, bigtool, deepagents, reflection 등용 LangGraph 에이전트를 별도로 보유하고 있습니다. 우리는 이미 미들웨어를 사용하여 이러한 아키텍처를 복제할 수 있음을 검증했습니다.

LangChain 1.0 알파에서 사용해 보기

가장 최신 LangChain 1.0 알파 릴리스(Python 및 JavaScript)에서 미들웨어를 사용해 볼 수 있습니다. 이것은 LangChain 1.0의 가장 큰 새로운 부분이므로 미들웨어에 대한 여러분의 피드백을 매우 원합니다.

이 알파 릴리스의 일부로, 우리는 세 가지 다른 미들웨어 구현(모두 내부 에이전트에서 이미 사용 중)을 출시합니다:

  1. Human-in-the-loop: ‎⁠Middleware.after_model⁠을 사용하여 도구 호출에 대한 human-in-the-loop 피드백을 얻기 위한 인터럽트를 손쉽게 추가하는 방법을 제공합니다.
  2. Summarization: ‎⁠Middleware.before_model⁠을 사용하여 메시지가 특정 임계값을 초과하여 누적될 때 메시지를 요약합니다
  3. Anthropic Prompt Caching: ‎⁠Middleware.modify_model_request⁠를 사용하여 특별한 프롬프트 캐싱 태그를 메시지에 추가합니다.

Python에서 사용해 보기: ‎⁠pip install --pre -U langchain⁠

JavaScript에서 사용해 보기: ‎⁠npm install langchain@next⁠

Edit this page

On this Page