Harbor 통합

Harbor 통합

LangSmith에서 Harbor로 평가(evals), Deep Agents, 샌드박스를 실행해요.

LangSmith를 사용해 한 곳에서 에이전트 평가를 실행하고, 트레이싱하고, 비교하며, 비용을 관리할 수 있어요. 실행 계층으로는 Harbor를 사용해요. Harbor는 Terminal-Bench의 제작자가 만든, 샌드박스 환경에서 에이전트와 언어 모델을 평가·최적화하기 위한 프레임워크예요. 각 시도를 격리된 컨테이너에서 실행하므로, 평가와 롤아웃을 여러 환경에서 한 번에 병렬화할 수 있어요.

LangSmith는 세 지점에서 Harbor와 통합돼요:

  • LangSmith 평가: --plugin langsmith로 모든 Harbor 작업을 실험으로 LangSmith에 기록해요.
  • Deep Agents: --agent langgraph로 LangGraph 또는 Deep Agents 애플리케이션을 Harbor 에이전트로 실행해요.
  • 샌드박스: --env langsmith로 각 Harbor 시도를 LangSmith 샌드박스에서 실행해요.

이 페이지는 LangSmith 전용 Harbor 플래그를 다룹니다. 전체 CLI는 harbor run --help를 실행하거나 Harbor 문서를 참조하세요.

출처: 문서

본문

사전 요구사항

  • LangSmith 계정API 키.
  • pip가 있는 Python 3.12 이상.
  • 에이전트가 호출하는 모델용 프로바이더 API 키(예: ANTHROPIC_API_KEY).

설치

langsmith extra로 Harbor를 설치해요. 이 extra에는 LangSmith 플러그인, 환경, 에이전트가 사용하는 harbor-langsmith 패키지가 포함돼요:

pip install "harbor[langsmith]"

인증

Harbor는 LangSmith 자격 증명으로 인증해요. API 키와 해당 키가 속한 엔드포인트를 설정해요:

export LANGSMITH_API_KEY="<LANGSMITH_API_KEY>"
export LANGSMITH_ENDPOINT="<LANGSMITH_ENDPOINT>"

LANGSMITH_ENDPOINT는 기본적으로 https://api.smith.langchain.com(GCP US)이에요. BYOC에서는 데이터 플레인 URL로, 셀프 호스팅에서는 인스턴스 URL로, 다른 Cloud 리전에서는 해당 리전의 API URL로 설정하세요.

또는 키를 내보내는 대신 LangSmith SDK 프로필을 선택할 수 있어요:

export LANGSMITH_PROFILE=prod

빠른 시작

Harbor 작업을 실험으로 LangSmith에 기록해요:

harbor run -d "[email protected]" \
  --agent <agent> \
  --model <provider:model> \
  --plugin langsmith

<agent>를 Harbor 에이전트로, <provider:model>을 설치된 langchain-* 프로바이더가 해석할 수 있는 provider:model 형식의 모델(예: anthropic:claude-opus-4-8)로 바꿔요. 사용 가능한 에이전트를 나열하려면 harbor run --help를 실행하거나, 완전한 langgraph 실행을 보려면 Deep Agents를 참조하세요.

Datasets & Experiments를 열고 Harbor가 동기화한 데이터셋(예: [email protected])을 선택한 다음 Experiments 탭을 열어 런을 확인하세요.

LangSmith 평가

LangSmith 플러그인은 모든 Harbor 작업을 LangSmith에 기록하므로, Datasets & Experiments 아래에서 결과를 보고 비교할 수 있어요. 플러그인은 Deep Agents뿐 아니라 모든 Harbor 에이전트에서 작동해요. --plugin langsmith로 활성화해요. 빠른 시작은 기본 호출을 보여주고, 이 섹션은 플러그인이 기록하는 내용과 구성 방법을 다룹니다.

실험과 함께 전체 에이전트 트레이스를 캡처하려면 LangSmith로 트레이싱하는 에이전트를 선택하세요. 에이전트가 LangSmith로 트레이싱하지 않으면, 플러그인은 에이전트 트레이스 없이도 데이터셋과 결과·피드백이 있는 실험을 계속 생성해요.

구분이 필요할 때는 짧은 플러그인 이름 대신 전체 import 경로를 전달하세요:

harbor run ... --plugin harbor_langsmith:LangSmithPlugin

