AI에게 "알아서 다 해줘"는 사고의 시작. 일을 맡기는 '발판' 만드는 법
AI 에이전트가 폭주하지 않는 이유는 모델의 똑똑함이 아니라 '하네스(발판)'. 복붙으로 돌아가는 최소 예제부터 안전하게 맡기는 요령까지 쉽게 풀어드립니다.
“이 저장소, 보기 좋게 좀 정리해줘.”
그렇게 부탁한 다음 날 아침, AI는 ‘보기 좋게’ 40개 파일을 갈아엎어 놨습니다. 돌아가는 코드도 멀쩡히 있었어요. 그런데 지우면 큰일 나는 설정 파일까지, 깔끔하게 싹 ‘정리’되어 있었습니다.
가슴이 철렁했던 경험, 없으신가요.
똑똑할 줄 알았던 AI가 왜 태연하게 사고를 칠까요. 이유는 간단합니다. ‘똑똑한 것’과 ‘안전하게 일하는 것’은 완전히 다른 문제거든요. 시험은 만점인데 첫 알바 날 계산대를 부숴 먹는 신입. 딱 그겁니다. 능력의 문제가 아니라 발판의 문제예요.
그 발판을 요즘은 하네스(harness) 라고 부릅니다. 오늘은 이걸 전문 용어를 최대한 안 쓰고 풀어볼게요.
하네스가 결국 뭔데?
하네스는 AI의 ‘바깥쪽’에 두는 작은 프로그램입니다.
떠올리기 쉬운 건 공사 현장의 안전벨트(생명줄), 아니면 아이용 자전거의 보조 바퀴예요. 본인의 능력은 그대로 두되, 떨어지지 않게 잡아주는 장치를 말합니다. AI로 치면 이런 역할을 합니다.
- 무엇을 읽힐지 정한다 (전부 보여주지 않는다)
- 무엇을 만들게 할지 정한다 (목표를 분명히 한다)
- 어디까지 알아서 하게 두고, 어디서 사람에게 확인받을지 정한다
- 완성된 결과물이 망가지지 않았는지 기계적으로 점검한다
‘좋은 프롬프트를 쓰는 것’은 이 중에 아주 일부일 뿐입니다. 프롬프트만 갈고닦아도 사고가 안 줄어드는 건, 보조 바퀴 없이 외발자전거를 연습하는 것과 같아서예요.
왜 지금 새삼 주목받을까
얼마 전까지만 해도 AI한테 부탁하는 일이라고는 “글 써줘” “코드 짜줘” 정도였습니다. 나온 걸 사람이 읽고 판단하면 그만이었죠.
그런데 지금은 AI에게 작업 그 자체를 맡기기 시작했습니다. 파일을 읽고, 기존 글과 안 겹치는 소재를 고르고, 변경점을 확인하고, 외부 서비스에 등록하고, 실패하면 원인을 보고하고 — 여기까지 오면 중간에 사람이 매번 끼어들지 않습니다. 그래서 ‘알아서 하다가 사고 난다’는 위험이 단번에 커진 거예요.
Claude Code가 평이 좋은 것도 모델이 똑똑해서라기보다, 이 발판이 잘 만들어져 있어서입니다. 파일을 읽는 도구, 검색하는 도구, 위험한 조작을 멈추는 장치, 프로젝트 규칙을 기억시키는 장치. 그런 ‘수수한 주변부’가 탄탄해요. 유행하는 건 마법 같은 프롬프트가 아니라, 바로 그 수수한 주변부입니다.
일단 돌려보기: 30줄짜리 최소 하네스
설명보다 직접 돌려보는 게 빠릅니다. AI에게 ‘읽기·쓰기’만 허락하고, 정해둔 폴더 바깥은 절대 못 건드리게 하는, 최소한의 발판을 만들어 봅시다. Node.js와 Anthropic의 API 키만 있으면 돌아갑니다.
먼저 준비합니다.
mkdir harness-demo && cd harness-demo
npm init -y
npm install @anthropic-ai/sdk
mkdir sandbox
echo "# 메모" > sandbox/note.md
다음으로 ‘허용 목록’을 씁니다. 이게 하네스의 심장부예요. sandbox 바깥은 못 건드리게 한다는 선언입니다.
{
"workspace": "./sandbox",
"maxSteps": 6
}
그리고 본체(harness.mjs). 기억해야 할 건 딱 한 군데뿐입니다. safePath 가 ‘폴더 바깥으로 나가려 하면 멈추는’ 문지기예요. 이게 있는 것만으로 첫머리의 ‘40개 파일 사고’는 일어나지 않습니다.
import Anthropic from "@anthropic-ai/sdk";
import { readFile, writeFile } from "node:fs/promises";
import path from "node:path";
const client = new Anthropic();
const policy = JSON.parse(await readFile(new URL("./policy.json", import.meta.url), "utf8"));
const root = path.resolve(policy.workspace);
// 문지기: 작업 폴더 바깥으로 나가려 하면 그 자리에서 멈춘다
function safePath(p) {
const resolved = path.resolve(root, p);
if (resolved !== root && !resolved.startsWith(root + path.sep)) {
throw new Error(`${p} 는 작업 폴더 바깥입니다. sandbox 안에서만 건드릴 수 있어요.`);
}
return resolved;
}
const tools = [
{ name: "read_file", description: "sandbox 안의 텍스트를 읽는다",
input_schema: { type: "object", properties: { path: { type: "string" } }, required: ["path"] } },
{ name: "write_file", description: "sandbox 안에 텍스트를 쓴다",
input_schema: { type: "object", properties: { path: { type: "string" }, content: { type: "string" } }, required: ["path", "content"] } },
];
async function useTool(name, input) {
if (name === "read_file") return await readFile(safePath(input.path), "utf8");
if (name === "write_file") { await writeFile(safePath(input.path), input.content, "utf8"); return "쓰기 완료"; }
throw new Error(`모르는 도구: ${name}`);
}
const messages = [{ role: "user", content: process.argv.slice(2).join(" ") || "note.md 를 읽고, 요약을 summary.md 에 써줘." }];
for (let step = 0; step < policy.maxSteps; step++) {
const res = await client.messages.create({
model: process.env.ANTHROPIC_MODEL || "claude-sonnet-4-6",
max_tokens: 1024,
tools,
system: "당신은 신중한 파일 담당자입니다. 꼭 필요할 때만 도구를 쓰고, 작업은 sandbox 안으로 한정합니다.",
messages,
});
messages.push({ role: "assistant", content: res.content });
const calls = res.content.filter((b) => b.type === "tool_use");
if (calls.length === 0) { console.log(res.content.find((b) => b.type === "text")?.text ?? ""); break; }
const results = [];
for (const c of calls) {
try { results.push({ type: "tool_result", tool_use_id: c.id, content: String(await useTool(c.name, c.input)).slice(0, 4000) }); }
catch (e) { results.push({ type: "tool_result", tool_use_id: c.id, is_error: true, content: e.message }); }
}
messages.push({ role: "user", content: results });
}
실행은 이게 전부입니다.
node harness.mjs
고작 수십 줄이지만, 벌써 ‘AI 본체’ ‘쓸 수 있는 도구’ ‘허용 범위’ ‘다시 시도 횟수 상한’ ‘망가지면 멈추는 장치’가 나뉘어 있습니다. 이게 하네스의 골격이에요. 여기에 검색·테스트 실행·승인 대기·알림을 더해가면, Claude Code 같은 형태로 자라납니다.
이런 장면에서 효과를 본다 (3가지)
1. 글이나 자료의 ‘양산 점검’ “블로그 써줘”로 끝내면 AI는 태연하게 얄팍한 글이나 ‘거의 같은 소재’를 양산합니다. 그래서 하네스에 “기존 제목을 읽는다 → 안 겹치는 관점을 고른다 → 본문을 쓴다 → 글자 수와 링크를 기계 점검한다”라는 단계를 쥐여줍니다. 그러면 결과물이 좋은지 나쁜지 사람이 고민하기도 전에, 문지기가 얄팍한 글을 걸러줍니다. 저는 이걸로 공개 전에 멈추는 초고가 한 달에 몇 편씩 나오게 됐어요. 멈춰줘서 고맙다, 하는 기분입니다.
2. 문의 분류 “들어온 문의를 읽고, 상담으로 이어질 만한 것만 알려줘.” 읽는 건 자동으로 해도 됩니다. 그런데 고객 리스트 등록은 사람이 버튼을 누를 때까지 보류예요. 이걸 하네스로 강제합니다. 읽기는 자동, 쓰기는 초안(dry-run), 최종 등록만 사람. 잘못 분류한 손님을 운영 데이터베이스에 멋대로 집어넣는 사고가 이걸로 사라집니다.
3. 배포 전 숨 한 번 공개 버튼을 누르기 전에, 빌드가 통과하는지·환경 변수가 갖춰졌는지·차이가 예상대로인지·되돌릴 절차가 있는지를 반드시 확인하게 합니다. AI는 실패 로그의 ‘마지막 줄’만 보고 엉뚱한 데를 고치기 일쑤라서, ‘어디를 볼지’를 먼저 정해두는 게 요령입니다. 로그는 전부 넘기지 말고 관련된 수십 줄로 좁힙니다. 이것만으로도 엉뚱한 수정이 확 줄어요.
Claude Code에서 ‘훔쳐올’ 수 있는 3가지 설계
직접 하네스를 만들 때 처음부터 다 짜낼 필요는 없습니다. Claude Code는 본보기의 보고예요. 전부 따라 할 필요는 없으니, 다음 3가지만 일찍 들여오면 단숨에 안정됩니다.
첫째는 규칙을 계층으로 나누는 것. 매번 안 변하는 약속은 설정 파일로, 이번에만 쓰는 지시는 그 자리 메모로, 오래 쓰는 취향은 또 다른 곳으로. 전부 매번 프롬프트에 적으면 길어지고 정확도가 떨어집니다.
둘째는 확정적인 작업은 명령어에 맡기는 것. 정리·점검·테스트는 AI한테 부탁하기보다 npm test 같은 명령어로 돌리는 편이 빠르고 확실합니다. AI한테는 ‘생각하는’ 일만 남겨요.
셋째는 무거운 조사는 다른 담당에게 떠넘기는 것. 긴 로그나 대량의 파일 읽기를 메인 대화에 흘려보내면, 정작 중요한 판단이 흐려집니다. 사전 조사는 별도 프로세스에 시키고 결론만 받는다. 이것만으로 판단의 날이 되살아납니다.
내가 저지른 실패 3가지
솔직하게 적습니다. 첫 하네스는 사고투성이였어요.
첫째는 도구를 너무 많이 쥐여준 것. 편하겠지 싶어 30개쯤 준비했더니, AI가 “어느 걸 써야 하지?” 하고 헤매다가 이상한 선택을 연발했습니다. 지금은 처음엔 5~10개로 좁힙니다.
둘째는 에러 메시지가 불친절했던 것. Error: failed 라고만 돌려줬더니 AI는 아무것도 못 고칩니다. README.md 를 찾을 수 없습니다. sandbox 에는 note.md 만 있어요 처럼 원인과 다음 한 수까지 적어 돌려줬더니, 갑자기 스스로 해결하기 시작했어요.
셋째는 확인을 사람 눈에만 기댄 것. “마지막에 내가 체크하면 되지”는 바쁜 날에 반드시 무너집니다. 글자 수·링크 깨짐·타입 오류처럼 기계가 알 수 있는 문지기를 둔 뒤로는, 한밤중 확인이 부쩍 줄었어요.
시작한다면, 여기서부터
다짜고짜 ‘완전 자동의 똑똑한 에이전트’를 만들지 마세요. 실패해도 되돌릴 수 있는, 작은 일 하나를 고릅니다. 초고 점검, PR 1차 리뷰, 문의 분류, 스테이징 공개 전 확인. 이 정도가 딱 알맞아요.
순서는 늘 같습니다. ① 읽힐 범위를 좁게 정한다 → ② 목표(결과물)를 분명히 한다 → ③ 확인은 되도록 명령어에 시킨다 → ④ 위험한 조작(삭제·운영 DB·결제·force push)은 처음엔 전부 “사람에게 묻기”로 둔다. 안전하다고 확인된 조작만 나중에 자동으로 승격합니다. 이 순서만 지켜도 사고는 놀랄 만큼 줄어요.
권한 정하는 법은 Claude Code 권한 설정 가이드에, 팀에서 쓸 때의 토대 만들기는 CLAUDE.md 베스트 프랙티스에 정리해 뒀습니다. 긴 작업을 나누고 싶다면 서브에이전트 활용 패턴도 함께 보세요. 공식 사고방식은 Claude Agent SDK 문서가 1차 정보입니다.
실제로 해본 결과
첫머리의 ‘40개 파일 사고’ 이후로, 저는 ‘AI를 믿느냐 마느냐’로 고민하기를 그만뒀습니다. 대신 보는 건 어느 문지기에서 멈췄나예요. 최소 하네스에 safePath 하나를 더했을 뿐인데, 폴더 바깥 사고는 0이 됐습니다. 글자 수와 링크 자동 점검을 더했더니, 얄팍한 글이 공개 전에 멈추게 됐어요. 똑똑한 AI를 찾기보다, 넘어져도 안 다치는 발판을 먼저 만든다. 돌아가는 길처럼 보여도 이게 가장 빠르다는 게 지금의 실감입니다.
정리
하네스 엔지니어링은 프롬프트를 꾸미는 기술이 아닙니다. AI에게 무엇을 보여주고, 무엇을 시키고, 어디서 멈추고, 어떻게 확인할지를 설계하는 기술입니다. 우선 위의 30줄을 돌려보고, 자기 일에 ‘문지기’를 하나 더하는 것부터 시작해 보세요. AI가 하는 일의 질은 모델의 똑똑함보다, 그 바깥쪽 발판이 결정합니다.
좀 더 체계적으로 자기 업무에 AI를 안전하게 끼워 넣고 싶은 분은 교재·템플릿 목록을, 팀 전체로 권한·리뷰·검증까지 갖추고 싶은 분은 연수·도입 상담을 들여다봐 주세요.
무료 PDF: Claude Code 치트시트
이메일을 입력하면 명령, 리뷰 습관, 안전한 워크플로를 정리한 PDF를 받을 수 있습니다.
개인정보를 안전하게 관리하며 스팸을 보내지 않습니다.
작성자 소개
Masa
Claude Code 실무 워크플로와 팀 도입을 검증하는 엔지니어입니다.
관련 글
Claude Code에게 파일 하나만 고치게 하는 지시문 작성법
'더 좋게 만들어줘'로 40줄이 바뀐 실패에서 배운, 수정 범위·검증·되돌리기를 묶은 Claude Code용 요청문 템플릿을 소개합니다.
Claude Code 권한 거절에서 복구하기: guardrail 을 약하게 만들지 않는 법
거절된 Claude Code 명령을 이유, 안전한 대안, 증거 명령, 재시도 조건으로 나누는 복구 workflow.
Claude Code Harness Smoke Test: 에이전트를 믿기 전 15분 검증 루프
Claude Code 작업 전에 범위, 금지 영역, 증거 명령, 공개 URL, 수익 CTA를 확인하는 실무 체크입니다.