TL;DR

  • agent-harness는 Go 1.26 이상에서 LLM API 기반 도구 호출 루프를 구축하는 최소 구성·조합형 라이브러리임.
  • harness.Run()이 LLM 호출, 도구 실행, 실행 결과 전달을 반복하며 저장소·프롬프트·라우팅은 애플리케이션이 담당함.
  • 제공 기능은 도구 실행 전 승인, 스트리밍, 이벤트 관찰, 도구 공개 범위 조절, 보류된 도구 호출의 일시 중지·재개임.
  • OpenAI Responses API 및 Anthropic 어댑터와 선택형 파일 기반 메모리를 포함하며, 고정된 LLM 제공자나 대화 저장 방식을 강제하지 않음.
  • 핵심 구현 가이드와 실행 가능한 REPL 예제를 제공하며 ACP 및 MCP와 조합 가능함.

요구 사항

  • Go 1.26 이상이 필요함.
  • harness.Run()에 컨텍스트와 제공자를 전달하고 시스템 프롬프트, 메시지, 도구, 모델 이름, 최대 실행 단계를 옵션으로 지정하는 방식임.

제공 기능

  • 에이전트 핵심 루프를 구현함: LLM 호출 → 도구 호출 실행 → 결과 전달 → 반복.
  • 저장소, 프롬프트, 라우팅은 라이브러리 범위에 포함되지 않음.

상태

  • 핵심 하네스 루프, 훅, 스레드 상태가 구현됨.
  • 핵심 루프 동작과 일시 중지·재개를 검증하는 단위 테스트가 마련됨.
  • OpenAI Responses API 어댑터가 provider/openai에 구현됨.
  • Anthropic 제공자 어댑터가 provider/anthropic에 구현됨.
  • 선택형 파일 기반 메모리, 회상 도구, 기록 및 승격 기능이 memory에 구현됨.
  • examples/claw에 수동 테스트용 REPL 하네스가 제공됨.

제공하지 않는 기능

  • 특정 LLM 제공자를 강제하지 않으며, 내장 어댑터를 사용하거나 Chat() 제공자를 직접 구현하는 방식임.
  • 대화 저장을 관리하지 않으며, Thread 유형을 원하는 방식으로 직렬화하는 구조임.
  • 시스템 프롬프트를 구성하지 않으며, 문자열을 직접 전달하는 방식임.
  • 다중 에이전트 워크플로를 조율하지 않으며, 하위 에이전트에는 도구에서 Run()을 호출하는 방식임.

설계

  • 프레임워크가 아니라 단일 Run() 함수로 구성됨.
  • 제공자 인터페이스는 메서드 하나로 구성됨.
  • 도구 스키마와 실행이 하나의 위치에 묶임.
  • 승인 게이트용 WithBeforeTool, 스트리밍용 WithOnDelta, 관찰 가능성용 WithEventHandler 훅을 제공함.
  • WithToolFilter로 도구를 점진적으로 공개함.
  • 명시적 PendingToolCalls를 사용해 일시 중지·재개를 지원하며 승인 워크플로에 활용 가능함.
  • ACP 및 MCP와 자연스럽게 조합됨.

주요 단계

  • 재사용 가능한 하네스 핵심 기능(Run, 메시지, 도구, 제공자 인터페이스) 분리.
  • 일시 중지·재개 지원 추가: StopPaused, PendingToolCalls, Thread.ResolvePending.
  • 생명 주기 훅과 이벤트 방출 추가.
  • 단위 테스트로 핵심 루프 의미를 안정화.
  • examples/claw에 실행 가능한 REPL 예제 추가.
  • go test, go test -race, go vet용 CI 추가.
  • 상태를 유지하는 연속 실행과 스트리밍을 지원하는 provider/openai Responses 어댑터 구현.
  • 비스트리밍과 스트리밍을 지원하는 provider/anthropic 어댑터 구현.
  • 로컬 HTTP 테스트 서버를 사용한 제공자 통합 테스트 추가.
  • 제공자 중립적인 종료 상태, 연속 실행, 캐시 인식 사용량 추가.
  • 선택형 파일 기반 메모리와 복구 가능한 도구 실행 기록 추가.

문서

  • docs/architecture.md: API 형태, 루프 생명 주기, 상태 모델.
  • docs/runner.md: 실행 중인 작업을 시작하고 중지하는 선택형 도우미.
  • docs/providers.md: 제공자 어댑터 계약과 유형 매핑.
  • docs/memory.md: 선택형 파일 기반 메모리 패키지, 회상 도구, 승격 기본 요소.
  • docs/research.md: 연구 노트와 설계 근거.
  • docs/ 디렉터리가 설계 및 구현 지침의 기준 문서임.

일시 중지 및 재개

  • harness.NewThread()로 스레드를 만들고 사용자 메시지를 추가한 뒤 harness.Run()에 메시지와 도구를 전달하는 방식임.
  • WithBeforeTool 훅에서 delete_deployment 호출이면 ToolActionPause, 그 외에는 ToolActionContinue를 반환하도록 설정할 수 있음.
  • 결과가 있으면 스레드에 추가하고, 종료 이유가 StopPaused이면 하네스 바깥에서 승인 흐름을 처리함.
  • thread.ResolvePending()에 승인된 도구를 실행하는 함수를 전달해 보류 중인 호출을 해결함.
  • 보류 호출 해결 후 메시지와 도구를 전달해 harness.Run()을 다시 호출하고, 결과를 스레드에 추가하는 방식임.

점진적 도구 공개

  • WithTools에 읽기 도구와 쓰기 도구를 전달하고 WithToolFilter로 단계별 공개 범위를 설정할 수 있음.
  • 0단계에서는 읽기 도구만 반환하고, 이후 단계에서는 읽기 도구와 쓰기 도구를 모두 반환하는 예시임.

실행 중인 작업 취소

  • 사용자 입력의 “stop”처럼 외부 제어 입력으로 실행 중인 작업을 중단하려면 runner.Runner를 사용할 수 있음.
  • runner.New()로 러너를 만들고 Start()에 컨텍스트, 스레드 ID, 실행 함수를 전달해 작업을 시작함.
  • 별도의 제어 흐름에서 입력을 공백 제거 후 대소문자 구분 없이 비교해 “stop”이면 r.Stop(thread.ID)를 호출함.
  • Start()가 반환하는 완료 채널에서 실행 종료 결과를 받을 수 있음.

Claw 예제 실행

  • OPENAI_API_KEY를 설정하고 go run ./examples/claw를 실행하는 방식임.
  • 프롬프트 또는 /stop, /history, /tools, /memory, /remember <text>, /new, /quit 제어 명령을 입력할 수 있음.
  • 예제는 기본적으로 ~/.agent-harness/claw에 파일 기반 메모리를 사용하며, --memory-dir ""을 전달하면 메모리를 비활성화함.
  • 주요 구현 가이드는 docs/architecture.md임.