플러그인은 LANGSMITH_API_KEY가 필요해요.

플러그인이 기록하는 내용

작업이 실행되면 플러그인은 API를 통해 LangSmith에 다음을 기록해요:

  • 데이터셋: 작업에서 참조 데이터셋을 동기화해요. 기본 이름은 데이터셋 또는 작업에서 비롯되며, 예를 들어 [email protected]이에요. 각 작업은 입력이 작업 이름, 지시문, 작업 ID인 예제가 돼요.
  • 실험: 작업당 하나의 실험을 만들며, 이름은 <name>-<job-id-prefix>이고 참조 데이터셋에 연결돼요.
  • : 시도당 루트 런을 만들고 입력에 작업 이름, 지시문, 에이전트, 모델을 넣으며, 환경·에이전트·검증 단계에 대한 하위 런도 만들어요.
  • 피드백: 검증기 보상 키(예: reward)당 하나의 피드백 점수를 첨부하고, 시도가 예외를 발생시키면 harbor_error 피드백을 첨부해요.
  • 출력: 각 시도 런에 대해 tokens 아래의 토큰 수(input, cache, output)와 cost_usd 아래의 런 비용을 기록해요.

LangSmith에서 결과 보기

LangSmith의 Datasets & Experiments를 열고 플러그인이 동기화한 데이터셋(예: [email protected])을 선택한 다음 Experiments 탭을 열어요. 각 Harbor 작업은 실험으로 나타나며, rewardharbor_error 피드백, 각 런에 기록된 토큰 수와 비용, 지연 시간으로 실험을 비교할 수 있어요.

Deep Agents

langgraph 에이전트는 Deep Agent와 같은 LangGraph 애플리케이션을 Harbor 에이전트로 실행해요. --agent langgraph로 선택해요. Harbor는 프로젝트를 샌드박스에 스테이징하고, 종속성을 설치하며, 각 시도에 대해 컨테이너 안에서 그래프를 실행해요.

LangSmith 및 모델 자격 증명을 설정한 다음 Harbor를 실행해요. harbor runharbor job start의 별칭으로, 작업을 빌드하고, 환경을 띄우며, LangGraph 에이전트를 실행해요:

export LANGSMITH_PROFILE=prod
export LANGSMITH_TRACING=true
export LANGSMITH_PROJECT=harbor-deepagents
export FIREWORKS_API_KEY="<FIREWORKS_API_KEY>"

harbor run \
  -t hello-world/hello-world \
  --agent langgraph \
  --model fireworks:accounts/fireworks/models/glm-5p2 \
  --ak project_path=./deep-agent \
  --ak graph=deep_agent

무엇에 대해 평가할지 선택

작업(task)은 고정된 레이아웃을 가진 하나의 디렉토리예요: 구성용 task.toml, 프롬프트용 instruction.md, 샌드박스가 빌드되는 Dockerfile용 environment/, 보상을 기록하는 검증기용 tests/. 데이터셋은 이러한 작업 디렉토리 여러 개예요.

작업 또는 데이터셋은 로컬 또는 원격일 수 있어요: Harbor를 자체 작업 디렉토리 폴더로 지정하거나 Harbor의 레지스트리에서 가져올 수 있어요.

작업이 실행되는 작업을 선택하는 세 가지 입력이 있어요:

  • -t org/name[@ref]: 레지스트리의 단일 작업. 원격 작업은 레지스트리 조회로 가져온 다음, 고정된 커밋에서 ~/.cache/harbor/tasks로 클론돼요.
  • -d name@version: 전체 벤치마크 데이터셋이며, 여러 작업이에요. 각 작업은 레지스트리에서 해석되어 캐시로 클론돼요.
  • -p <dir>: 하나의 작업 또는 여러 작업의 루트 폴더에 대한 로컬 경로. 로컬 경로는 다운로드나 캐시 복사 없이 제자리에서 읽어요.

선택한 작업을 -i-x(글로브 include/exclude)로 필터링하고 -l로 수를 제한해요.

작업 디렉토리는 이 레이아웃을 가져요:

hello-world/
├── task.toml         # timeouts, CPU, and memory
├── instruction.md    # the prompt given to the agent
├── environment/
│   └── Dockerfile    # image the sandbox is built from
├── tests/
│   ├── test.sh       # writes the reward to /logs/verifier/reward.txt
│   └── test_state.py # the assertions
└── solution/         # optional, used only by the oracle agent

