작업을 의뢰하기 전에 목소리를 오디션하세요
요약
AI 에이전트가 생성할 글의 목소리(어조, 어휘, 정체성)를 작업 시작 전 미리 검증하는 '오디션' 워크플로우를 소개합니다. 로컬 모델과 엄격한 스키마를 활용해 비용을 최소화하면서도 재현 가능한 튜닝 루프를 구축하는 방법을 다룹니다.
핵심 포인트
- 재현성을 위해 도구 없이 인라인 컨텍스트만 사용하는 에이전트 설계
- 비용 절감을 위해 스타일 검증에는 빠르고 저렴한 로컬 모델 활용
- 엄격한 출력 스키마를 통해 메타 코멘터리 없는 순수 샘플 생성 강제
- 상태를 남기지 않는 휘발성 구조로 효율적인 튜닝 루프 구현
원문은 olund.dev에서 처음 게시되었습니다.
제 툴링(tooling)의 일부는 설정된 목소리(voice)로 긴 형식의 글 콘텐츠를 생성합니다. 여기서 목소리란 독자, 어조(register), 어휘, 그리고 작가가 어떻게 들리는지를 설명하는 편집적 정체성(editorial identity)을 의미합니다. 이 정체성은 설정(config) 안에 담긴 산문(prose)입니다. 그리고 톤(tone)을 위한 산문 설정에는 고약한 특성이 하나 있습니다. 바로 '쓰기 전용(write-only)'이라는 점입니다. 당신이 원하는 목소리를 설명하면(
- 도구 없음 (No tools). 에이전트는 파일을 읽거나, 브라우징하거나, 검색할 수 없습니다. 에이전트에게 필요한 모든 것(정체성 텍스트와 선택적 주제)은 디스패치(dispatch) 시 인라인(inline)으로 전달됩니다. 이는 단순한 비용 제어가 아닙니다. 도구가 없고 컨텍스트가 완전히 인라인인 에이전트는 _재현 가능(reproducible)_합니다. 동일한 입력에 대해 동일한 부류의 출력이 나오며, 주변 환경에 의해 결과가 드리프트(drift)될 요소가 없습니다.
- 빠른 로컬 모델 (A fast local model). 레지스터(register, 말투의 격식)를 오디션하는 것은 좁은 범위의 작업입니다. 이는 추론의 깊이가 아니라 스타일 설명에 대한 충실도가 필요합니다. 호출은 제 워커 런타임(worker runtime)에서 가장 저렴한 티어로 라우팅됩니다. 즉, 제 개인 장비에서 실행되는 작은 모델입니다. 측정된 오디션은 엔드 투 엔드(end to end)로 약 500 토큰이 소요되며, 로컬 하드웨어에서는 비용이 거의 제로에 가깝습니다.
- 엄격한 출력 스키마 (A hard output schema). 에이전트는 반드시 2개에서 6개의 샘플 라인을 반환해야 하며, 각 라인은 해당 목소리가 실제로 말할 법한 한두 문장이어야 합니다. 그 외의 것(헤딩, 무대 지시문, 목소리에 대한 해설 등)은 포함될 수 없습니다. 스키마는 호출 레이어(call layer)에서 강제되므로, 형식이 잘못된 응답은 UI에 도달하기 전에 재시도됩니다. 미리보기는 채팅이 아니라 계약(contract)입니다.
- 구조적으로 휘발성임 (Ephemeral by construction). 이를 서비스하는 경로는 아무것도 기록하지 않습니다. 데이터베이스 행, 아티팩트(artifact), 히스토리 모두 남기지 않습니다. 지속되는 미리보기 출력은 상태(state)가 되어 목록화, 마이그레이션, 정리의 대상이 됩니다. 미리보기의 진정한 가치는 그것이 증발한다는 점에 있습니다.
- 타임아웃과 단 한 번의 재시도. 90초의 제한 시간, 한 번의 복구 시도, 그 후에는 눈에 보이게 실패합니다. 멈춰 있는 미리보기는 에러가 발생하는 미리보기보다 더 나쁩니다.
프롬프트 측면은 세 가지 방식으로 반복되는 하나의 규칙입니다: 정체성의 톤(tone), 레지스터(register), 어휘(vocabulary)를 정확하게 일치시킬 것; 각 라인은 그 자체로 말할 수 있는 산문 형태의 라인이어야 할 것; 메타 코멘터리(meta-commentary)를 수행하지 말 것. 목소리가 '되는' 대신 목소리를 '설명하는' 샘플 라인은 실패 사례이며, 지침은 이를 직접적으로 타격합니다.
이것이 만들어내는 루프
설정 UI의 정체성 편집기(identity editor) 옆에는 샘플 버튼이 있습니다. 선택 사항인 주제를 입력하고 클릭하면, 잠시 후 설정된 목소리로 몇 줄의 문장이 생성됩니다. 정체성을 편집하고 다시 샘플링해 보세요. 튜닝 루프(tuning loop)가 "전체 결과물을 생성하고, 읽어보고, 움찔하는" 방식에서 반복당 몇 초 단위로 단축됩니다.
두 가지 UI 결정은 보기보다 더 큰 비중을 차지합니다.
미리보기(preview)는 아무것도 무효화하지 않습니다. 이는 상태를 변경하지 않으므로 캐시 업데이트가 없는 단순한 fire-and-return 호출입니다. 미리보기를 마치 뮤테이션(mutation)인 것처럼 앱의 데이터 레이어(data layer)에 연결하는 것은, 모든 미리보기에 리페치(refetch) 비용을 발생시키는 범주 오류(category error)입니다.
빈 상태(empty state)는 가르침을 줍니다. 정체성이 구성되지 않은 상태에서 버튼은 조용히 비활성화되지 않습니다. 엔드포인트(endpoint)는 "정체성이 설정되지 않았습니다"라며 거부하고, UI는 이를 사용자에게 알립니다. 전제 조건이 보이지 않는 미리보기 기능은 고장 난 것으로 간주됩니다.
그 아래에는 설계(seam)에 대한 결정도 있습니다. 경로는 클라이언트가 폴링(polling)해야 하는 작업 ID(job id)를 반환하는 대신, 2분으로 제한된 상태에서 워커(worker)를 동기식(synchronously)으로 기다립니다. 미리보기는 상호작용적(interactive)입니다. 사용자가 그 자리에 앉아 있기 때문입니다. 미리보기에 진행 표시줄(progress bar)이 필요한 순간, 그것은 이미 미리보기로서 실패한 것이므로, API 구조는 지연 시간 예산(latency budget)을 인코딩합니다. 사용자가 지켜보는 동안 응답할 수 없다면, 상태 업데이트를 스트리밍하는 것이 아니라 에러를 발생시켜야 합니다.
이것이 기능이 아니라 패턴인 이유
일반적인 형태는 다음과 같습니다: 시스템이 인간이 작성한 설명을 소비하여 비용이 많이 드는 무언가를 생성할 때, 그 둘 사이에 가능한 한 가장 저렴한 샘플러(sampler)를 삽입하십시오. 설명과 출력 사이의 간극은 확신이 조용히 사라지는 지점입니다. 당신은 설정을 작성했고, 그것이 당신의 의도대로 작동한다고 생각하지만, 제공되는 유일한 검증 방법은 전체 실행 비용을 치러야 하기 때문입니다.
샘플러는 다음과 같을 때 그 가치를 인정받습니다:
- 반사적으로 반응할 수 있을 만큼 충분히 빨라야 합니다 (Instant enough to be reflexive). 분 단위가 아닌 초 단위여야 합니다. 샘플링을 하는 순간, 이것이 실행할 가치가 있는지 고민해야 한다면 반복 작업(Iteration)은 중단됩니다.
- 죄책감이 들지 않을 만큼 충분히 저렴해야 합니다 (Free enough to be guiltless). 로컬 모델(Local model)이나 가장 저렴한 API 티어를 사용하세요. 작업은 설계 단계부터 좁게 정의되어 있습니다. 해당 작업을 수행할 수 있는 가장 좁은 범위의 작업자(Worker)를 사용하십시오.
- 정직할 수 있을 만큼 충분히 제약되어야 합니다 (Constrained enough to be honest). 대상 형식에 맞춘 스키마 강제 출력(Schema-forced output)이 필요합니다. 자신이 무엇을 할 것인지에 대해 에세이를 써 내려가는 샘플러는 연극에 불과합니다.
- 무시해도 될 만큼 충분히 상태가 없어야 합니다 (Stateless enough to be ignorable). 영속성(Persistence), 이력(History), 정리(Cleanup)가 필요 없어야 합니다. 마흔 번을 실행하더라도 아무것도 축적되지 않아야 합니다.
이제 저는 산문 설정(Prose config)이 생성을 주도할 때마다 이 형태를 활용합니다:
작품을 만들기 전에 페르소나(Persona)를 샘플링하고, 배치(Batch)를 돌리기 전에 요약 스타일을 샘플링하며,
리뷰 실행 전에 리뷰어의 엄격함을 샘플링합니다. 각 샘플러는 반나절 정도의 작업량입니다. 왜냐하면 뺄셈(Subtraction)은 구축하기 빠르기 때문입니다. 에이전트(Agent) 정의 전체가 화면 하나에 들어오며, 그것이 구동되는 작업자 런타임(Worker runtime)은 이미 존재하기 때문입니다.
그 밑바탕에 깔린 조용한 교훈은 모델 라우팅(Model routing)에 관한 것입니다. 본능적으로는 사용 가능한 가장 강력한 모델에 모든 작업을 보내고 싶어 합니다. 하지만 미리보기(Preview)의 역할은 최대치(Maximal)를 보여주는 것이 아니라, _대표적이고 즉각적(Representative and immediate)_이어야 합니다. 엄격한 스키마와 인라인 컨텍스트(Inline context)를 가진 작은 로컬 모델이, 더 많은 자유도를 가지고 즉흥적으로 연주하는 프런티어 모델(Frontier model)보다 "설정된 목소리가 실제로 어떻게 들릴 것인가"를 더 잘 대표합니다. 작업의 협소함에 맞춰 작업자를 매칭하십시오. 그러면 어떤 작업들은 거의 비용이 들지 않는 것처럼 느껴질 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기