Jev로 하네스 만들기

TMT

https://www.langchain.com/blog/building-a-harness-with-jev

에이전트는 반복 루프로 동작합니다. LLM이 무엇을 할지 결정하면 도구가 실행하고, 모델이 결과를 평가합니다. 그런 다음 작업이 끝날 때까지 이 과정을 반복합니다.

소프트웨어 애플리케이션은 구조화된 데이터와 예측 가능한 인터페이스를 바탕으로 동작하기 때문에, 초기에는 에이전트와 LLM을 애플리케이션에 통합하기가 어려웠습니다. 이후 두 가지 기본 기능이 등장하면서 통합이 훨씬 쉬워졌습니다.

  • 도구 호출을 통해 모델이 구조화된 요청을 보내고 구조화된 결과를 받을 수 있게 되었습니다.
  • 구조화된 출력을 통해 모델이 결과를 구조화된 형태로 반환할 수 있게 되었습니다.

하지만 이런 기능이 있어도 에이전트 루프는 여전히 느리고 비용이 많이 듭니다. 결정을 내릴 때마다 모델을 다시 호출해야 하기 때문입니다.

여기에 Jev가 등장했습니다. Jev는 TypeSafe AI가 출시한 새로운 모델입니다. 회사에 따르면 분류 작업에서 비교 대상 LLM보다 추론 속도는 최대 200배 빠르고, 비용은 최대 400분의 1 수준이라고 합니다.

이 글에서는 Jev의 작동 방식과 에이전트 루프에서 맡는 역할, 그리고 LangChain과 함께 사용하는 방법을 살펴봅니다.

Jev 알아보기

사실 Jev는 기존의 LLM과 다릅니다. 텍스트를 생성하지 않습니다. TypeSafe AI 팀이 System One 모델이라고 부르는 모델입니다.

📖 System One 모델은 소프트웨어가 바로 활용할 수 있는 구조화된 결정을 빠르게 내리도록 만든 AI 모델입니다. System One 모델은 상태(state)를 평가하고, 타입이 지정된 답변과 확률을 반환합니다.

Jev는 판단의 확률을 보정하기 위한 강화 학습(RLCD)으로 훈련되었습니다. 코드에서 이 결과를 활용해 에이전트가 다음에 무엇을 할지 정할 수 있으므로, 결정을 내릴 때마다 채팅 LLM을 호출할 필요가 없습니다.

Jev 모델을 호출할 때는 상태, 즉 맥락과 그 상태에 관한 질문을 전달합니다. 다음은 공식 문서의 고객 지원 티켓 예제를 질문 하나로 구성한 것입니다.

{
  "model": "jev-latest",
  "state": "안녕하세요. 3일째 Stripe 계정 연결을 시도하고 있는데 계속 실패합니다. 매출 손실이 발생하고 있습니다. 최대한 빨리 도와주세요.",
  "questions": {
    "is_urgent": {
      "type": "noul",
      "instructions": "메시지에 긴급하거나 신속한 대응이 필요한 상황이 드러나 있다"
    }
  }
}

문서의 예제는 긴급성에 대해 다음과 같이 답합니다. 여기서는 응답의 나머지 부분을 생략했습니다.

{
  "is_urgent": {
    "type": "noul",
    "noul": 0.999
  }
}

이 메시지가 긴급할 확률이 99.9%라는 뜻이며, 애플리케이션은 이 값을 이용해 티켓의 처리 우선순위를 정할 수 있습니다.

지원하는 질문의 유형은 세 가지입니다.

Image
  • Choice: 주어진 선택지 중에서 고릅니다. 각 선택지의 확률과 전체 신뢰도 점수를 반환합니다.
  • Score: 낮음, 중간, 높음처럼 순서가 있는 단계에 따라 입력을 평가합니다. 연속적인 점수와 그 바탕이 되는 분포, 신뢰도 값을 반환합니다.
  • Noul: 예 또는 아니요로 답할 수 있는 질문에 답합니다. 주어진 진술이 참일 확률을 반환합니다.

한 번의 요청으로 같은 상태에 대해 여러 질문을 할 수 있다는 점도 핵심 기능입니다.

💡 System One 모델은 요청에 담긴 모든 질문을 병렬로 평가합니다. 질문을 추가해도 응답 시간은 거의 달라지지 않으며, 비용도 추가 질문에 해당하는 토큰만큼만 늘어나므로 저렴합니다.

고객 지원 티켓에 대해 여러 질문을 하는 예제는 TypeSafe 빠른 시작 가이드에서 확인할 수 있습니다.

즉, Jev는 기존 LLM과 달리 텍스트 생성이나 순차적인 의사 결정에 얽매이지 않습니다!

LangChain에서 Jev 사용하기

LangChain은 특정 제공업체에 종속되지 않는 모델을 채택하고 있어, 수천 개의 다른 통합 기능 및 모델 제공업체와 함께 Jev를 지원하기에도 적합합니다.

LangChain 통합 기능TypeSafeClassifier를 통해 Jev를 제공합니다. .invoke()에 상태와 질문을 전달하면 채팅 응답 대신 분류 결과를 받습니다.

