Agent-Native CLI 설계: AI 시대를 위한 10가지 원칙

수십 년 동안 명령줄 인터페이스(CLI)는 터미널에 있는 인간을 주요 사용자로 설계되었습니다. 우리는 시각적 정렬, ANSI 색상, 인터랙티브 프롬프트와 같은 사람에게 직관적인 요소들을 최적화했지만, 이는 종종 AI 에이전트에게는 장애물이 됩니다. 에이전트가 점점 우리 API의 주요 소비자가 됨에 따라 설계 철학도 변화해야 합니다.

Trevin Chow는 최근 자신의 작업과 Cloudflare 및 HeyGen과 같은 기업들의 구현을 바탕으로 “Agent-Native CLI” 프레임워크를 제안했습니다. 핵심 논지는 간단합니다: 에이전트를 먼저 설계하면, 그 결과로 얻어지는 엄격함과 일관성 덕분에 인간도 실제로 혜택을 받게 됩니다.

Tier 1: 에이전트를 깨뜨리지 말기

첫 번째 단계의 원칙은 방어적인 설계에 초점을 맞춥니다. 이는 에이전트가 멈추거나 무한 루프에 빠지거나 조용히 실패하지 않도록 보장하는 기본 요구사항입니다.

1. 기본적으로 비대화형

  • 에이전트는 “정말 실행하시겠습니까? [y/N]”와 같은 프롬프트에 답할 수 없습니다. 명령이 입력을 기다리며 멈추면 에이전트는 단순히 중단됩니다.
  • 표준: 프롬프트가 발생할 수 있는 모든 명령은 --no-input 또는 --yes 플래그를 가져야 합니다.
  • 최적화: Cloudflare는 파괴적인 우회를 위해 --force를 표준화하고, 예측 가능한 어휘를 유지하기 위해 --skip-confirmations 사용을 명시적으로 금지합니다.

2. 구조화되고 파싱 가능한 출력

  • 표준: 데이터를 반환하는 모든 명령에 --json 플래그를 제공해야 합니다.
  • 최적화: 엄격한 일관성을 유지합니다. --format=json--output json을 혼용하지 마세요. 데이터는 stdout으로, 진단 정보는 stderr로 출력합니다.

3. 가르치고 열거하는 오류

  • “invalid visibility”와 같은 오류는 에이전트에게 막다른 길이 됩니다. 반면 “--visibility must be one of: public, private, unlisted”와 같이 가능한 값을 직접 제시하는 오류는 에이전트가 한 번의 재시도만으로 스스로 교정할 수 있게 합니다.
  • 표준: 열거형이나 스키마에 맞지 않는 입력을 거부할 때는 오류 메시지에 유효한 값 목록을 직접 표시합니다.

4. 안전한 재시도와 명시적인 변이 경계

  • 에이전트는 자주 재시도합니다. 멱등성이 없으면 재시도된 “create” 명령이 중복된 리소스를 생성하게 됩니다.
  • 표준: 멱등성 토큰이나 자연키를 사용합니다.
  • 최적화: 중요한 작업에 --dry-run을 구현하고, 파괴적인 동작은 명시적이고 기본값이 아닌 플래그를 요구하도록 합니다.

5. 제한된 응답

  • 무제한 출력은 토큰을 낭비하고 에이전트의 컨텍스트 창을 초과시킬 수 있습니다.
  • 표준: 모든 리스트형 명령에 페이지네이션, 제한, 필터링을 구현합니다.
  • 최적화: 다음 쿼리를 좁히는 방법을 명시적으로 알려주는 잘림 메시지를 제공하세요(예: “add --limit=N to see more”).

Tier 2: 에이전트 강화

CLI가 안정화되면, 다음 목표는 사용 빈도가 높아질수록 더 유용하게 만드는 것입니다. 이 단계는 수동 코딩보다 코드 생성이나 스키마를 통해 구현하는 것이 일반적으로 가장 좋습니다.

6. 크로스 CLI 어휘 일관성

  • 에이전트는 CLI 작동 방식을 일반화된 모델로 구축합니다. 대부분의 도구가 get을 사용하지만 여러분의 도구가 info를 사용한다면, 에이전트는 이를 파악하기 위해 토큰과 재시도를 소비하게 됩니다.
  • 표준: 커뮤니티 관례(get, list, create, update, delete 등)를 따릅니다.
  • 최적화: 인간 리뷰에 의해 발생할 수 있는 “스위스 치즈”식 일관성 문제를 방지하기 위해 스키마 레이어에서 기계적으로 강제합니다.

7. 3계층 인스펙션

  • Layer 1: 인간을 위한 표준 --help.
  • Layer 2: agent-context — CLI 전체 구조를 설명하는 버전 관리된 기계 판독 가능한 JSON.
  • Layer 3: 스킬 매니페스트(예: SKILL.md) — 에이전트가 작업을 복합 워크플로우로 구성하는 방법을 가르치는 장문 문서.

8. 비동기 인식 실행

  • 에이전트가 비동기 작업을 위해 자체 폴링 루프를 작성하도록 강요하면 토큰 소모가 많고 오류가 발생하기 쉽습니다.
  • 표준: 완료될 때까지 차단하는 --wait 플래그를 제공합니다.
  • 최적화: 로컬 작업 원장을 유지(~/.cli/jobs.jsonl 등)하여 에이전트가 폴링 중 연결이 끊어지면 다음 실행 시 새 작업을 시작하는 대신 진행 중인 작업을 복구할 수 있게 합니다.

9. 프로파일을 통한 지속적인 정체성

  • 무상태 CLI는 에이전트가 매번 동일한 구성 플래그를 다시 지정하도록 강요합니다.
  • 표준: 구성 묶음을 위해 프로파일 시스템(profile save, profile use)을 구현합니다.
  • 최적화: agent-context에 사용 가능한 프로파일을 표시하여 에이전트가 설정 파일을 파싱하지 않고도 기존 정체성을 발견할 수 있게 합니다.

10. 양방향 I/O

  • 에이전트는 종종 생성된 비디오나 로그와 같은 아티팩트를 특정 목적지로 이동시켜야 합니다.
  • 표준: stdout, file:<path>, webhook:<url>를 지원하는 --deliver 플래그를 구현합니다.
  • 최적화: 에이전트가 마찰을 직접 보고할 수 있도록 feedback 명령을 포함합니다(예: “this flag is documented but rejected”).

논쟁: Agent-Native vs. Unix-Native

모든 개발자가 “agent-native”라는 라벨에 동의하는 것은 아닙니다. 일부는 이 원칙들이 단순히 “좋은 CLI 설계”이며 원래부터 따라야 했다고 주장합니다.

"만약 jq를 사용해 본 적이 있다면, --json이 매우 유용한 옵션이라는 것을 누가 알려줄 필요가 없습니다... 이것은 단순히 명령줄 인터페이스를 인터페이스로서 진지하게 바라보는 것입니다. AI와는 가장자리 부분을 제외하고는 거의 관련이 없습니다."

다른 사람들은 인간 사용성을 희생하면서까지 에이전트를 위해 과도하게 설계하는 것을 경고하며, 충분히 좋은 “LLM용 매뉴얼 페이지”만 제공된다면 에이전트가 복잡한 CLI도 충분히 다룰 수 있다고 제안합니다.

철학적 입장 차이와 관계없이 실질적인 결과는 동일합니다: 예측 가능하고 구조화되며 일관된 CLI는 탄소든 실리콘이든 모든 사용자에게 더 우수합니다.

Sources