데이터셋은 작업 디렉토리들의 디렉토리예요:

terminal-bench/
├── hello-world/      # each subdirectory is a full task
├── fix-bug/          # (task.toml + instruction.md + environment/ + tests/)
└── parse-csv/

에이전트 구성

--ak로 에이전트 kwargs를 전달해요:

  • --agent langgraph: LangGraph 에이전트 선택.
  • --model <provider:model>: 실행할 모델. 기본값이 없으므로 필수예요. 에이전트는 init_chat_model로 해석하므로, 설치된 langchain-* 프로바이더가 provider:model 형식으로 해석할 수 있어야 해요(예: anthropic:claude-opus-4-8). provider/model 값은 provider:model로 정규화돼요. 모델은 configurable['model'] 또는 HARBOR_MODEL 환경 변수에서 비롯되며, 해석할 수 없거나 누락된 값은 ValueError를 발생시켜요.
  • --ak project_path=<dir>: langgraph.json을 포함하는 로컬 디렉토리.
  • --ak graph=<name>: langgraph.json에서 실행할 그래프.
  • --ak config=<file>: project_path 안에서 그래프를 선언하는 구성 파일 이름. 기본값은 langgraph.json.
  • --ak configurable='{...}': LangGraph 런별 구성으로 config["configurable"]로 전달되고 인보크 시점에 그래프가 읽어요. 공통 키는 model, model_kwargs, cwd예요.
  • --ak model_kwargs='{...}': configurable의 중첩 model_kwargs 키의 단축형(예: {"temperature": 0, "max_tokens": 8000}).
  • --ak dependency_overrides='[...]': 에이전트 가상 환경용 Pip 패키지. 이 목록은 langgraph.json에 선언된 종속성을 대체하므로, 프로젝트를 편집하지 않고 버전을 고정하거나 교체할 수 있어요(예: '["deepagents==0.6.10"]').

langgraph.json을 에이전트와 종속성에 연결

에이전트는 project_pathlanggraph.json 파일에서 그래프를 로드해요. 이 파일은 그래프 진입점과 Harbor가 샌드박스 가상 환경에 설치하는 pip 종속성을 선언해요:

{
  "dependencies": [
    "deepagents>=0.6.10,<0.7.0",
    "langchain-anthropic>=1.4.6,<1.5.0",
    "langchain-openai>=1.3.0,<1.4.0"
  ],
  "graphs": {
    "deep_agent": "./agent.py:make_graph",
    "research_agent": "./agent.py:make_research_graph"
  }
}

프로젝트는 --ak graph로 선택되는 두 개의 그래프를 노출해요. 둘 다 create_deep_agent로 Deep Agent를 빌드하며 입력만 달라요:

  • **deep_agent**는 모델만으로 만들어진 Deep Agent인 make_graph로 해석돼요.
  • **research_agent**는 연구 시스템 프롬프트가 있는 동일한 Deep Agent인 make_research_graph로 해석돼요.

각 그래프는 --model의 모델(configurable.model에서 읽음)을 create_deep_agent에 전달하며, init_chat_model()으로 해석해요:

from deepagents import create_deep_agent


def make_graph(config):
    return create_deep_agent(model=config["configurable"]["model"])


def make_research_graph(config):
    return create_deep_agent(
        model=config["configurable"]["model"],
        system_prompt="You are a research assistant.",
    )

configurable.model을 읽는 팩토리 함수는 그래프를 모델에 구애받지 않게 유지하지만, 항상 같은 모델을 실행해야 한다면 그래프에 모델을 하드코딩할 수도 있어요. 고정 모델의 경우 langgraph.json을 팩토리 대신 컴파일된 그래프로 연결해요:

from deepagents import create_deep_agent

graph = create_deep_agent(model="fireworks:accounts/fireworks/models/glm-5p2")

샌드박스 안에서 에이전트 실행

Harbor는 전체 에이전트를 시도 컨테이너 안에서 실행해요.

