본문으로 건너뛰기

© 2026 Molayo

LangChain헤드라인2026. 05. 21. 03:46

기술(Skills) 평가하기

요약

LangChain은 코딩 에이전트의 성능을 높이기 위해 동적으로 로드되는 '기술(Skills)'을 구축하고 있으며, 이를 효과적으로 검증하기 위한 평가 방법론을 제시합니다. 기술은 에이전트가 필요할 때만 호출되는 프롬프트와 리소스의 집합으로, 에이전트의 성능 저하를 방지하면서 전문성을 높이는 역할을 합니다. 안정적인 평가를 위해서는 Docker와 같은 샌드박스 환경을 통해 테스트의 재현성을 확보하는 것이 필수적입니다.

핵심 포인트

  • 기술(Skills)은 에이전트가 필요할 때만 동적으로 로드되어 성능 저하를 방지하는 큐레이션된 지침 및 리소스임
  • 기술 평가를 위해서는 기술 적용 전후의 에이전트 성능을 비교하는 반복적인 파이프라인이 필요함
  • 테스트의 재현성을 극대화하기 위해 Docker와 같은 깨끗하고 일관된 샌드박스 환경 설정이 중요함
  • 기술은 LLM 프롬프트와 유사하게 에이전트의 행동에 영향을 미치므로 지속적인 테스트와 개선이 요구됨

Robert Xu 작성

최근 LangChain에서는 Codex, Claude Code, Deep Agents CLI와 같은 코딩 에이전트(coding agents)가 우리의 생태계, 즉 LangChain 및 LangSmith와 함께 작동할 수 있도록 돕는 기술(skills)을 구축해 왔습니다. 이는 우리만의 독자적인 노력은 아닙니다. 거의 모든 기업이 코딩 에이전트에게 부여할 기술을 어떻게 만들지 탐색하고 있습니다. 이러한 기술을 구축하는 핵심적인 부분은 그것들이 실제로 제대로 작동하는지 확인하는 것입니다. 이 블로그에서는 기술을 생성할 때 이를 어떻게 평가할지에 대한 몇 가지 학습 내용과 모범 사례(best practices)를 다룹니다.

기술(Skills)이란 무엇인가?

기술(Skills)은 전문화된 도메인에서 에이전트의 성능을 향상시키는 큐레이션된 지침(instructions), 스크립트(scripts) 및 리소스(resources)입니다. 중요한 점은, 기술은 점진적 공개(progressive disclosure)를 통해 동적으로 로드된다는 것입니다. 즉, 에이전트는 현재 수행 중인 작업과 관련이 있을 때만 기술을 검색합니다. 이는 에이전트가 성능을 확장하는 데 도움을 줍니다. 역사적으로 에이전트에게 너무 많은 도구(tools)를 제공하면 성능이 저하되는 현상이 발생하곤 했습니다.

실제로 기술은 에이전트가 필요할 때 동적으로 로드되는 프롬프트(prompts)라고 생각할 수 있습니다. 다른 프롬프트와 마찬가지로, 기술은 예상치 못한 방식으로 에이전트의 행동에 영향을 미칠 수 있습니다. 결과적으로, LLM 프롬프트를 테스트하는 것과 마찬가지로 기술도 테스트가 필요합니다. 어떤 기술이 코딩 에이전트의 성능을 향상시킬까요? 어떤 콘텐츠의 변경이 가장 많은 개선을 가져왔을까요?

기본적인 평가 파이프라인(Evaluation Pipeline)

기술을 테스트하기 위한 우리의 기본적인 접근 방식은 다음과 같습니다:

  • Claude Code가 성공적으로 완료하기를 원하는 작업(tasks)을 정의합니다.
  • 해당 작업에 도움이 되는 기술(skills)을 정의합니다.
  • 기술 없이 해당 작업에 대해 Claude Code를 실행합니다.
  • 기술을 사용하여 해당 작업에 대해 Claude Code를 실행합니다.
  • 성능을 비교하고 기술을 반복적으로 개선(iterate)합니다.

아래에서는 여러분만의 평가 파이프라인을 구축한 경험을 바탕으로 몇 가지 모범 사례를 공유합니다.

