ax-go 0.2 및 0.3: 고정(pinning)할 가치가 있는 컨트랙트
요약
ax-go 0.2 및 0.3 릴리스를 통해 에이전트 컨트랙트의 독립적인 고정(pinning) 기능이 도입되었습니다. v0.2.0은 무거운 런타임 의존성 없이 필요한 컨트랙트 패키지만 가볍게 임포트할 수 있도록 구조를 개선했습니다.
핵심 포인트
- v0.2.0: 런타임 의존성 없이 컨트랙트 패키지만 분리하여 임포트 가능
- v0.3.0: 고정된 컨트랙트의 불변성 유지 기능 제공
- 의존성 최적화: 불필요한 텔레메트리 스택 없이 가벼운 오케스트레이터 구현 가능
- 타입 별칭 활용: 패키지 분리 후에도 기존 타입과의 호환성 유지
두 번의 ax-go 릴리스가 짧은 간격으로 출시되었으며, 이들은 사실 하나의 아이디어를 두 부분으로 나눈 것입니다. v0.2.0은 에이전트가 의존하는 컨트랙트(contract)만을 런타임(runtime) 없이 고정(pin)할 수 있게 해줍니다. v0.3.0은 일단 고정한 컨트랙트가 변경되지 않도록 유지하는 작업입니다.
처음 오신 분들을 위한 설명: ax-go는 제 Go CLI들의 agentic-experience foundation입니다. stdout은 데이터이며, 트레이스(traces)는 플러그인 경계를 넘나들고, 모든 인간용 테이블에는 JSON 쌍이 존재합니다. 컨트랙트(contract)가 핵심이며, 따라서 두 릴리스 모두 컨트랙트에 관한 것입니다.
v0.2.0: import-isolated 컨트랙트 패키지
Go의 임포트(import)는 전부 아니면 전무(all-or-nothing) 방식입니다. 트리 쉐이킹(tree-shaking)이 없습니다. 패키지를 임포트하면, 해당 패키지를 호출하든 안 하든 전체 전이적 의존성 그래프(transitive dependency graph)가 함께 컴파일됩니다.
따라서 v0.2.0 이전까지는 ax-go 컨트랙트(에러 엔벨로프(error envelope), 종료 코드(exit codes), __schema 형태)를 재사용하려면 루트 ax 패키지를 임포트해야만 했습니다. 그리고 ax는 OpenTelemetry SDK, zerolog 및 Loki, HTTP 및 gRPC 인스트루멘테이션(instrumentation)을 포함하는 전체 런타임(runtime)입니다. 잘 형성된 에러 엔벨로프를 내보내기만 원하는 가벼운 오케스트레이터(orchestrator)가 사용하지도 않는 텔레메트리(telemetry) 스택의 비용을 지불해야 했던 것입니다.
v0.2.0은 루트에서 네 개의 좁은 패키지를 분리해냈습니다:
contract: 종료 코드(exit codes), 모드 해석(mode resolution), 컨텍스트 메타데이터(context metadata), 성공/에러 엔벨로프(success/error envelope), 엄격한 JSON/NDJSON 라이터(writers).config: 제한된 Hujson 읽기 및 주석을 보존하는 RFC 6902 패치.schema: ax-native 및 MCP 호환 스키마 빌더(schema builders), 그리고__schema명령.id: UUID v4 멱등성 키(idempotency keys) 및 UUID v7 엔티티 ID(entity IDs).
각 패키지는 표준 라이브러리에 의존하며 그 외에는 거의 의존하지 않습니다. 루트 파사드(root facade)나 런타임 어댑터(runtime adapter)에는 절대 의존하지 않습니다. 따라서 여러분이 선택하는 임포트(import)는 여러분이 감당해야 할 무게와 일치합니다:
import "github.com/rshade/ax-go/contract" // 형태(shapes)만 포함
import ax "github.com/rshade/ax-go" // 형태(shapes)와 런타임(runtime) 모두 포함
루트 ax 패키지는 여전히 변경 없이 작동합니다. 이 패키지는 이동된 모든 타입을 다시 내보내는(re-export) 얇은 파사드(facade)가 됩니다:
type Error = contract.Error
이것은 새로운 타입이 아니라 타입 _별칭(alias)_이며, 이 구분은 실제로 중요한 역할을 합니다: ax.Error와 contract.Error는 동일한 타입입니다. 따라서 errors.As(err, *contract.Error)는 런타임 깊숙한 곳에서 생성된 에러와 여전히 매칭됩니다. 분리 후에도 정체성(Identity)이 유지되므로, v0.1.0에서 업그레이드하는 방법은 go get -u 외에는 아무것도 필요하지 않습니다.
이 경계(boundary)는 약속이 아니라 테스트입니다. 각 컨트랙트(contract) 패키지는 go list -deps를 실행하는 임포트 격리(import-isolation) 테스트를 포함하며, 그래프에 금지된 런타임 임포트(루트 파사드, OTel SDK, Loki, HTTP 또는 gRPC 인스트루멘테이션(instrumentation))가 나타나면 빌드를 실패시킵니다. CI(지속적 통합)가 격리를 강제하므로, 제가 일일이 기억할 필요가 없습니다.
v0.3.0: 컨트랙트가 표류하지 않도록 유지하기
컨트랙트를 분리하는 것은 약속의 절반입니다. 나머지 절반은 당신이 고정(pin)한 형태(shapes)가 당신의 발밑에서 움직이지 않는 것입니다. v0.3.0은 그 안전 가드레일입니다.
커버리지 하한선(Coverage floors). 이제 모든 컨트랙트 패키지는 저장소 전체에 적용되는 하한선과 더불어, CI에서 강제되는 자체 커버리지 하한선을 가집니다. 가벼운 소비자(consumer)가 고정하는 패키지들은 테스트 커버리지가 조용히 누락되어서는 안 되는 바로 그 패키지들입니다.
호환성 매트릭스(compatibility matrix) 및 기여 가이드(CONTRIBUTING guide). 이제 README에 어떤 Go 버전과 어떤 ax-go 버전이 지원되는지 명시되어 있으므로, "이것에 의존해도 되는가"에 대해 추측 대신 문서화된 답변을 얻을 수 있습니다. CONTRIBUTING 문서에는 컨트랙트 인터페이스(surface)가 어떻게 변경될 수 있는지, 그리고 어떻게 변경될 수 없는지를 설명합니다.
파괴적 변경(breaking changes)에 대한 게이트. 이제 공개 API(Public-API) 변경 사항은 CI에서 go-apidiff를 통해 검사되므로, 내보내진(exported) 컨트랙트에 대한 파괴적 변경은 게이트를 통과하지 않고는 머지(merge)될 수 없습니다. 당신이 의존하는 고정된 버전이 실수로 움직이는 일은 없을 것입니다.
문서 사이트
두 릴리스 모두 이제 실제 홈 페이지를 갖게 되었습니다: rshade.github.io/ax-go. 이는 공유된 rshade-theme를 기반으로 구축된 Astro Starlight 사이트입니다. finfocus와 동일한 토큰을 사용하는데, 같은 곳에서 만들어졌기 때문입니다.
현재 상황
여전히 1.0 버전 이전 단계이며, 여전히 고정(pinning)할 가치가 있습니다. v0.2.0은 컨트랙트(contract)만 고정할 수 있게 해주었으며, v0.3.0은 그 고정을 안전하게 유지하는 작업을 수행합니다. 에이전트(agent)가 종료 코드(exit code)를 읽기 위해 텔레메트리 스택(telemetry stack)을 컴파일할 필요가 없어야 하며, 깨어났을 때 코드가 발밑에서 움직여 있는 것을 발견해서도 안 됩니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기