오픈소스 기여 이야기: oh-my-opencode에 /subagents 명령어를 추가하다
안녕하세요, Quokka Labs의 단테입니다.
오늘은 제가 최근 oh-my-opencode 플러그인에 /subagents 명령어를 기여하게 된 과정과, 이 기능이 왜 필요했는지, 그리고 AI 코딩 에이전트의 내부 구조가 어떻게 동작하는지 공유하려고 합니다.
📎 PR 링크: github.com/code-yeongyu/oh-my-opencode/pull/710
🎬 영상으로 보기: OpenCode & oh-my-opencode 소개 및 사용법 (YouTube)
배경: OpenCode와 oh-my-opencode란?
OpenCode
OpenCode는 터미널 기반의 AI 코딩 어시스턴트입니다. GitHub Copilot처럼 AI가 코드 작성을 도와주지만, 터미널(CLI) 환경에서 동작합니다.
┌─────────────────────────────────────────┐
│ $ opencode │
│ │
│ You: "login.ts의 버그 수정해줘" │
│ │
│ AI: [파일 읽기, 수정 제안] │
│ │
└─────────────────────────────────────────┘
oh-my-opencode
oh-my-opencode는 OpenCode를 확장하는 플러그인입니다:
- 다양한 특화 AI 에이전트 제공 (oracle, librarian, explore 등)
- 커스텀 슬래시 명령어 (
/init-deep,/refactor,/subagents) - 도구 통합 (LSP, AST-Grep 등)
마치 셸의 "oh-my-zsh"처럼, 기본 도구를 강력하게 확장시켜 줍니다.
문제 인식: 왜 /subagents가 필요했나?
oh-my-opencode는 여러 개의 **서브에이전트(Subagent)**를 제공합니다. 각 서브에이전트는 특정 작업에 최적화되어 있는데요:
| 서브에이전트 | 역할 |
|---|---|
| Sisyphus | 복잡한 작업을 하위 태스크로 분할하여 관리 |
| oracle | 고급 추론이 필요한 질문에 답변 |
| librarian | 코드베이스 탐색 및 문서화 |
| explore | 새로운 코드베이스 분석 |
문제는, 각 서브에이전트마다 어떤 LLM 모델을 사용할지 설정해야 하는데, 기존에는 이를 위해 JSON 설정 파일을 직접 편집해야 했습니다:
{
"agents": {
"oracle": {
"model": "claude-opus-4-5"
},
"Sisyphus": {
"model": "gpt-5.1-codex"
}
}
}
개발자라면 어렵지 않겠지만, 몇 가지 문제가 있었습니다:
- 어떤 모델을 사용할 수 있는지 모른다 - 사용 가능한 모델 목록을 알아야 함
- 설정 파일 위치를 찾아야 한다 - 전역/프로젝트 설정 경로가 다름
- JSON 문법 오류 - 쉼표 하나 빠뜨려도 전체 설정이 깨짐
터미널에서 자연스럽게 대화형으로 서브에이전트 모델을 변경할 수 있다면 훨씬 편할 것 같았습니다.
해결책: /subagents 명령어
제가 기여한 /subagents 명령어는 **대화형 TUI(Terminal User Interface)**를 통해 서브에이전트의 모델을 설정합니다.
User: /subagents
╭─────────────────────────────────────────────────╮
│ 🤖 Subagent Configuration │
│ │
│ Current Assignments: │
│ 1. Sisyphus → gpt-5.1-codex │
│ 2. oracle → claude-opus-4-5 │
│ 3. librarian → haiku-4.5 │
│ 4. explore → (default) │
│ │
│ Enter number to change model (or 'q' to quit) │
╰─────────────────────────────────────────────────╯
사용자가 번호를 입력하면 해당 에이전트에 사용 가능한 모델 목록이 표시됩니다:
User: 2
╭─────────────────────────────────────────────────╮
│ Available models for: oracle │
│ │
│ 1. claude-opus-4-5 │
│ 2. claude-sonnet-4.5 │
│ 3. gpt-5.1-codex │
│ 4. haiku-4.5 │
│ │
│ Enter number to select model │
╰─────────────────────────────────────────────────╯
모델을 선택하면 자동으로 설정 파일이 업데이트됩니다.
구현 과정: 템플릿 기반 명령어 아키텍처
전체 흐름
AI 코딩 에이전트의 명령어가 어떻게 동작하는지 이해하면, 이 기여가 더 흥미롭게 느껴질 겁니다.
┌──────────────────────────────────────────────────────────────────────┐
│ 사용자 입력: /subagents │
└──────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────┐
│ STEP 1: 명령어 조회 │
│ │
│ OpenCode가 "/subagents"를 보고 명령어 레지스트리(commands.ts)에서 │
│ 해당 정의를 찾습니다. │
└──────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────┐
│ STEP 2: 템플릿 주입 │
│ │
│ subagents.ts의 템플릿이 AI의 "시스템 프롬프트"에 주입됩니다. │
│ 이것이 AI가 따라야 할 지침입니다. │
└──────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────┐
│ STEP 3: AI가 템플릿 실행 │
│ │
│ AI가 템플릿 지침을 읽고: │
│ - TUI(텍스트 기반 UI) 표시 │
│ - 사용자 입력 대기 │
│ - 설정 파일 읽기/쓰기 수행 │
└──────────────────────────────────────────────────────────────────────┘
파일별 역할
1. templates/subagents.ts - 두뇌
이 파일은 AI를 위한 지침을 담고 있습니다. 실행되는 코드가 아니라, AI에게 무엇을 할지 알려주는 프롬프트입니다.
export const SUBAGENTS_TEMPLATE = `You are helping the user configure...
## TWO-STEP TUI FLOW
### STEP 1: List Subagents
Display the current subagent configurations...
### STEP 2: Model Selection
When user enters a number, show available models...
`
왜 자연어로 작성했을까요?
- AI(GPT, Claude 등)는 자연어를 이해합니다
- 우리는 본질적으로 지침을 통해 AI의 동작을 "프로그래밍"하고 있습니다
- 이것을 "프롬프트 엔지니어링"이라고 합니다
| 섹션 | AI에게 전달하는 내용 |
|---|---|
## CONTEXT | 서브에이전트에 대한 배경 정보 |
## STEP 0 | "먼저 사용자가 어떤 모델을 쓸 수 있는지 확인해" |
## STEP 1 | "이 번호 목록 형식으로 표시해" |
## STEP 2 | "사용자가 번호를 선택하면 모델 목록을 보여줘" |
## CRITICAL RULES | "입력을 기다려, 자동으로 진행하지 마" |
2. commands.ts - 레지스트리
모든 명령어를 등록하여 OpenCode가 인식할 수 있게 합니다.
const BUILTIN_COMMAND_DEFINITIONS = {
// 다른 명령어들...
subagents: {
description: "(builtin) Configure subagent-model assignments via interactive TUI",
template: `<command-instruction>
${SUBAGENTS_TEMPLATE} // ← 여기에 템플릿 주입
</command-instruction>
<user-request>
$ARGUMENTS // ← /subagents 뒤의 인자로 대체됨
</user-request>`,
},
}
3. types.ts - TypeScript 타입 안전성
export type BuiltinCommandName =
| "init-deep"
| "ralph-loop"
| "subagents" // ← 추가
TypeScript가 유효한 명령어 이름만 사용하는지 컴파일 타임에 검사합니다.
4. config/schema.ts - 런타임 검증
export const BuiltinCommandNameSchema = z.enum([
"init-deep",
"start-work",
"subagents", // ← 추가
])
사용자 설정 파일의 유효성을 런타임에 검증합니다.
핵심 인사이트: AI를 자연어로 프로그래밍하기
이번 기여에서 가장 흥미로웠던 점은 **"AI를 자연어로 프로그래밍한다"**는 개념입니다.
전통적 코드 vs 템플릿 기반
전통적 코드: 템플릿 기반:
───────────────── ───────────────
if (input === "2") { "When user enters a number,
showModels(2); show available models for
} that subagent"
AI가 실행자가 된다
AI는 단순히 질문에 답하는 것이 아니라, 템플릿에 정의된 프로그램을 실행합니다:
┌─────────────────────────────────────────────────────────────────────────┐
│ USER OPENCODE AI │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ /subagents 입력 │
│ ───────────► │
│ "subagents" 조회 │
│ commands.ts에서 │
│ │ │
│ ▼ │
│ 템플릿 찾음 │
│ 프롬프트에 주입 │
│ │ │
│ ▼ │
│ AI에게 전송 ────────► 템플릿 수신 │
│ │
│ 지침 해석: │
│ "Step 0: 사용 가능한 │
│ 모델 확인하기" │
│ │ │
│ ▼ │
│ 설정 파일 읽기: │
│ - opencode.yaml │
│ - oh-my-opencode.json │
│ │ │
│ ▼ │
│ TUI 표시: ◄──────────────────── Step 1 표시: │
│ ╭─────────────────────╮ "현재 서브에이전트..." │
│ │ 🤖 Subagent Config │ │
│ │ 1. Sisyphus │ │
│ │ 2. oracle │ │
│ ╰─────────────────────╯ │
│ │
│ 2 입력 │
│ ───────────────────────────────────► "2" 확인 │
│ Step 2 실행: │
│ "#2의 모델 표시" │
│ │ │
│ ▼ │
│ 모델 목록 표시: ◄──────────────────── 모델 표시 │
│ ╭─────────────────────╮ │
│ │ Models for: oracle │ │
│ │ 1. claude-opus-4-5 │ │
│ │ 2. gpt-5.1 │ │
│ ╰─────────────────────╯ │
│ │
│ 1 입력 │
│ ───────────────────────────────────► "1" 확인 │
│ Step 3 실행: │
│ "설정 파일 업데이트" │
│ │ │
│ ▼ │
│ 파일 쓰기: │
│ oh-my-opencode.json │
│ │ │
│ 완료 토스트: ◄──────────────────── 성공 메시지 표시 │
│ ╭─────────────────────╮ │
│ │ ✅ oracle 업데이트! │ │
│ ╰─────────────────────╯ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
오픈소스 기여의 가치
개발자로서 얻은 것
- 프롬프트 엔지니어링 깊은 이해 - AI를 프로그래밍하는 새로운 패러다임
- 실제 프로덕션 코드 경험 - 많은 사용자가 쓰는 도구에 기여
- 코드 리뷰 학습 - 메인테이너들의 피드백을 통한 성장
Quokka Labs가 오픈소스에 기여하는 이유
저희 Quokka Labs는 단순히 기술 서비스를 제공하는 것을 넘어, 기술 생태계에 기여하는 것을 중요하게 생각합니다.
- 실력 증명: 블로그 글만으로는 보여줄 수 없는 실제 구현 능력
- 최신 기술 선도: AI 코딩 도구의 최전선에서 직접 개발
- 커뮤니티와 함께 성장: 사용하기만 하는 것이 아니라 돌려주는 것
마무리
/subagents 명령어는 작은 기능일 수 있지만, AI 에이전트의 템플릿 기반 아키텍처를 이해하고 실제로 기여하는 과정은 매우 의미 있는 경험이었습니다.
만약 여러분도 오픈소스 기여에 관심이 있다면, oh-my-opencode같은 프로젝트는 좋은 시작점이 될 수 있습니다. 코드를 작성하지 않더라도, 프롬프트 템플릿을 개선하는 것만으로도 훌륭한 기여가 됩니다.
관련 링크:- 🔗 /subagents PR #710 - 이 포스팅에서 다룬 실제 기여 PR
- 🎬 OpenCode & oh-my-opencode 소개 영상 (YouTube)
- oh-my-opencode GitHub
- OpenCode 공식 사이트
요약
| 구성 요소 | 역할 |
|---|---|
템플릿 (subagents.ts) | AI를 위한 지침 - "무엇을 해야 하는지" |
레지스트리 (commands.ts) | /subagents → 템플릿 매핑 |
타입 (types.ts) | TypeScript 컴파일 타임 안전성 |
스키마 (schema.ts) | 런타임 설정 검증 |
| AI | 템플릿 지침 실행 |
| 설정 파일 | 사용자의 모델 선호도 저장 |
핵심은 자연어로 AI를 프로그래밍하고, AI가 복잡한 부분(파일 I/O, JSON 파싱, 사용자 상호작용)을 모두 처리한다는 것입니다.