1단계: 깨끗한 테스트 환경 설정하기

기술(Skills)은 Claude Code와 같은 코딩 에이전트(Coding agents)나 Deep Agents와 같은 하네스(Harnesses)와 함께 흔히 사용됩니다. 기술을 테스트한다는 것은 실제로 이러한 강력한 에이전트들이 기술 정보를 효과적으로 사용할 수 있는지를 테스트하는 것입니다. 즉, 에이전트의 성능이 향상되는지를 테스트하는 것이며, 결과적으로 실무에서는 코딩 에이전트 자체를 테스트하는 것이 됩니다.

코딩 에이전트와 하네스는 작동할 수 있는 방대한 액션 스페이스(Action space)를 가집니다. 또한 이들은 시작 조건(Starting conditions)에 민감합니다. 예를 들어, Claude Code는 작업을 시작하기 전에 종종 디렉토리를 탐색하며, 그 과정에서 발견한 내용이 접근 방식(Approach)을 결정합니다. 이는 기술을 테스트할 때, 여러분의 기술을 사용하는 에이전트를 위해 일관되고 깨끗한 환경을 준비하는 것이 매우 중요하다는 것을 의미합니다. 이를 통해 테스트의 재현성(Reproducibility)을 극대화할 수 있습니다.

우리의 테스트에서는 Claude Code를 실행하기 위해 경량화된 Docker 스캐폴드(Scaffold)를 사용했습니다. 다른 대안으로는 Harbor나 여러분이 선택한 샌드박스(Sandbox)가 있습니다.

def run_claclaude_in_docker(

test_dir: Path, prompt: str, timeout: int = 300, model: str = None

) -> subprocess.CompletedProcess:

"""Docker에서 Claude CLI를 실행합니다. CompletedProcess를 반환합니다."""

if not check_docker_available():

raise RuntimeError("Docker not available")

cmd = ["run-claude", str(test_dir), prompt, "--timeout", str(timeout)]

if model:

cmd.extend(["--model", model])

try:

return run_shell("docker.sh", *cmd, timeout=timeout + 30, check=False)

except subprocess.TimeoutExpired:

