"채팅"을 넘어: 스킬과 사양 엔지니어링(Specification Engineering)으로 지능을 설계하기
요약
단순한 채팅 방식의 프롬프팅을 넘어, XML 태깅과 구조화를 통해 LLM을 설정(Configuring)하는 컨텍스트 엔지니어링의 중요성을 다룹니다. 지침과 데이터를 분리하고 예시(Few-shot)를 활용하여 모델의 안정성과 확장성을 확보하는 방법을 제시합니다.
핵심 포인트
- 메가 프롬프트의 한계: 거대한 단일 프롬프트는 관리와 확장이 어려움
- 컨텍스트 엔지니어링: 지침(로직)과 데이터(컨텍스트)의 엄격한 분리 필요
- XML 태깅 활용: 태그를 통해 모델에게 명확한 구조와 경계 제공
- Few-Shot 패턴: 좋은 예시와 나쁜 예시를 제공하여 행동 제어
우리가 모든 CSS와 JavaScript를 단 하나의 index.html 파일에 쏟아붓던 시절을 기억하시나요? 오늘날의 "메가 프롬프트(Mega-Prompt)"가 바로 그것입니다. 즉, 관리 불가능한 모놀리스(Monolith)입니다.
몇 주 전, 저의 로컬 AI 에이전트인 Vibrisse Agent의 오케스트레이션(Orchestration) 작업을 하던 중 정확히 이 벽에 부딪혔습니다. 저는 500줄에 달하는 시스템 프롬프트(System Prompt)에 지침을 추가하여 복잡한 작업을 안정화하려 노력하고 있었습니다. 하지만 규칙을 더 많이 추가할수록, 모델은 이전의 규칙들을 더 많이 잊어버렸습니다.
업계는 우리에게 메가 프롬프트라는 신화를 팔아왔습니다. 그 유명한 "최고의 프롬프트 50가지"나 거대한 주문 같은 텍스트 블록들은 기술적인 막다른 길입니다. 창의적인 글쓰기는 프로덕션(Production) 환경에서 확장(Scale)될 수 없습니다.
웹 개발자로서 저의 신념은 간단합니다. 신뢰할 수 있는 애플리케이션을 구축하려면, 기계에게 "말을 거는" 것을 멈추고 기계를 **설정(Configuring)**하기 시작해야 합니다. 이것이 프롬프트 엔지니어링(Prompt Engineering)에서 **컨텍스트 엔지니어링(Context Engineering)**으로의 전환입니다.
컨텍스트 엔지니어링: 타이핑(Typing)과 구조
LLM(Large Language Models)을 다룰 때 저지르는 첫 번째 실수는 지침(로직)과 컨텍스트(데이터)를 구조화되지 않은 텍스트 스트림으로 섞어버리는 것입니다. 이는 인지적으로 스파게티 코드(Spaghetti Code)와 같습니다.
해결책은 무엇일까요? 바로 관심사의 엄격한 분리(Separation of Concerns)입니다. 매우 효과적인 기술(Anthropic에서 문서화되었지만, 로컬 SLM을 포함한 모든 모델에 적용 가능함)은 바로 **XML 태깅(XML Tagging)**입니다.
다음은 "지저분한" 방식(전형적인 채팅)입니다:
당신은 보안 전문가입니다. 이 인증 코드를 분석하세요. 엄격하게 처리하고, 요약하지 마세요. XSS 및 SQLi 취약점을 점검하세요. 여기 코드가 있습니다: function login() { ... }
그리고 이것은 "엔지니어링" 방식입니다:
<role>애플리케이션 보안 전문가</role>
<instructions>
...
태그를 통해 언어를 타이핑(Typing)하면 명확한 경계가 생성됩니다. 모델은 지시 사항이 어디에 있고 데이터가 어디에 있는지 정확히 알게 됩니다.
예시의 힘 (Few-Shot Prompting)
명확한 지침이 있더라도 AI는 출력 형식이나 어조에서 벗어날 수 있습니다. 이 지점에서 예시(exemplars)를 통한 관리가 중요해집니다.
AI에게 기대되는 행동의 구체적인 예시(Good Example, 좋은 예시)와 피해야 할 행동(Bad Example, 나쁜 예시)을 제공하는 것은 15줄의 이론적인 지침을 추가하는 것보다 훨씬 더 강력하고 토큰 효율적(token-efficient)인 경우가 많습니다.
단순히 XML 구조에 예시 섹션을 추가하기만 하면 됩니다:
<examples>
<example>
<input>Review of Button.tsx component</input>
...
이 "Good vs Bad + Explanation(좋은 예시 vs 나쁜 예시 + 설명)" 패턴은 행동적 안전장치(behavioral safeguard) 역할을 합니다. 이는 Edge AI에서 특히 중요합니다. 만약 브라우저에서 직접 소규모 3B 파라미터 모델을 실행한다면(예: window.ai와 @mlc-ai/web-llm을 사용하는 우리의 데모 모델 Vans), 모델의 추론 능력은 제한적입니다. XML few-shot(퓨샷)을 제공하는 것은 컨텍스트 윈도우(context window)를 과도하게 낭비하지 않으면서 결정론(determinism)을 강제할 수 있는 유일하고 신뢰할 수 있는 방법입니다:
// window.ai를 통한 Edge AI 호출 예시
const response = await window.ai.createTextSession().prompt(`
<instructions>Analyze the accessibility of this component according to WCAG standards.</instructions>
...
💡 장인의 팁 (The Craftsman's Tip): 프롬프트를 설정 파일(configuration file)처럼 취급하세요. 전체 컨텍스트가 200줄을 초과한다면, 그것은 더 이상 프롬프트가 아니라 모놀리스(monolith)입니다. 이제 이를 분해해야 할 때입니다.
절차적 기억 (Procedural Memory): "스킬 (Skills)"
여기서 **스킬 (Skill)**이라는 개념이 등장합니다. IBM 팀이 매우 잘 설명했듯이, 우리는 의미론적 기억(semantic memory, 주로 RAG를 통해 관리되는 사실들)과 절차적 기억(procedural memory, 방법론적인 것)을 구분해야 합니다.
LLM을 비행기 조종사라고 생각해보세요. 조종사는 본질적으로 비행하는 법(추론 능력)을 알고 있습니다. 하지만 이륙하기 전에, 추락하지 않기 위해 자신이 조종하는 항공기에 특화된 체크리스트(스킬)가 필요합니다. 세스나(Cessna) 조종사에게 보잉 747 매뉴얼을 건네주지는 않는 것과 같습니다.
에이전트의 모든 능력을 단일 프롬프트(prompt)에 로드하는 대신, 각 능력을 하나의 **스킬 (Skill)**로 캡슐화하는 것이 핵심 아이디어입니다. 현대적인 스킬은 더 이상 단순한 텍스트 파일이 아닙니다. 그것은 진정한 의미의 버전 관리가 가능한 "플러그인 (plugin)"입니다. 일반적으로 메인 지침 파일(SKILL.md 및 _agentskills.io_에서 밀고 있는 표준인 Front Matter 포함)을 포함하는 폴더 형태를 띠지만, 비즈니스 스크립트나 참조 예시를 포함할 수도 있습니다.
다음은 스킬의 중심이 되는 SKILL.md 파일의 전형적인 구조입니다:
---
name: obsidian-researcher
description: 사용자의 Obsidian 보관함에서 정보를 검색하기 위해 이 스킬을 실행합니다.
...
Front Matter의 tools 키에 주목하십시오. 이것은 사양 엔지니어링 (Specification Engineering)에서 가장 강력한 개념 중 하나인 **도구 범위 지정 (tool scoping)**입니다.
AI 에이전트에게 50개의 도구에 대한 전역적 접근 권한을 부여하는 대신(이는 공격 표면을 넓히고 모델의 주의력(attention)을 분산시킵니다), 이 특정 작업에 엄격하게 필요한 도구로만 무기고를 제한하는 것입니다. 스킬은 외부 MCP 서버, 로컬 Python 스크립트, 또는 단순한 URL로 연결되는 안전한 진입점이 됩니다.
이러한 점진적 공개 (Progressive Disclosure) 접근 방식(모델에 꼭 필요한 경우에만 정보를 공개하는 방식)은 로컬 AI에서 매우 중요합니다. Llama 3나 Gemma를 자체 하드웨어에서 실행할 때는 모든 토큰(token)이 중요합니다. 컨텍스트와 관련된 절차적 "두뇌"만을 로드하면 VRAM을 절약하고, 추론(inference) 속도를 높이며, 환각 (hallucination)을 획기적으로 줄일 수 있습니다.
좋은 스킬이란 인간 인턴에게 건네줄 수 있는 단계별 절차와 같습니다. 인간이 이해하지 못한다면, AI는 환각을 일으킬 것입니다.
오케스트레이션 (Orchestration) 및 전역 컨텍스트 (Global Context)
스킬이 온디맨드(on-demand) 방식의 절차적 메모리 역할을 하는 동안에도, 에이전트에게는 여전히 정체성과 전역 규칙이 필요합니다. 여기서 구조 파일(structure files)이 역할을 하게 됩니다:
AGENTS.md: 에이전트의 정체성(identity), 톤(tone), 그리고 범위를 정의합니다. 이것이 루트 컨텍스트가 됩니다.DESIGN.md: 절대적인 표준을 확립합니다. 예를 들어, 모든 스킬에서
1. 구조화된 출력 (Structured Output, JSON Schema) 및 함수 모델 (Function Models): 스킬은 반드시 API처럼 동작해야 합니다. 만약 AI가 "결과입니다: { ... }"라고 정중하게 응답한다면, 이는 당신의 파이프라인을 망가뜨립니다. 로컬 AI 환경에서는 프롬프트만으로는 충분하지 않습니다. 출력값이 당신의 스키마 (Schema)를 준수한다는 것을 수학적으로 보장하기 위해, Outlines, XGrammar, 또는 Ollama의 네이티브 JSON 모드 등을 통해 SLM (Small Language Model)의 생성을 제약해야 합니다. 이제 에이전트는 자유 텍스트를 생성하는 것이 아니라, 결정론적인 데이터 (Deterministic data)를 생성합니다.
나아가, 업계는 현재 함수 모델 (Function Models) (예: FunctionGemma 또는 Hermes 시리즈)의 사용으로 이동하고 있습니다. 이러한 모델들은 대화를 하기 위해서가 아니라, 파라미터 (Parameters)를 파싱하고, 도구를 호출하며, 유효한 JSON을 반환하도록 특화되어 훈련되었습니다. 이는 논리적인 진화입니다. 언어 모델이 단순한 API 실행 엔진이 되는 것입니다.
예를 들어, 우리의 내러티브 RPG 엔진인 **GemMaster**에서는 이론적인 액션 스키마 대신, 다음과 같이 모델이 게임에서 기대하는 엄격한 형식으로 NPC를 생성하도록 강제합니다:
# GemMaster: NPC 생성을 위한 엄격한 JSON 응답 강제
schema = {
"type": "array",
...
2. 체계적 평가 (Systematic Evaluation, Evals): 스킬에 대한 풀 리퀘스트 (Pull Request)를 "직감"에 의존하여 승인해서는 안 됩니다. 에이전트를 평가하는 것은 그 자체로 하나의 전문 분야 (LLMOps)가 되었습니다. 행동 수정 사항은 머지 (Merge)되기 전에 반드시 회귀 테스트 (Regression tests)를 통과해야 합니다. promptfoo와 같은 도구를 사용하면 테스트 데이터셋을 대상으로 에이전트를 실행하고, 새로운 스킬이 엣지 케이스 (Edge cases)에서 성능이 저하되는지 여부를 평가 (Assert)할 수 있습니다.
이러한 엄격함이야말로 "마법 같은" 프로토타이핑과 산업적 수준의 프로덕션 배포를 구분 짓는 요소입니다.
결론 및 요약 (Conclusion & TL;DR)
웹 개발자로서 우리의 직업은 진화하고 있습니다. 우리는 고립된 함수를 더 적게 작성하고, 더 많은 행동 (Behaviors)을 설계하게 될 것입니다.
요약하자면:
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기