Jev와 LangGraph를 사용한 프로덕션 에이전트 구축하기
요약
TypeSafe가 출시한 Jev는 텍스트 생성 대신 구조화된 결정을 내리는 새로운 모델입니다. 이는 에이전트의 라우팅 및 분류와 같은 좁은 결정 작업에서 기존 LLM 대비 압도적인 속도와 비용 효율성을 제공합니다. LangGraph를 활용하여 Jev의 장점을 극대화함으로써, 신뢰할 수 있고 관찰 가능한 '프로덕션'급 AI 시스템을 구축하는 방법을 제시합니다.
핵심 포인트
- Jev는 텍스트 생성 대신 구조화된 결정을 내리는 모델입니다.
- 좁은 결정 작업에서 기존 LLM보다 빠르고 저렴하게 작동합니다.
- LangGraph와 결합하여 신뢰할 수 있는 프로덕션 에이전트를 구축할 수 있습니다.
- AI 기반 소프트웨어는 코드(구조)와 모델(판단)을 결합하는 중간 경로를 취합니다.
지난주 TypeSafe AI는 새로운 종류의 모델인 Jev를 출시했습니다. 기존 LLM과 달리, Jev는 텍스트를 생성하지 않습니다. 대신, 코드가 직접 행동할 수 있는 결정을 내리며, 이는 TypeSafe가 'AI 기반 소프트웨어'라고 부르는 영역입니다. 이 분야에서는 '워크플로우는 코드가 소유하고 AI는 좁고 구조화된 결정(narrow, structured decisions)을 처리합니다.' TypeSafe는 이러한 철학을 '신(god)이 아닌 프로덕션(prod)' 구축으로 요약합니다.
최첨단 LLM들이 점점 더 강력해지면서, 우리는 이들을 마치 신처럼 취급하기 시작했습니다. 모호한 입력(fuzzy inputs)이 들어오는 모든 작업에 대해 의존하죠: 산문 생성, 문서 추출, 검색, 순위 지정, 리서치, 분류 등등입니다. 하지만 안타깝게도, 신은 비싸고 느립니다. 단지 예/아니오만 필요할 때조차 그 일반성(generality)에 대한 비용을 호출마다 지불해야 합니다.
이것이 Jev의 출시가 큰 주목을 받은 이유입니다. 많은 에이전트들이 기반으로 하는 라우팅 및 분류 단계와 같은 좁은 결정 작업에서, TypeSafe의 벤치마크는 Jev가 선도적인 LLM보다 최대 200배 빠르고 400배 저렴하게 작동함을 보여줍니다.
TypeSafe의 접근 방식은 LangChain에 있는 저희에게 거의 향수를 불러일으키는 느낌이었습니다. 우리의 임무는 에이전트를 유용하고 보편적으로 만드는 것이며, 우리의 오픈 소스 생태계는 모델 환경이 발전함에 따라 진화해 왔습니다. 하지만 매 단계마다 우리는 같은 두 가지 질문으로 돌아왔습니다: 어떻게 하면 모델들이 유용한 결정을 내리게 할 수 있을까? 그리고 그 결정들을 어떻게 신뢰할 수 있게 행동(act)하게 할 수 있을까?
LangGraph는 이 두 질문에 대한 우리의 해답입니다. 우리는 수많은 기업이 AI를 프로덕션 환경에 도입하도록 돕는 과정에서 배운 것을 바탕으로 이를 구축했으며, 이는 모델 기반의 결정과 결정론적 코드(deterministic code)를 결합하여 신뢰할 수 있고 관찰 가능한 시스템을 만들 수 있게 해줍니다. Jev는 이러한 시스템들이 결정을 내리는 더 빠르고 저렴한 방법을 제공합니다. 이 게시물에서는 Jev와 LangGraph를 사용하여 '신이 아닌 프로덕션'을 구축하는 방법을 다룰 것입니다.
결정에 사용되는 Jev
Jev는 최첨단 LLM 번들에서 판단(judgment)이라는 하나의 기능을 분리하여 측정하기 너무 저렴한 원시 요소로 만듭니다. 이는 TypeSafe가 시스템 원(system one) 모델이라고 부르거나, 더 일반적으로 의사결정 모델(decision model)이라고 불리는 것입니다. 이 모델에 상태와 일련의 질문을 제공하면, 확률과 함께 타입이 지정된 답변을 반환합니다.
TypeSafe의 문서는 소프트웨어를 구축하는 세 가지 방법을 제시합니다. 전통적인 소프트웨어는 명시적 논리(explicit logic)로 구성되며, 모든 분기(branch)가 수동으로 작성되고 감사 가능하지만 그 결과로 경직됩니다. 에이전트들은 반대 방향으로 움직였습니다. 즉, 하나의 모델이 매 단계마다 결정을 처리하고 제어 흐름이 코드에서 프롬프트로 이동합니다. AI 기반 소프트웨어는 중간 경로를 취합니다. 코드는 구조를 유지하고 정확한 계산을 처리하며, 모델은 의미론적 판단(semantic judgment)이 필요한 분기 지점에만 배치됩니다.