return subprocess.CompletedProcess(cmd, 124, "", f"Timeout after {timeout}s"

2단계: 작업(Tasks) 정의하기

기술을 통해 코딩 에이전트가 개선되었는지 확인하기 위해 직관(Vibes)에 의존하고 싶은 유혹이 들 수 있지만, 성능은 작업(Tasks)에 따라 달라질 수 있으며 실제로도 달라집니다. 명확하게 정의된 작업은 회귀(Regressions)를 포착할 수 있는 체계적인 벤치마크(Benchmark)를 제공합니다. 작업을 구축하며 우리가 배운 교훈은 다음과 같습니다:

제약 조건이 있는 작업(Constrained Tasks) 생성하기

  • 개방형 출력(Open-ended output)은 채점하기 어렵습니다. 특히 코딩 에이전트(Coding agents)의 경우 더욱 그렇습니다. 만약 우리가 Claude Code에게 연구를 수행하기 위한 LangChain 에이전트를 생성하도록 요청한다면, Claude Code는 다양한 접근 방식을 취할 수 있습니다. Claude Code가 생성한 에이전트의 품질을 채점하는 것은 어렵고, 에이전트 설계에 대해 너무 규정적인(prescriptive) 기준을 적용하면 유효한 연구 결과를 만들어내는 작동 가능한 솔루션에 불이익을 줄 수 있습니다.
  • 우리가 유용하다고 발견한 한 가지 전략은 Claude Code에게 버그가 있는 코드를 수정하도록 하는 것이었습니다. 이는 설계 공간(design space)을 제한하여 정답 여부를 검증하기 더 쉽게 만들었습니다. 즉, 결과물인 에이전트가 미리 정의된 테스트에서 여전히 버그가 있는 동작을 보인다면, Claude의 솔루션을 안전하게 실패로 처리할 수 있었습니다. 또한, Claude가 우리의 기존 방식을 사용하도록 유도(primed)되었기 때문에 설계 검사(design checks)가 덜 취약(brittle)해졌습니다.

명확한 지표와 함께 작업(Tasks)을 쌍으로 구성하기

  • 명확한 지표(metrics)는 당신의 기술(skill)이 코딩 에이전트를 개선하는지 정량화하는 데 매우 중요합니다. 우리가 추적한 몇 가지 지표는 다음과 같습니다:

  • 기술이 호출되었는가? 반대로, 관련이 없을 때 기술이 호출되지 않았는가?

  • 에이전트가 작업을 완수했는가? 하나의 작업은 여러 가지 다른 단계(steps)를 포함할 수 있으며, 완료된 단계의 수를 추적하는 것은 '완전한 실패'와 '거의 성공함'을 구분하는 데 도움이 되었습니다.

  • Claude Code가 작업을 완료하는 데 몇 번의 턴(turns)을 소모했는가? Claude Code가 기술 없이도 작업을 완료할 수 있더라도, 기술을 포함하는 것이 효율성을 향상시킬 수 있습니다.

  • Claude Code가 작업을 완료하는 데 실제 시간(real time)이 얼마나 걸렸는가? 효율성을 측정할 때 모든 턴이 동일한 가치를 갖는 것은 아닙니다.

  • 우리는 이러한 지표들과 각 실행 시 지표가 어떻게 변하는지를 LangSmith 평가(evaluations)를 통해 추적했습니다. 이를 통해 실험 결과를 이해하기 위한 단일 창(single pane of glass)을 확보할 수 있었습니다.

난이도에 과도하게 집중하지 마세요

  • 기술(Skill)을 평가할 때는 코딩 에이전트(coding agent)나 하네스(harness)를 통해 수행하게 됩니다. 코딩 에이전트는 이미 매우 뛰어난 문제 해결사입니다. 만약 작업을 너무 적대적이거나(adversarial) 복잡하게(convoluted) 만든다면, 여러분의 기술이 아닌 코딩 에이전트의 문제 해결 능력을 테스트하게 될 위험이 있습니다.
  • 코딩 에이전트에서 실제로 관찰된 실패 사례를 기반으로 작업을 구성하는 것이 유용합니다. 휴리스틱(heuristic)으로서, 실패를 유도하는 가장 직관적인 테스트 케이스를 만드는 것을 목표로 해야 합니다. 예를 들어, 저희는 Claude Code가 LangSmith에 평가기(evaluator)를 효과적으로 업로드하는 데 어려움을 겪는 것을 발견했습니다. 저희의 테스트 케이스는 Claude에게 "이 데이터셋을 사용하여 궤적 평가기(trajectory evaluator)를 생성하고 이를 LangSmith에 업로드하세요"라고 요청했습니다.

예시 작업 (Example Task)

저희의 내부 테스트에서는 기본적인 LangChain 및 LangSmith 작업에 대해 Claude를 평가했습니다. 예시 작업은 다음과 같은 모습일 수 있습니다:

// 작업 (TASK)

우리 LangSmith 프로젝트의 가장 최근 트레이스(trace) 5개로부터 5개의 예시를 포함하는 궤적 데이터셋(trajectory dataset)을 생성하고, 도구 호출 일치율(tool call match percentage)을 측정하는 평가기를 추가하세요.

출력: trajectory_dataset.json 및 trajectory_evaluator.py

(둘 다 "bench-{run_id}"로 LangSmith에 업로드)

작성한 모든 코드를 직접 실행하세요.

이 과정의 일부로, 저희는 에이전트가 trajectory_dataset.json을 생성할 것으로 기대합니다. 저희는 아래와 같은 지표(metric)를 사용하여 출력을 점수화할 수 있습니다:

# 샘플 지표, Claude가 생성한 데이터셋을 확인합니다

def check_accuracy(runner: TestRunner):

"""궤적이 정답(ground truth)과 일치하는지 확인합니다.""" # Claude의 출력이 정답과 일치했는가

dataset_file = runner.artifacts[0] # Claude의 출력: trajectory_dataset.json

test_dir = Path(".")

p, f = check_trajectory_accuracy(
test_dir=test_dir,
outputs=runner.context,
filename=dataset_file,
expected_filename="expected_dataset.json", # 정답(Ground Truth), expected_dataset.json
data_dir=test_dir / "data", # 작업 내 정답을 저장하는 폴더
)

for msg in p:
runner.passed(msg)

for msg in f:
runner.failed(msg)

저희가 최종적으로 작성한 모든 테스트를 확인하려면, 여기에서 저희의 벤치마킹 리포지토리(benchmarking repo)를 참조하세요.

3단계: 기술(Skills) 정의하기

기술(Skills)을 생성하고 반복(iteration)할 때 가장 주요하게 고려해야 할 사항은 어떤 콘텐츠를 포함할 것인지, 그리고 그 콘텐츠를 어디에 배치할 것인지입니다. 기술(Skills)은 종종 항상 컨텍스트(context)에 로드되는 AGENTS.md 또는 CLAUDE.md 파일과 함께 제공됩니다. 답변해야 할 몇 가지 질문은 다음과 같습니다:

  • 콘텐츠를 AGENTS.md(사전 로드됨)에 넣어야 할까요, 아니면 기술(skill)에 넣어야 할까요?
  • 콘텐츠를 하나의 커다란 기술(skill)로 구성해야 할까요, 아니면 여러 개의 더 작은 기술(skill)로 나누어야 할까요?
  • 성능 차이(performance deltas)에 영향을 주지 않고 콘텐츠를 제거할 수 있습니까?

저희가 따랐던 유용한 가이드라인은 다음과 같습니다:

기술(Skills)을 모듈화하기

  • 저희는 기술(skill) 콘텐츠의 서로 다른 섹션을 구분하기 위해 XML 태그를 사용합니다. 이는 에이전트(agent)에게 구조를 제공할 뿐만 아니라, 기술(skills)을 A/B 테스트하기 위해 섹션을 교체하거나 제거할 수 있는 편리한 방법을 제공합니다.
  • 일반적으로 규모가 큰 기술(skills, 300-500행)의 경우, 작은 서식이나 문구 변경은 영향이 제한적이라는 것을 발견했습니다. 예를 들어, 긍정적 지침(“이것을 하세요”) 대 부정적 지침(“이것을 하지 마세요”), 그리고 마크다운(markdown) 대 XML 태그는 기록된 작업에서 유사한 성능을 보였습니다.
  • 반복(iteration)할 때, 저희는 더 세밀한 수준에서 최적화하기보다는 테스트를 위해 하나 이상의 섹션에 변경을 가하는 방식을 주로 사용합니다.

AGENTS.md 및 CLAUDE.md 활용하기

  • 실제로 기술(skills)이 항상 안정적으로 호출되는 것은 아닙니다. LangChain 에이전트(agent)를 생성하는 한 작업에서, Claude Code는 “langchain agents” 기술(skill)을 전혀 호출하지 않았습니다. 기술(skills)을 호출하도록 프롬프트(prompt)를 포함하더라도 호출률은 70%까지만 올라갔습니다.
  • AGENTS.md와 CLAUDE.md는 컨텍스트(context)에 안정적으로 로드되기 때문에, Claude에게 기술(skills)을 어떻게 그리고 언제 사용할지 알려주기에 좋은 장소입니다. 이를 통해 저희는 일관된 기술(skill) 호출을 달성할 수 있었습니다.
  • AGENTS.md와 CLAUDE.md는 여러 기술(skills)을 함께 사용하는 방법에 대한 지침을 포함하기에 좋은 장소입니다. LangSmith 기술(skills)을 사용하는 작업에서 더 적은 턴(turns)으로 더 일관된 통과율(pass rates)을 확인했습니다.

기술(Skills) 간의 콘텐츠 균형 맞추기

  • 기술(Skill)의 이름과 설명은 Claude Code가 어떤 기술을 호출할지 결정하는 데 매우 중요합니다. 약 20개의 유사한 LangGraph 기술을 사용하여 테스트했을 때, Claude Code는 때때로 잘못된 기술을 호출했습니다. 기술을 12개로 줄였을 때, Claude는 일관되게 올바른 기술을 호출했습니다.
  • 적은 수의 기술로 기술 콘텐츠를 통합하면 콘텐츠가 컨텍스트(context)에 더 일관되게 포함된다는 것을 의미합니다. 하지만 이는 또한 Claude Code가 한 번에 더 큰 덩어리(chunks)를 로드하게 되어, 잠재적으로 필요하지 않은 콘텐츠까지 보게 된다는 것을 의미하기도 합니다. 적절한 균형을 찾는 데는 테스트가 필요합니다!

4단계: 실행 및 성능 비교

기술을 테스트하기 위해, 우리는 다양한 기술 조합을 사용하여 작업(tasks)에 Claude Code를 실행했습니다. 일부 테스트 케이스는 다음과 같습니다:

  • 기술 없이 Claude Code를 실행한 대조군(Control case)
  • 작업에 모든 기술을 사용하여 Claude Code를 실행
  • 기술을 몇 개의 큰 기술로 통합하여 Claude Code를 실행
  • 기술을 더 작은 기술들로 분할하여 Claude Code를 실행

우리는 LangSmith의 pytest 통합 기능을 사용하여 각 시나리오별 작업 완료율(completion rate)을 비교했습니다. 기술을 포함하는 것은 거의 항상 유익했으며, 콘텐츠를 어떻게 분할하느냐에 따라 서로 다른 작업에서 더 나은 성능을 보였습니다. 전반적으로 기술을 갖춘 Claude Code는 82%의 확률로 작업을 완료했지만, 기술이 없을 경우 성능은 9%로 떨어졌습니다. 그러나 단순히 작업 완료율을 비교하는 것 이상으로, 우리는 기술을 반복 개선(iterate)할 수 있도록 Claude가 실패했는지 이해해야 했습니다.

Docker 내에서 Claude Code가 무엇을 하고 있는지, 그리고 왜 그렇게 하는지 이해하는 것은 쉽지 않은 일이었습니다. 즉, Claude Code의 궤적(trajectory)에 대한 관측 가능성(observability)이 필요했습니다. 테스트 과정에서 우리는 Claude Code가 취하는 모든 동작을 캡처하기 위해 LangSmith와 통합했습니다. 이를 통해 Claude가 어떤 파일을 읽었는지, 어떤 스크립트를 생성했는지, 그리고 어떤 기술을 호출했는지(또는 호출하지 않았는지)를 이해할 수 있었습니다.

결정적으로, 우리는 Claude Code가 자체적인 트레이싱 기술 (tracing skill)을 사용하여 트레이스 (traces)를 조사하고 발생한 일을 요약하도록 했습니다. 이를 통해 기술 (skill) 콘텐츠를 반복 개선하는 속도가 훨씬 빨라졌습니다. Claude Code는 트레이스를 LangSmith로 전송하고, 해당 트레이스를 가져와서 사람이 검토할 수 있도록 문제를 요약했습니다. 그러면 사람은 수정 사항을 제안하고, 테스트를 다시 실행하며, LangSmith의 실험 포털 (experiment portal)에서 성능이 어떻게 변했는지 확인할 수 있었습니다.

자신만의 기술 평가 파이프라인 (skill evaluation pipeline)을 구축할 때, 좋은 관찰 가능성 (observability)과 좋은 평가 (evaluation)를 갖추는 것은 매우 중요합니다. 특히 Claude Code와 같은 에이전트 (agents)들은 매우 강력하기 때문입니다.

결론

기술 (Skills)은 Claude Code, Codex 또는 Deep Agents CLI를 포함한 코딩 에이전트 (coding agents)의 능력을 향상시키는 유용한 방법입니다. LLM 및 에이전트와 관련된 다른 구성 요소들과 마찬가지로, 기술 (skills) 또한 유용하게 사용되기 위해서는 반드시 평가되어야 합니다.

이 모든 과정이 실제로 작동하는 모습을 보려면, 여기에서 우리의 벤치마킹 리포지토리 (benchmarking repo)를 확인하세요.

우리는 이러한 학습 내용이 여러분이 자신만의 기술을 구축할 때 좋은 평가 휴리스틱 (evaluation heuristics)을 제공하기를 바랍니다. 기술 평가를 시작하려는 분들은 LangSmith의 평가 플랫폼 (evaluation platform)을 확인해 보세요!

AI 자동 생성 콘텐츠

본 콘텐츠는 LangChain Blog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0