LangSmith Engine: 에이전트 개선을 위한 에이전트를 구축한 방법
요약
LangSmith Engine은 에이전트 트레이스 위에 위치하여 반복적인 실패 패턴을 자동으로 감지하고, 이를 실행 가능한 문제점(issues)으로 전환하는 새로운 에이전트입니다. 이 엔진은 단순히 오류를 포착하는 것을 넘어, 평가자 및 데이터셋 예시와 같은 지속적인 개선 사항까지 제안하며 에이전트 개발 루프를 지원합니다.
핵심 포인트
- Engine은 트레이스 분석을 통해 반복되는 실패 패턴(issue)을 식별합니다.
- 발견된 문제점에는 심각도, 관련 트레이스, 그리고 해결책인 '제안된 조치'가 포함됩니다.
- 이 엔진은 에이전트 개발의 핵심 루프를 자동화하여 사용자의 개선 시간을 절약해 줍니다.
지난주 저희는 LangSmith Engine을 출시했습니다. Engine은 사용자의 에이전트 트레이스 위에 위치하여 반복되는 문제를 발견하고 다음에 무엇을 해야 할지 제안하는 에이전트입니다.
본 게시물에서는 이를 어떻게 구축했는지에 대한 기술적인 세부 사항을 다룹니다. 즉, 왜 Engine을 만들었는지, 어떤 입출력으로 작동하는지, 그리고 대량의 트레이스를 분석할 수 있게 해준 아키텍처 결정 사항들입니다.
Engine을 구축한 이유
LangSmith는 에이전트 개선 루프(agent improvement loop)의 중심지입니다. 빌드(Build), 테스트(Test), 배포(Deploy), 모니터링(Monitor)은 이 루프를 구동하는 네 가지 기둥이며, 이는 에이전트 개발을 가능하게 합니다.
배포하는 에이전트 수가 늘어날수록 생성되는 트레이스 수도 증가합니다. 그 결과, 사용자는 트레이스를 분류하고 자신의 에이전트가 어디서 잘못되었는지 파악하는 데 점점 더 많은 시간을 소비하게 됩니다.
기본적인 도구 오류(tool errors)는 비교적 쉽게 포착할 수 있습니다. 전체 궤적(trajectories) 역시 트레이스 보기에서 확인할 수 있습니다. 하지만 에이전트 문제 중 상당수는 각 트레이스를 세밀한 수준으로 검사하지 않으면 감지하기가 훨씬 어렵습니다:
- 에이전트가 동일한 도구 호출을 반복하는 경우
- 잘못된 도구 인수를 사용하는 경우
- 비효율적으로 실행되는 경우
- 사용해야 할 도구를 놓치는 경우
- 여러 실행에 걸쳐 같은 종류의 요청에서 실패하는 경우
LangChain 내부에서 이 문제를 겪은 후, 저희는 LangSmith Engine을 구축하기로 결정했습니다.
Engine은 세 가지 역할을 합니다:
- 트레이스에서 반복되는 실패를 찾습니다.
- 이러한 실패들을 실행 가능한 문제(actionable issues)로 전환합니다.
- 이러한 문제들을 지속적인 개선 사항(durable improvements): 평가자(evaluators), 데이터셋 예시(dataset examples), 그리고 수정사항으로 변환합니다.
Engine 자체도 에이전트입니다. 이는 전문화된 구성 요소들을 사용하여 개선 루프를 처음부터 끝까지 실행하는 오케스트레이터 역할을 합니다. 트레이스를 가져오고, 레포지토리가 연결되면 코드를 읽으며, 실패들을 문제로 그룹화하고, 평가자와 데이터셋 예시를 제안하며, 시간이 지남에 따라 사용자의 에이전트에 대한 이해도를 업데이트합니다.