1. **파싱 및 준비**: `harbor run`이 플래그를 작업 구성으로 파싱해요. 작업 팩토리는 시도가 실행되기 전에 작업을 해석·캐시하고, 환경 리소스 한도를 검증하며, 지표를 해석해요. 캐싱은 원격 작업에만 적용되므로 `-p` 로컬 작업은 제자리에서 읽혀요. 2. **Fan out**: Harbor는 `n_attempts × tasks × agents`로 시도 목록을 만들고 `-n` 한도까지 시도를 동시에 실행하며 `-r` 재시도로 보강해요. 병렬성은 시도 단위이므로 서로 다른 작업, 에이전트, 시도가 각자 자신의 샌드박스에서 함께 실행돼요. 3. **시도 생성**: 시도는 캐시된 작업을 로드하고, `project_path`, `graph`, `model`에서 LangGraph 에이전트를 빌드하며, 시작하지 않고 환경을 구성해요. 4. **환경 시작**: 환경이 시작되고 컨테이너를 띄워요. Docker 환경에서는 이미지를 빌드하거나 재사용하고 컨테이너를 실행해요. 5. **에이전트 설치**: Harbor는 컨테이너 안에 가상 환경을 만들고, `project_path`를 업로드하며, 컨테이너 안에서 `langgraph.json` 종속성을 pip 설치해요. 6. **실행 및 검증**: Harbor는 LangGraph 러너를 통해 컨테이너 안에서 그래프를 실행한 다음 `tests/test.sh`를 실행해 보상을 `/logs/verifier/reward.txt`에 기록해요. 7. **마무리**: Harbor는 컨테이너를 멈추고 삭제하며 시도 결과를 기록해요. 작업은 모든 시도 결과를 하나의 작업 결과로 집계해요.

Deep Agents 빌드에 대한 자세한 내용은 Deep Agents 문서를 참조하세요.

샌드박스

langsmith Harbor 환경은 각 시도를 LangSmith 샌드박스에서 실행해요. --env langsmith로 선택해 다른 샌드박스 프로바이더와 함께 Harbor 작업을 LangSmith 인프라에서 실행해요. 각 시도는 자체 샌드박스를 받으며, 시도가 끝나면 Harbor가 샌드박스를 삭제해요.

평가 실행

Harbor 작업을 실행하고 --env langsmith로 LangSmith 환경을 선택해요:

harbor run -d "<org/name>" \
  --model "<model>" \
  --agent "<agent>" \
  --env langsmith \
  -n "<n-parallel-trials>"

Harbor는 시도당 하나의 LangSmith 샌드박스를 만들고 그 안에서 에이전트와 검증기를 실행해요.

샌드박스 환경 구성

LangSmith 환경은 각 샌드박스를 파일시스템 스냅샷에서 부팅해요. Harbor 작업에서 다음 중 하나를 제공하세요:

  • 사전 빌드 이미지: task.toml[environment].docker_image를 설정해요. Harbor는 해당 이미지에서 스냅샷을 재사용하거나 생성해요.
  • 기존 스냅샷: 이미 만든 스냅샷에서 부팅하려면 environment.kwargs.snapshot_name을 전달해요.
  • Dockerfile: environment/Dockerfile을 포함해요. Harbor는 작업 environment/ 디렉토리를 빌드 컨텍스트로 사용해 Dockerfile-빌드-플로우로 스냅샷을 빌드해요.

환경 kwargs로 샌드박스 수명을 조정하고, 명령줄에서 --ek로 전달해요:

harbor run -d "<org/name>" \
  --model "<model>" \
  --agent "<agent>" \
  --env langsmith \
  -n "<n-parallel-trials>" \
  --ek idle_ttl_seconds=0 \
  --ek delete_after_stop_seconds=7200
  • idle_ttl_seconds: 이 초 후 유휴 샌드박스를 중지해요. 유휴 타임아웃을 비활성화하려면 0을 설정해요.
  • delete_after_stop_seconds: 멈춘 샌드박스를 이 초 후 삭제해요.

문제 해결

  • 인증 오류로 작업이 시작되지 않음: LANGSMITH_API_KEY가 설정되어 있는지, 또는 LANGSMITH_PROFILE이 구성된 프로필을 가리키는지 확인하세요.
  • 모델에 대해 에이전트가 ValueError를 발생: --modelprovider:model 형식으로 전달하고, init_chat_model()이 해석할 수 있도록 일치하는 langchain-* 프로바이더 패키지를 설치하세요.

같이 보기

더 알아보기 (Learn more)