Self-Contained 및 모듈식 AI 에이전트 설정 시스템, rigup
요약
rigup은 지식, 명령어, 기술(skills)을 패키징하여 AI 에이전트가 실행할 수 있는 모듈식 설정 시스템입니다. Nix 기반으로 구축되어 '실행 가능한 지식'인 riglet을 정의하며, 이를 조합해 복잡한 프로젝트 작업을 수행하는 에이전트를 구성합니다. 이는 기존의 Skills와 높은 상호 운용성을 가지며, 에이전트에게 필요한 도구와 운영 지식을 체계적으로 제공하여 개발 워크플로우를 개선합니다.
핵심 포인트
- rigup은 Nix 기반으로 AI 에이전트의 모듈식 설정을 지원합니다.
- 지식(knowledge), 명령어(instructions), 기술(skills)을 패키징한 'riglet' 개념을 도입했습니다.
- 에이전트가 필요한 정보를 지연 로드하거나 특정 방식으로 노출할 수 있는 제어권을 제공합니다.
- ‘지식 우선’ 설계를 채택하여 문서화와 도구를 분리하고 체계화했습니다.

Self-Contained & Modular AI Agent Config
rigup은 지식(knowledge), 명령어(instructions) 및 기술(skills)을 패키징하여 AI 에이전트가 이를 실행하는 데 필요한 도구와 설정을 제공하는 Nix 기반 시스템입니다.
_riglet_이란 _실행 가능한 지식_을 의미합니다:
- 에이전트에게 이 riglet의 목적과 언제 참고하면 유용한지 알려주는 메타데이터
- 에이전트를 위한 일련의 작업, 명령어, 프로세스 (즉, 새로운 Skill)
- 이러한 명령을 실행하는 데 필요한 도구(nix 패키지)
- 이 도구들에 대한 설정(있을 경우)
관련된 riglet들을 조합함으로써, 에이전트의 _rig_을 구축하게 됩니다. 이는 프로젝트 작업을 수행하는 데 필요한 도구와 해당 도구를 적절하고 효율적으로 사용하는 데 필요한 운영 지식을 의미합니다.
기본적으로 riglet의 문서는 _지연 로드(lazily)_됩니다 (Skills가 그러하듯이): 에이전트가 시작될 때 매니페스트를 받게 되며, 각 riglet에 대해 간략한 설명과 사용 사례만 표시됩니다. 이후 필요할 때 또는 프롬프트가 주어질 때 읽기 시작합니다.
다만, rigup은 에이전트가 언제 riglet의 내용에 노출되어야 하는지에 관해서는 Skills가 전통적으로 제공하는 것보다 더 많은 제어권을 제공합니다. 예를 들어, 기본적인 riglet은 _즉시 공개(eager)_되도록 설정할 수 있습니다 (에이전트에게 시작 시 전체 SKILL.md를 강제 노출). 반면, 다른 riglet은 얕은 목차(shallow-toc) 공개가 가능합니다 (에이전트는 riglet의 메인 SKILL.md의 목차만 보게 됩니다).
게다가, Skills는 필연적으로 고정된 파일인 반면, riglets의 문서 파일은 모든 Nix _derivation_을 통해 생성될 수 있습니다. 이는 내용이 단순한 원본 파일에서 읽힐 수도 있고, 예를 들어 bash 스크립트를 통해 프로그래밍 방식으로 정의될 수도 있음을 의미합니다. 이로 인해 riglet의 문서 파일 내용은 해당 riglet의 도구와 동일한 방식으로 구성 가능해집니다. rigup의 Nix 라이브러리는 minijinja를 통해 스킬을 템플릿화할 수 있는 유틸리티를 제공하여 이 사용 사례를 용이하게 합니다.
rigup은 '지식 우선(knowledge-first)' 설계를 채택했습니다: 문서화가 페이로드(payload)이며, 도구들은 의존성(dependencies)입니다. rigup의 '주요 진입점(main entrance)'은 RIG.md 매니페스트(manifest)가 될 것이며, 이 파일을 통해 rigup은 여러분의 AI 에이전트가 읽을 수 있도록 하고, 이용 가능한 모든 도구, 지식 및 프로세스를 발견하게 합니다.
간단히 말해, rigup은 에이전트용 매개변수화된 스킬(parametrable agent skills) + 경량 홈 관리 시스템이며, Skills와 Claude 플러그인 마켓플레이스와 높은 수준의 상호 운용성(interoperability)을 제공하여 기존 Skills를 riglets로 재사용하거나 riglets의 기반으로 삼는 것이 가능한 한 쉽게 만듭니다.
빠른 시작 (Quick start)
먼저, rigup CLI 도구를 설치합니다:
nix profile add github:YPares/rigup.nix#rigup
참고: 구형 Nix 버전에서는 'add' 대신 'install'을 사용해야 합니다.
이미 설치되어 있다면, 다음 명령어로 업데이트합니다:
nix profile upgrade rigup
이 CLI 도구는 다음 작업을 더 쉽게 수행할 수 있도록 돕습니다:
- flake 및 그 입력값(inputs)에 노출된 riglets와 rigs에 대한 정보를 얻기 (
rigup show) - rig의 내용을 보여주며, 어떤 옵션들을 사용하여 설명(description), 유형(type), 기본값(default) 및 현재 값(current values)과 함께 사용자 정의할 수 있는지 확인하기 (
rigup inspect) - rig이 _entrypoint_를 제공하는 riglet을 포함하고 있다면 코딩 에이전트 하네스(coding agent harness)를 직접 시작하기 (
rigup run또는 단순히rigup) . 엔트리포인트는 커넥터 역할을 하여 적절한 설정으로 하네스를 시작하도록 래핑합니다. - 전체 rig를 심볼릭 링크 폴더로 빌드하기 (
rigup build) $PATH와$RIG_MANIFEST(RIG.md의 경로)가 설정된 상태에서 rig를 서브쉘(subshell)처럼 사용하기 (rigup shell)
참고할 점은 이 모든 명령어는 편의를 위해 제공되는 래퍼(wrappers)일 뿐이며, rigup Nix 라이브러리를 기반으로 합니다. 따라서 선호한다면 여전히 일반적인 nix build 호출로 모든 것을 할 수 있습니다.
그 후에는 이 저장소에서 제공하는 템플릿을 사용하여 새 프로젝트를 만들거나, 여기에 정의된 예제 rig를 직접 빌드할 수 있습니다.
이 프로젝트의 rig 사용하기 (Use a rig from this project (or any other repo using rigup))
이 프로젝트는 예제 riglets와 이를 결합한 예제 rig를 정의합니다.
# 원격 flake에서 노출되는 riglet과 rig을 보여줍니다.
rigup show github:YPares/rigup.nix
# riglet 및 각 rig의 내용에 대한 모든 메타데이터를 보여줍니다.
...
새 프로젝트 생성하기
이 저장소의 템플릿 중 하나로 생성합니다:
rigup new foo [-t minimal]
# 로컬 riglet을 정의할 필요가 없는 프로젝트에는 'minimal' 템플릿을 사용하세요.
...
이 명령어는 ./foo 폴더를 만들고, 이를 git 저장소로 초기화하며, flake.nix와 예시 riglet 및 rig으로 기본적인 프로젝트 구조를 생성하기 위해 nix flake init을 호출하고, 모든 파일을 git 추적 대상에 추가합니다(중요), 마지막으로 결과물에 대해 nix flake check를 실행하여 모든 것이 순서대로 되어 있는지 확인합니다.
# flake의 self 및 inputs에서 사용 가능한 riglet 목록을 보여줍니다.
rigup show --detailed --with-inputs
...
프로젝트를 사용자 정의하려면 riglets/*.nix와 rigup.toml 파일을 수정하세요.
기본 템플릿에는 몇 가지 예시 riglet이 포함되어 있으며, rigup이 Claude Marketplace를 직접 입력으로 사용하는 방법을 보여주어 기존에 존재하는 Skills을 가져와 riglet의 기반으로 사용할 수 있음을 보여줍니다.
대안: devenv 사용하기
프로젝트가 Nix flakes 대신 devenv를 사용하는 경우, 이 저장소를 devenv 모듈로 직접 사용하여 실험적인 rigup 통합을 이용할 수 있습니다. 여기 예시를 따르세요.
중요: rigup CLI 도구는 오직 flake 기반 프로젝트만 다루며, 나머지 문서는 flake 기반 프로젝트를 가정하고 작성되었지만, rig과 riglet을 선언하는 방법에 관한 모든 내용은 여전히 적용 가능합니다. 시작하는 방식만 변경됩니다.
또한, devenv 통합은 사용자가 자신의 rig과 riglet을 선언하고 다른 flake 기반 프로젝트에서 정의된 riglet을 재사용하는 것만을 다룹니다. 다른 사람이 사용할 riglet을 패키징하려면 Nix flakes가 더 적합합니다.
rigup을 devenv와 함께 사용하는 방법에 대한 자세한 정보는 이 통합이 성숙해짐에 따라 여기에 추가될 것입니다.
깊이 파고들기
이 섹션에서는 riglet과 rig을 정의하고 편집하는 일반적인 워크플로우를 다룹니다.
riglet 생성하기
riglets는 Nix 모듈(Nix modules)의 간단한 사용 사례입니다. 구체적으로, 이는 riglet이 (가장 일반적인 형태에서) (config, dependencies) -> data라는 Nix 함수임을 의미합니다. 여기서:
config는 해당 riglet이 속한 rig의 최종 설정 값입니다.data는 중첩된 필드를 제공하는 사전(dictionary)과 같은 구조("속성 집합(attribute set)"은 Nix 용어입니다)이며, 이 필드들이 스스로 최종 통합 설정에 기여하게 됩니다.
프로젝트 루트 디렉터리에 riglets/ 폴더를 만드세요.
그런 다음 그 안에 <riglet-name>.nix 파일을 추가합니다:
# riglets/my-riglet.nix
# 첫 번째 인자: 정의하는 flake의 'self' - 다음 사항에 접근할 수 있게 해줍니다:
...
...아니면 에이전트에게 요청하세요! :) rigup.nix에는 에이전트가 riglet을 작성하도록 가르치는 riglet-creator riglet이 포함되어 있습니다. 그리고... 음, 네, 이것은 매우 메타적인 내용이 되어서 죄송합니다.
일반 Agent Skill과 마찬가지로, 문서를 여러 파일로 분리하는 목적은 _점진적 공개(progressive disclosure)를 가능하게 하기 위함입니다. AI 에이전트를 사용할 때 이는 중요합니다. 왜냐하면 컨텍스트(context)는 제한적이기 때문에, 에이전트가 작업을 완료하기 위해 필요한 것보다 더 많은 문서를 읽을 필요가 없어야 하기 때문입니다.
대안 구조
riglets/<riglet-name>.nix 대신, riglets/<riglet-name>/default.nix로 riglet을 정의하여 그 옆에 지원 파일을 추가할 수 있습니다:
riglets/
├── simple-riglet.nix # 단일 파일 riglet
└── complex-riglet/ # 디렉터리 기반 riglet
...
이 방식은 riglet을 여러 Nix 파일이나 일반 텍스트 파일로 분해하여 관리하기 쉽게 만드는 데 유용합니다. rigup은 두 가지 레이아웃 모두를 발견하고 동일하게 처리할 것입니다.
riglet 간 의존성
만약 하나의 riglet이 다른 riglet에 의존하는 경우(예를 들어 개념을 기반으로 하거나 도구나 구성을 필요로 하는 경우), self.riglets.*를 사용하여 imports를 사용하십시오:
# riglets/advanced-riglet.nix
self:
{ riglib, ... }: {
...
중요: 항상 self.riglets.*를 가져오기(import)에 사용하고, ./base-riglet.nix와 같은 경로 기반의 임포트는 절대 사용하지 마십시오. self.riglets.* 형식은 동일한 riglet이 직접 포함되거나 임포트를 통해 포함될 때 적절한 중복 제거를 보장합니다.
외부 flake의 riglet에 의존하는 경우:
self:
{ riglib, ... }: {
imports = [ self.inputs.other-flake.riglets.some-riglet ];
...
외부 패키지 사용하기
Riglets는 self.inputs를 통해 외부 flake의 패키지에 접근할 수 있습니다:
self:
{ pkgs, system, riglib, ... }: {
config.riglets.my-riglet = {
...
이를 통해 riglets가 소비자(consumers)가 알 필요 없이 자체 의존성을 묶을 수 있게 합니다.
rig 생성하기
간단한 옵션: rigup.toml
프로젝트 상단에 있는 rigup.toml에서 rig를 정의하십시오:
# 이 rig에 포함할 riglet을 소스별로 그룹화
[rigs.default.riglets]
rigup = [
이는 사용자의 `flake.nix`에 `riglets.foo`와 `riglets.bar` 출력을 노출하는 `some-flake` 입력이 있다는 것을 의미합니다.
`self`는 그 경우의 특별한 예시일 뿐인데, 모든 flake는 자체적으로 플레이크 자체를 나타내는 암묵적인 `self` 입력을 가지고 있기 때문입니다.
**참고:** TOML 파일을 사용하는 주된 이유는 항상 모든 것을 Nix 코드로 정의하는 것보다 단순히 TOML이 (훨씬) 더 잘 알려진 문법이기 때문만은 아닙니다.
주로 순수 데이터(이미 많은 사용 사례를 포괄할 수 있는 데이터)가 Nix 코드보다 CLI 도구를 통해 조작하기가 더 쉽기 때문입니다.
#### 고급 옵션: Nix와 결합하기
...라고 하더라도, Nix에서 직접 리그(rigs)를 구축하는 것(리그의 구성을 작성하는 데 전체 Nix 기능이 필요할 경우)은 완전히 지원됩니다:
```nix
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
inputs.rigup.url = "github:YPares/rigup.nix";
...
중요: 이렇게 하면 rigup.toml이 완전히 선택 사항이 되지만, 플레이크의 출력을 구성하기 위해 rigup { inherit inputs; ... }를 사용하는 것은 여전히 필수적입니다.
이는 rigup이 $PROJECT_ROOT/riglets/에 정의된 어떤 리그렛(riglet)을 발견하고 플레이크의 riglets 출력을 올바르게 설정할 수 있도록 하기 위함입니다.
위에서 제안했듯이, 두 옵션을 완전히 혼합할 수 있습니다. 즉, rigup.toml에 간단한 리그를 일부 정의하고 고급 리그는 Nix 코드로 일부 정의하는 방식입니다.
비록 모든 것을 flake.nix에 선언하기보다는 별도의 Nix 파일에 리그 정의를 분리하는 것이 좋지만, 위 예시는 간결함을 위한 것일 뿐입니다.
리그렛 메타데이터
리그렛은 스킬(Skills)보다 메타데이터 측면에서 조금 더 풍부하지만 동시에 더 엄격하다는 것을 알아차렸을 수 있습니다.
이는 좋은 문서 작성 관행을 좀 더 엄격하게 강제하고, 에이전트가 매니페스트를 읽거나 사람이 rigup show로 제공되는 리그렛을 검색할 때 중요한 정보가 더 눈에 띄도록 하기 위함입니다.
이는 너무 제약적이지 않으면서 최종 문서의 품질 향상에 기여합니다.
이것이 스킬과 달리 다음과 같은 이유입니다:
AI 자동 생성 콘텐츠
본 콘텐츠는 개발 자료 GitHub · 9ffce42f의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기