Engine이 생성하는 것: 문제점(issues)
근본적으로 Engine은 문제점을 식별합니다.
Engine이 생성하는 것: 문제점(issues)
근본적으로 Engine은 문제점을 식별합니다.
문제점(issue)이란 증거 트레이스(evidence traces)를 기반으로 하며, 제안된 후속 조치(proposed follow-up actions)가 포함된 반복적인 실패 패턴입니다. 발견된 문제점들은 Issue Board에 사용자에게 제시됩니다. Issue Board는 Engine이 추적 프로젝트에서 찾아낸 문제점들의 목록입니다.
문제점은 다음 요소들로 구성됩니다:
이름(Name): 문제점의 제목
설명(Description): 문제점에 대한 단락 설명
카테고리(Category): 미리 정의된 에이전트 실패 카테고리 중 하나
심각도(Severity): 낮음(low), 중간(medium), 또는 높음(high)
트레이스(Traces): 문제점이 발생하는 위치에 대한 증거를 제공하는 관련 트레이스
제안된 조치(Proposed actions): 문제가 재발하는 것을 방지하기 위한 제안된 다음 단계
태그(Tags): needs_fix와 같이 후속 워크플로우를 구동하는 데 사용되는 메타데이터
제안된 조치에는 다음이 포함될 수 있습니다:
제안된 온라인 평가기(Proposed online evaluator): 다시 발생할 경우 문제점을 플래그 지정할 평가기
제안된 데이터셋 예시(Proposed dataset examples): 문제점을 대표하는 오프라인 데이터셋에 추가될 항목
제안된 수정 사항(Proposed fix): 근본적인 문제를 해결하기 위한 코드 또는 프롬프트 변경 사항들
중요한 점은 Engine이 단순히 나쁜 트레이스를 지적하는 것이 아니라는 것입니다. Engine은 프로덕션 실패를 팀이 실행하고 미래에 테스트할 수 있는 무언가로 전환하려고 노력합니다.
Engine이 소비하는 것
Engine은 네 가지 주요 입력(input)을 받거나 가져올 수 있습니다.
지침(Instructions)
Engine은 에이전트 개요(Agent Overview)에 의해 안내됩니다. 이는 AGENTS.md 파일과 유사합니다. 이 파일은 에이전트가 무엇을 하는지, 어떤 트레이스 구조를 예상해야 하는지, 어떤 실패 모드를 주시해야 하는지, 그리고 팀이 표현한 선호 사항들이 담긴 살아있는 설명서입니다.
첫 번째 실행(run)은 온보딩 답변과 프로젝트 컨텍스트에서 부트스트랩됩니다. 이 초기 실행 동안 Engine은 트레이스를 분석하고 학습한 것을 사용하여 에이전트 개요의 첫 버전을 만듭니다. 이후 실행에서는 에이전트 개요가 영구적인 입력값(persistent input)이 되어 Engine이 읽고 업데이트합니다.
또한, 언제든지 수동으로 에이전트 개요를 편집할 수도 있습니다.
트레이스(Traces)
Engine은 LangSmith CLI를 통해 관련 LangSmith 트레이싱 프로젝트에서 트레이스를 가져옵니다.
전체 트레이스(full trace)에는 에이전트 실행의 메시지와 궤적(trajectory)이 포함됩니다. 규모가 클 경우, Engine은 모든 트레이스의 전체 내용을 로드하는 것으로 시작하지 않습니다. 대신 압축된 궤적 요약(compact trajectory summaries)으로 시작한 다음, 트레이스에 더 깊은 조사가 필요할 때 선택적으로 전체 트레이스 내용을 로드합니다.
기존 이슈(Existing issues)
Engine은 열려 있는 이슈와 이전에 닫힌 이슈를 포함하여 현재의 이슈 보드(Issue Board)를 가져옵니다.
이를 통해 Engine은 프로젝트의 현재 상태를 파악할 수 있습니다. 알려진 이슈의 중복을 방지하고, 기존 이슈에 증거(evidence)를 추가하며, 이미 해결되거나 닫힌 것이 무엇인지 이해할 수 있습니다.
코드베이스 (Codebase), 선택 사항
Engine을 코드베이스와 연결하는 것은 선택 사항입니다. 이를 통해 Engine은 이슈를 더 정확하게 진단할 수 있으며, 별도의 수정 에이전트(fix agent)가 변경 사항을 제안하도록 할 수 있습니다.
저장소(repository)가 연결되면, 해당 저장소가 샌드박스(sandbox)에 설치됩니다. 설정하는 동안 Engine이 사용할 브랜치 또는 하위 디렉터리를 지정할 수 있습니다.
Engine의 업데이트 내용
Engine은 실행되는 동안 여러 출력을 업데이트할 수 있습니다.
이슈 보드 (Issue Board)
Engine의 주요 역할은 이슈 보드를 업데이트하는 것입니다. 새로운 이슈를 생성하고, 기존 이슈를 업데이트하며, 증거 트레이스를 첨부하고, 이슈 메타데이터(metadata)를 변경할 수 있습니다.
각 이슈에 대해 Engine은 미래 트레이스에서 동일한 패턴을 포착하는 평가자(evaluator)를 제안할 수 있습니다. 또한 증거 트레이스로부터 회귀 예제(regression examples)를 제안하여, 프로덕션 환경에서 관찰된 실패가 오프라인 테스트 커버리지(test coverage)가 되도록 할 수 있습니다. 나아가 근본적인 문제를 해결하기 위한 프롬프트나 코드 변경 사항도 제안할 수 있습니다.
에이전트 개요 (Agent Overview)
Engine은 자신이 발견한 내용을 기록하고 향후 실행을 위해 에이전트 개요를 업데이트할 수 있습니다.
이것이 Engine이 시간이 지남에 따라 프로젝트별 정보를 기억하는 방식입니다: 일반적인 실패 모드, 트레이스 패턴, 도구 동작(tool behavior), 사용자 선호도 등.
높은 수준의 아키텍처 (High-level architecture)
Engine은 Deep Agents를 기반으로 구축되었으며, 파일 작성, 트레이스 검사, 코드 실행 및 체크아웃된 저장소 작업이 가능한 샌드박스에 연결됩니다.