다음 속성들은 Jev가 프로덕션 시스템의 구성 요소로 자격이 있음을 보여줍니다:
구조화됨(Structured): 답변은 확률과 함께 타입이 지정된 답변으로 돌아오므로, 코드가 결과에 따라 예측 가능하게 분기할 수 있습니다.
병렬적(Parallel): 동일한 상태에 대해 여러 질문을 한 번에 할 수 있습니다.
빠름(Fast): 결정 비용이 저렴하여 단일 실행에서 많은 결정을 내릴 수 있습니다.
자기 일관성(Self consistent): 시스템 원은 반복적인 평가 전반에 걸쳐 안정적인 답변을 반환하도록 설계되었습니다.
💡 Jev의 일관성은 LLM의 비결정성(non-determinism)과는 환영할 만한 변화입니다. LLM에게 같은 질문을 여러 번 실행하여 물어보면 다른 답변을 얻을 수 있습니다. Jev는 동일한 입력에 대해 동일한 답변을 반환하도록 설계되었습니다. 초기 Jev-as-a-judge 실험에서, 이 모델의 점수는 100번 반복된 실행 전반에 걸쳐 거의 움직이지 않았으며, 테스트했던 어떤 LLM 판정기보다 훨씬 적었습니다.
예를 들어, 이 비디오는 Jev가 LLM과 어떻게 다르게 작동하는지 시각화하는 데 도움이 됩니다. 여기서의 작업은 입력에 다양한 유형의 PII(개인 식별 정보)가 포함되어 있는지 여부를 판단하는 것입니다:
실제 애플리케이션은 수많은 결정을 내리며, 각 결정은 이전 선택에 복잡하게 의존합니다. 일단 결정 비용이 저렴해지면, 과제는 이들을 오케스트레이션(orchestrating)하는 것이 되며, 이것이 바로 LangGraph가 하는 일입니다.
LangGraph를 사용한 오케스트레이션
우리는 수년 동안 LLM을 중심으로 시스템을 구축하는 팀들을 도와왔으며, 거의 모든 팀이 동일한 두 가지 문제에 직면합니다:
컨텍스트 관리의 어려움. 모델이 올바른 결정을 내리려면 컨텍스트 창(context window)에 '다음 단계를 위한 정확히 필요한 정보'가 있어야 합니다. 이 정보는 모호하며, 애플리케이션이 실행됨에 따라 변합니다.
모델 기반 시스템의 신뢰성 확보 필요. 이러한 시스템은 장애를 견뎌내야 하고, 인간의 개입을 지원해야 하며, 모든 단계를 관찰 가능하게 만들어야 합니다.
기존 프레임워크들은 이 문제들의 일부를 다루었지만, 개발 방식에 제약을 가하지 않으면서 둘 다 해결한 것은 없었습니다. 그래서 저희가 LangGraph를 만들었습니다. 현재 월 6천만 회 이상 다운로드되었으며 AI로 구축하는 포춘 500대 기업들로부터 많은 사용을 받고 있습니다.
상태(State)를 컨텍스트로 활용하기
LangGraph 애플리케이션은 세 가지 요소로 구성됩니다. **노드(Nodes)**는 작업 단위입니다: 일반 코드, 모델 호출, 도구 호출 또는 전체 서브그래프일 수 있습니다. **상태(State)**는 노드가 읽고 업데이트하는 정보입니다. **엣지(Edges)**는 고정된 경로를 따르거나 현재 상태에 따라 동적으로 어떤 노드를 실행할지 결정합니다.
어떤 그래프든 더 큰 그래프의 노드가 될 수 있으므로, 작고 테스트된 조각들이 모여 더 큰 시스템을 구성할 수 있습니다. TypeSafe의 선언문은 지능에 대해서도 같은 전제를 합니다: 작고 명확한 기본 요소(primitives)가 복잡한 시스템이 신뢰성을 유지하게 하는 핵심입니다.
그래프가 실행되는 동안, 각 단계의 결과는 상태에 축적됩니다. 이 상태는 이후 모든 단계의 컨텍스트가 되며, 어떤 노드가 다음으로 실행될지 결정하는 근거가 됩니다.
도메인 지식을 프롬프트 안에 단순히 채워 넣는 대신, 그래프의 토폴로지(topology) 안에 인코딩합니다: 어떤 결정이 내려질지, 그 순서는 어떠한지, 그리고 각 단계가 어떤 상태를 볼 수 있는지 말입니다. 이것이 TypeSafe가 말하는 방식으로 소프트웨어가 의도와 상식에 따라 분기할 수 있게 하는 방식입니다. 판단은 모델로부터 오지만, 흐름(flow)은 검사하고 테스트할 수 있는 코드 안에 남아 있습니다.
신뢰할 수 있는 런타임
TypeSafe의 선언문이 주장하듯이, 어떤 구성 요소가 신뢰성이 확보될 때만 방치된 상태로 실행하게 하고, 검사(inspect)하고 테스트하며 제약(constrain)할 수 있을 때만 그 위에 구축해야 합니다. LangGraph는 런타임에서 이를 처리합니다:
- 영속적 실행(Durable execution): 모델 기반 단계는 비결정론적이므로, 동일한 입력이라도 모델이 다른 호출을 유발하여 실행 흐름을 다른 경로로 보낼 수 있습니다. 실패 후 처음부터 다시 시작하는 것은 느린 것보다 더 나쁩니다. 왜냐하면 재실행 시 같은 경로를 추적하지 못할 수도 있기 때문입니다. 체크포인팅(Checkpointing)은 모든 단계에서 상태를 유지하므로, 실패한 실행도 이미 내렸던 결정으로 재개됩니다.
- 인간 개입 루프(Human in the loop): 시스템이 행동하기 전에 검토가 필요한 단계가 있을 때, 인터럽트(interrupts) 기능을 사용하면 일시 중지하고 승인한 후 이전에 멈췄던 지점부터 다시 시작할 수 있습니다.
- 관찰 가능성(Observability): 모델 기반 단계는 매번 같은 작업을 수행하지 않으므로, 무엇이 결정되었고 왜 그렇게 되었는지 확인하려면 LangSmith에 추적 기록(traces)이 필요합니다.
이 중 어느 것도 LLM에만 국한된 것은 아닙니다. Jev 역시 비정형 텍스트 컨텍스트를 입력받아 판단을 내리므로, 동일한 보장이 필요하며, 그래프는 모든 노드에 자동으로 이를 제공합니다.
.png)
예시: 발견(discovery)을 위한 문서 검토
소송에서 회사는 상대방에게 문서를 제출하기 전에 모든 페이지를 검토해야 하며, 단일 사건은 수십만 페이지에 달할 수 있습니다. 이 검토의 대부분은 반복적으로 이루어지는 동일한 경계 판단 호출(bounded judgment call)이므로 Jev가 자연스럽게 적합합니다.
Jev는 각 페이지에 대해 한 번의 요청으로 세 가지 질문에 답하며, 각 답변은 그래프 내의 경로와 연결됩니다:
- 이 페이지가 요청과 관련성이 있습니까? 아니라면 제외됩니다.
- 개인 정보를 포함하고 있습니까? 그렇다면 LLM이 PII(개인 식별 정보)를 삭제합니다.
- 특권 사항일 수 있습니까? 그렇다면
attorney_review로 이동하며, 이는 인간 개입 루프를 위해 그래프를 일시 중지시킵니다.
남은 모든 것은 제출할 준비가 된 것입니다. 흐름에 대한 간단한 데모입니다 (실제로는 페이지들이 병렬로 처리됩니다):
Jev가 모든 분류 작업을 처리하고, 페이지가 더 많은 조치를 필요로 할 때만 그래프가 에스컬레이션합니다: 삭제를 위해 LLM으로, 또는 특권 판단을 위해 변호사에게로.
우리는 Jev가 분류를 처리하고 Sonnet을 심판으로 사용한 동일한 그래프를 실행했으며, Jev는 모든 시도에서 분류 단계에서 5~6배 더 빨랐습니다. 두 실행 모두 LangSmith에 추적되므로, 원하는 페이지를 열어 어떤 경로를 거쳤고 그 뒤에 숨겨진 확률을 확인할 수 있습니다. 또한 LangSmith에는 Jev와 같은 의사결정 모델을 위한 전용 보기(dedicated views)가 있어, 각 결정의 입력값과 보정된 출력값을 보여줍니다:


지능의 위대한 분해화 (The Great Unbundling of Intelligence)
지난 3년 동안 대부분의 에이전트는 모든 것을 하나의 최첨단 LLM(frontier LLM)을 통해 라우팅했습니다. Jaya Gupta는 다음에 올 현상을 "지능의 위대한 분해화(the Great Unbundling of Intelligence)"라고 부릅니다. 이 능력들이 분리되어, 각각 그것을 처리할 수 있는 가장 저렴한 모델로 이동하게 됩니다. Jev는 판단(judgment)을 추출하여 생성된 텍스트 대신 구조화된 결정을 반환합니다. 조각들이 분리되면, 각 단계를 라우팅하고 언제 에스컬레이션할지 결정함으로써 무언가가 그것들을 다시 연결해야 합니다. 이것이 런타임(runtime)의 역할입니다.
브라우저 자동화는 이것이 실제 어떻게 보이는지를 보여줍니다. 브라우저 에이전트는 페이지를 읽고 다음에 무엇을 할지 결정합니다: 버튼 클릭, 필드 채우기, 스크롤하기. 이는 개방적(open-ended)으로 들리지만, 주어진 순간에 페이지가 제공하는 것은 유한한 상호작용 요소 세트일 뿐이므로, 다음 동작은 실제로 목록에서 선택하는 것입니다.
Browserbase는 이 아이디어를 중심으로 Stagehand의 act()를 재구축했습니다. Stagehand는 페이지의 상호작용 요소를 표시하고, Jev가 액션 유형과 최적의 후보 요소를 선택하며, 신뢰도 임계값 0.7 미만인 모든 것은 LLM으로 폴백(fallback)합니다. 초기 테스트에서 중앙값 act() 지연 시간은 1.97초에서 0.46초로 떨어져 약 4.3배 빨라졌습니다.
Jev는 대부분의 사용 사례에서 LLM을 완전히 대체하지 않습니다. Jev는 자신이 확신하는 범위 내의 선택지들을 처리하고, 나머지 모든 것은 LLM에 맡깁니다. 이것이 Gupta가 설명한 '기본적으로 최전선(frontier by default)으로 시작하여 나중에 최적화한다'는 방식에서 '기본적으로 저렴하게(cheap by default) 시작하고 예외적인 경우에만 최전선을 사용한다'로의 변화입니다. 우리는 이러한 패턴을 더 많이 볼 것으로 예상합니다: 결정 모델이 행동 공간이 제한된 곳에서는 빠르고 저렴한 호출을 수행하고, LLM은 개방형 추론과 작은 모델이 확신하지 못하는 경우를 위해 예약되는 것입니다.
개발자들은 이미 이 방향으로 이동하고 있습니다. 이번 주에 한 개발자가 우리에게 말했듯이, '저는 현재 가지고 있는 모든 에이전트를 Jev가 구동하는 워크플로우로 변환하고 있습니다.'
시작하기
- LangGraph를 사용한 3년간의 그래프 엔지니어링에서 LangGraph 런타임 작동 방식 학습하기
- Jev를 모델 라우팅 및 자동 모드 분류기 등을 포함하여 에이전트 하니스에 통합하는 방법 보기 (Building a harness with Jev)
- LangSmith로 에이전트 모니터링 및 평가하기
감사의 글
Sydney Runkle과 Hunter Lovell 작성.
Kevin Frank, Harrison Chase, Eugene Yurtsev, 그리고 Nathan Drezner에게 리뷰와 생각에 감사드립니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 LangChain Blog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기