langchain-typesafe를 설치하고 TYPESAFE_API_KEY를 설정한 다음, 아래와 같이 호출합니다.

from langchain_typesafe import Noul, TypeSafeClassifier

classifier = TypeSafeClassifier()

response = classifier.invoke(
    state=(
        "배포가 두 번 실패했고 고객들에게 500 오류가 나타나고 있습니다. "
        "지금 확인해 주실 분 계신가요?"
    ),
    questions={
        "urgent": Noul(
            instructions="지금 바로 대응해야 하나요?"
        ),
    },
)

urgency = response.nouls["urgent"].noul

상태에는 텍스트, 구조화된 데이터, LangChain 메시지를 사용할 수 있습니다. 따라서 에이전트가 이미 가진 맥락을 활용해 노드나 미들웨어 훅에서 Jev를 쉽게 호출할 수 있습니다.

이를 커스텀 미들웨어나 도구에 넣어 활용할 수도 있습니다!

활용 사례

Jev로 LLM을 그대로 대체할 수는 없습니다. 텍스트를 생성하지는 않지만, 지금까지 흔히 LLM에 맡겨 온 분류 작업을 더 적은 지연 시간과 비용으로 처리할 수 있습니다. 따라서 에이전트를 구동하는 모델을 보완할 수 있는 유망한 수단입니다. 정해진 답이 없는 추론과 생성에는 LLM을 사용하고, 그 과정에서 구조화된 결정을 빠르게 내려야 할 때는 Jev를 사용하는 것입니다.

모델 라우팅

단순 조회에 어려운 디버깅 작업과 같은 모델을 쓸 필요는 없습니다. 모델 라우팅 미들웨어를 사용하면 Jev가 요청을 평가하고, 미리 정의한 기준에 따라 모델을 선택합니다. 간단한 작업에는 빠르고 저렴한 모델을, 복잡한 작업에는 성능이 더 좋은 모델을 선택하는 식입니다.

from langchain.agents import create_agent
from langchain_typesafe.experimental.middleware import (
    ModelChoice,
    ModelRouterMiddleware,
)

router = ModelRouterMiddleware(
    choices={
        "fast": ModelChoice(
            model="openai:<빠른 모델 ID>",
            criteria="단순 조회, 추출, 국소적인 변경.",
        ),
        "powerful": ModelChoice(
            model="openai:<고성능 모델 ID>",
            criteria="아키텍처와 중대한 의사 결정.",
        ),
    },
    instructions="작업을 완료할 수 있는 모델 중 비용이 가장 낮은 모델을 선택하세요.",
)

agent = create_agent("openai:<빠른 모델 ID>", middleware=[router])

라우터는 가장 최근의 사용자 메시지를 바탕으로 모델을 선택하고, 실행이 끝날 때까지 그 모델을 사용합니다. 확률과 신뢰도도 에이전트 상태에 남아 있어 활용할 수 있습니다.

자동 모드

에이전트는 여전히 본질적으로 신뢰하기 어렵습니다. 에이전트는 잘못된 지시를 받을 수 있으며, 그 지시가 우연히 주어졌든 충분한 의지를 가진 공격자가 의도적으로 주입했든, 지시에 설득되어 우리가 원하지 않는 행동을 할 수 있습니다.

Claude, Codex, Cursor 같은 코딩 하네스는 위험한 행동을 실행하기 전에 분류하는 기능을 어떤 형태로든 도입해 왔으며, 덕분에 에이전트에 대한 신뢰도 조금씩 쌓이고 있습니다. 하지만 지금까지 이 분류 단계는 하네스에서 소스가 공개되지 않은 부분에만 들어 있었습니다.

이제 저렴하면서도 성능이 좋은 분류 모델이 나왔으니, 같은 방식을 모든 에이전트에 적용할 수 있습니다!

from langchain.agents import create_agent
from langchain_typesafe.experimental.middleware import (
    AutoModeMiddleware,
)

guardrail = AutoModeMiddleware(tools=["bash"])

agent = create_agent("openai:<모델 ID>", middleware=[guardrail])

AutoModeMiddleware는 Jev를 사용해 도구 호출에 위험한 판단이 포함되어 있는지 확인하고, 도구가 실행되기 전에 호출을 차단합니다.

시작해 보세요!

저희는 Jev와 그 가능성에 큰 기대를 걸고 있습니다. 벌써 눈길을 끄는 프로젝트도 여럿 보입니다. Browserbase의 Kyle Jeong은 1센트도 안 되는 비용으로 브라우저 사용 에이전트를 구동하고 있고, Jarrod Watts는 실시간 트레이딩 에이전트를 만들었으며, Ryan Vogel은 대규모로 이메일을 분류하고 우선순위를 정하고 있습니다.

이제는 매주 새로운 모델이 나오지만, 이번 모델은 유난히 큰 반응을 얻었습니다. 여러분이 LangChain과 Jev로 무엇을 만들지 기대됩니다.

포럼에 의견을 남기거나, X에서 저희를 태그해 만들고 있는 것을 공유하거나, LangChain 이슈에 참여해 주세요!

Edit this page

Search the archive

Find a page by title, or search the text inside one.