높은 수준에서 Engine은 다음 요소들에 의해 구동됩니다:
시스템 프롬프트 및 지침(System prompt and instructions): 에이전트 개요(Agent Overview) 포함
샌드박스(Sandbox): Engine이 작동하는 환경
LangSmith CLI: Engine이 데이터를 가져오고 LangSmith에 업데이트를 푸시하는 데 사용하는 주요 인터페이스
커스텀 툴(Custom tools): 특히 평가자 테스트 및 회귀 예제 제안을 위한 툴
서브 에이전트(Subagents): 메인 에이전트 컨텍스트가 넘치지 않도록 트레이스를 선별하고 발생 가능한 문제를 조사하는 데 사용됨
메모리(Memory): 에이전트 개요를 통해 유지되며 사용자 행동에 기반하여 업데이트됨
나머지 내용은 핵심 루프를 설명합니다:
- 에이전트의 컨텍스트 준비.
- 대규모로 트레이스 선별하기.
- 발생 가능한 문제 조사하기.
- 이슈, 평가자(evaluators), 데이터셋 예제 생성하기.
- 필요할 때 수정 사항을 별도의 에이전트에 전달하기.
- 다음 실행을 위해 메모리 업데이트하기.
1. 에이전트 컨텍스트 준비하기
Engine이 트레이스를 분석하려면 작동할 환경과 검사하는 에이전트를 이해하기에 충분한 컨텍스트가 필요합니다.
샌드박스 설정
Engine은 샌드박스에 연결되어 실행됩니다. 여기서는 LangSmith Sandboxes를 사용합니다.
Engine을 실행하기 전에 에이전트의 환경을 설정합니다. 먼저 기본 Engine Docker 이미지를 가져옵니다. 이 이미지에는 필요한 라이브러리와 LangSmith CLI가 포함되어 있으며, Engine은 이를 사용하여 LangSmith 데이터와 상호 작용합니다.
만약 Engine이 GitHub 저장소에 연결되어 있다면, 관련 코드 아티팩트도 함께 가져옵니다. 사용자는 설정 과정에서 사용할 브랜치나 하위 디렉토리를 지정할 수 있습니다.
샌드박스가 중요한 이유는 Engine이 종종 트레이스 데이터를 검사하고, 중간 파일을 작성하며, 평가자 코드를 테스트하고, 제안된 출력을 반복적으로 개선해야 하기 때문입니다. 에이전트에게 통제된 작업 환경을 제공하면 이러한 워크플로우가 훨씬 더 안정적이 됩니다.
에이전트 개요(Agent Overview)
에이전트 개요는 지침 파일인 동시에 메모리 계층입니다.
Engine을 설정할 때, 기본 일련의 온보딩 질문에 답변합니다. Engine은 이러한 답변과 첫 실행 중에 발견한 내용을 종합하여 초기 에이전트 개요를 생성합니다.
개요는 Engine이 다음 사항들을 지속적으로 기록하는 데 도움을 줍니다:
Engine은 다음 사항들을 지속적으로 기록하는 데 도움을 줍니다:
- 에이전트가 무엇을 하는지 (what your agent does)
- 예상되는 트레이스 구조 (what trace structures to expect)
- 주의할 일반적인 함정 (common pitfalls to watch for)
- 프로젝트별 컨텍스트 (project-specific context)
- 사용자 선호도 (user preferences)
Engine은 연속 실행(consecutive runs)마다 이 파일을 읽고 업데이트합니다.
LangSmith CLI
Engine이 LangSmith와 상호작용하는 주요 방법은 LangSmith CLI를 이용하는 것입니다.
저희는 대부분의 경우, 모든 LangSmith 작업에 대해 사용자 지정 도구(custom tool)를 생성하는 것보다 이것을 선호합니다. CLI는 Engine에게 트레이스를 가져오고(pulling traces), 이슈를 쿼리하고(querying issues), 이슈를 생성하며(creating issues), 트레이스를 첨부하고(attaching traces), 이슈 메타데이터를 업데이트하며(updating issue metadata), 아티팩트를 제안하는(proposing artifacts) 일반적인 목적의 인터페이스를 제공합니다.
또한, 이는 Engine을 디버깅하고 재현하기 쉽게 만듭니다. CLI는 다운로드가 가능하고 코딩 에이전트에게 로컬에서 제공될 수 있는 동일한 인터페이스입니다. Engine이 CLI를 통해 어떤 작업을 수행하든, 일반적으로 그 작업을 Engine 외부에서도 이해하고 재현하는 것이 가능합니다.
2. 대규모 트레이스 스크리닝 (Screening traces at scale)
Engine을 구축할 때 가장 큰 아키텍처 과제는 트레이스 볼륨이었습니다.
에이전트가 한 번에 50개의 트레이스를 조사하고 분류하도록 하는 것은 비교적 쉬웠습니다. 하지만 시스템을 프로덕션 에이전트에 연결하자, 그 규모에서 작동했던 기술들이 무너지기 시작했습니다. 프로덕션 프로젝트는 조회 기간(lookback window) 동안 수천 개 또는 수만 개의 트레이스를 가질 수 있습니다.
모든 전체 트레이스 내용을 메인 에이전트의 컨텍스트에 로드하는 것은 실행 가능하지 않습니다. 장시간 실행되는 에이전트의 트레이스 10개만 해도 수백 개의 도구 호출(tool calls)과 메시지를 포함할 수 있습니다.
그래서 저희는 이 문제를 두 단계로 분리했습니다:
- 의심스러운 트레이스를 빠르게 식별하는 광범위한 스크리닝 단계 (A broad screening phase that quickly identifies suspicious traces).
- 중요할 가능성이 있는 트레이스에 대해서만 전체 컨텍스트를 로드하는 더 깊은 조사 단계 (A deeper investigation phase that only loads full context for traces that are likely to matter).

궤적 형식 (Trajectory format)
스크리닝을 가능하게 하려면, 각 트레이스의 압축된 표현이 필요했습니다.
질문은 다음과 같았습니다:
트레이스에 있는 정보를 어떻게 압축하면서도, 그 안으로 다시 탐색하는 데 필요한 정보는 유지할 수 있을까요?
답변은 에이전트 궤적(agent trajectories)이었습니다. 이는 트레이스의 간결한 골격입니다.

궤적(trajectory)은 턴(turn)마다 하나의 항목을 가지며, 역할(role), 선택적 도구 이름(optional tool name), 지연 시간(latency), 콘텐츠 크기(content size)를 포함합니다. 전체 내용은 포함하지 않습니다.
{ role: "human", chars: 142 }
{ role: "ai", latency_ms: 1820, chars: 89 }
{ role: "tool", tool_name: "search_db", latency_ms: 340, chars: 2100 }
{ role: "tool", tool_name: "search_db", latency_ms: 312, chars: 1980 }
{ role: "tool", tool_name: "search_db", latency_ms: 298, chars: 2040 }
{ role: "ai", latency_ms: 2100, chars: 210 }
궤적은 탐색 도구(navigation tool) 역할을 합니다. 이를 통해 스크리너는 의심스러운 패턴을 빠르게 포착할 수 있으며, 이후 전체 트레이스(full trace)를 검색하여 필요한 정보만 컨텍스트에 로드합니다.
피드백을 통한 트레이스 우선순위 지정
트레이스에는 이미 피드백이 연결되어 있을 수 있습니다. 이는 인간의 주석(human annotations), LLM-as-a-judge 점수, 또는 최종 사용자 피드백(좋아요/싫어요)에서 비롯될 수 있습니다.
Engine은 트레이스에 대한 피드백을 잠재적인 문제가 존재할 수 있다는 고우선순위 신호로 사용합니다.
Engine이 가져오는 초기 트레이스 세트에는 피드백 통계가 포함됩니다. Engine은 피드백이 있는 트레이스를 찾아 분류(triage)를 위해 우선순위를 높이도록 지시받습니다.
피드백 자체가 자동으로 문제가 되는 것은 아닙니다. 이는 스크리닝 및 조사에 대한 우선순위를 높일 뿐입니다. 에이전트는 여전히 해당 트레이스가 실제 문제의 일부인지 판단해야 합니다.
스크리너 서브에이전트
핵심 스크리닝 질문은 다음과 같습니다:
이 트레이스를 기반으로, 추가 조사가 필요한 문제가 있습니까?
Engine은 이를 위해 전용 스크리너 서브에이전트를 사용합니다. 이 스크리너는 Haiku 기반의 서브에이전트로, 메인 에이전트가 약 20개의 트레이스 그룹에 걸쳐 배포(dispatch)합니다.
스크리너의 임무는 의도적으로 범위가 좁습니다. 이는 문제를 생성하지 않으며, 근본 원인을 진단하지 않습니다. 단지 표면적인 수준에서 해당 트레이스가 깨끗한지 아니면 문제가 포함되어 있을 가능성이 있는지만 결정합니다.
스크리너는 메인 에이전트에게 구조화된 응답을 반환합니다. 이 응답에는 플래그가 지정된(flagged) 각 트레이스에 대해 트레이스 ID, 카테고리, 그리고 간략한 이유가 한 줄씩 포함되며, 그 뒤에 깨끗한 트레이스의 개수가 이어집니다.
<trace_id> | <category> | <간략한 이유>
CLEAN: 47
이 단계는 탐색 공간을 줄입니다. 메인 에이전트가 모든 트레이스를 완전히 추론하도록 요청하는 대신, 우리는 병렬 스크리너(parallel screeners)를 사용하여 더 깊은 주의가 필요한 트레이스를 식별합니다.
3. 발생 가능성이 높은 문제 조사하기
AI 자동 생성 콘텐츠
본 콘텐츠는 LangChain Blog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기