AI에게 규칙을 주는 것도 설계다
AI 코딩 도구를 쓰면서 가장 많이 듣는 불만이 뭔지 아시나요? "왜 AI가 내 규칙을 무시하죠?"입니다. Cursor의 .mdc 파일, Claude Code의 CLAUDE.md, GitHub Copilot의 copilot-instructions.md — 도구마다 컨텍스트 파일 형식이 다르고, 어떤 규칙은 따르고 어떤 규칙은 조용히 씹힙니다. 저도 이 문제에 한동안 시달렸는데, 최근 dev.to에 올라온 Ned의 실험 결과(What I Actually Put in My Project Context Files)가 정확히 이 지점을 데이터로 찍어줬습니다.
핵심 발견은 이렇습니다. .mdc 파일에서 YAML frontmatter가 깨지거나 아예 없으면 경고도, 에러도 없이 규칙이 로드되지 않습니다. 7가지 결함 케이스를 테스트한 결과, 'silent failure'를 일으키는 건 딱 두 가지 — malformed YAML과 missing frontmatter. 나머지 다섯 가지(alwaysApply 누락, 잘못된 glob 패턴 등)는 의외로 잘 동작했죠. 이걸 팀 차원에서 보면, AI에게 규칙을 주는 행위 자체가 하나의 설계 업무라는 뜻입니다. 컨텍스트 파일을 대충 쓰면 AI가 대충 일합니다.
더 흥미로운 건 규칙의 구체성이 길이보다 중요하다는 점입니다. 121KB짜리 .cursorrules 파일도 동작했지만, "적절한 에러 처리를 사용하라"는 모호한 규칙은 무시당했습니다. 반면 "async 라우트 핸들러를 try/catch로 감싸고, logger.error(err)로 로깅하고, status 500으로 { error: 'Internal server error' }를 반환하라"는 구체적 규칙은 Sonnet 4.5, Gemini 3 Flash, GPT-5.1 Codex Mini 세 모델 모두에서 9/9 준수율을 기록했습니다. 모델이 규칙을 안 따르는 게 아니라, 규칙이 모델에게 따를 수 있는 형태가 아닌 겁니다. 이건 팀원들에게 AI-First 마인드를 심어줄 때 가장 먼저 가르쳐야 할 포인트예요.
AI가 틀릴 때, 인간은 '감'이 아니라 '사양'으로 잡는다
컨텍스트를 잘 설계해서 AI에게 좋은 코드를 쓰게 하는 것, 그건 절반입니다. 나머지 절반은 AI가 틀릴 때 그걸 알아차리는 능력이죠. GlobalRemote라는 구직 플랫폼을 AI 코딩 에이전트로 거의 전부 구축한 Dalleyne의 사례(The Job Isn't Writing Code. It's Knowing When the AI Is Wrong.)가 이걸 세 가지 패턴으로 정리해줍니다.
첫째, "잘못된 도구로 올바르게 풀기" 패턴입니다. regex로 기술 스택을 추출하던 파이프라인에서 매칭 실패가 발생하자, AI는 regex 패턴 확장을 제안했습니다. 기술적으로는 맞지만, 이미 같은 파이프라인에 LLM이 붙어 있는데 왜 brittle한 regex를 고수하죠? AI 에이전트는 주어진 문제를 최적화하지, '이게 올바른 문제인지' 질문하지 않습니다. 둘째, "기술적으로 정확하지만 사용자에게 오해를 주는" 패턴. 미국·캐나다·프랑스 등 8개국 한정 채용 공고를 Americas와 Europe으로 태깅한 건 데이터 정합성 관점에선 맞지만, 브라질이나 헝가리 사용자에겐 거짓 신호입니다. 셋째, "성공으로 보고된 실패" 패턴. 39개 공고를 스크래핑했는데 신규 0건, 에러도 0건. 조용히 정상 종료했지만 실제로는 중복 제거 로직과 급여 파싱 버그가 유효한 데이터를 전부 드롭하고 있었습니다.
Dalleyne는 이 세 가지를 코드 리뷰가 아니라 "출력이 말이 되는지"에 대한 gut check로 잡았습니다. OpenAI가 말하는 'Harness Engineering' — 스펙, 테스트, 신뢰 경계, 검증 레이어 — 이 바로 이겁니다. AI가 프로덕션 코드를 쓰는 시대에 인간의 역할은 코드를 읽는 게 아니라 "이게 우리 사용자에게 실제로 의미가 있는지"를 판단하는 것으로 이동하고 있어요.
교차 검증과 자동화: '사람의 판단'을 루프에 끼우는 방법
여기서 한 발 더 나아간 사례가 두 개 있습니다. 하나는 Velog에 올라온 유니티 개발자의 AI 교차 검증 워크플로우입니다. 안티그래비티(Gemini 기반)로 설계 문서를 생성하고, 이를 Claude에 넘겨 리팩토링한 뒤, 다시 Codex로 코드 검증을 거칩니다. 단일 AI의 오차를 다른 AI의 시점으로 잡는 거죠. 글쓴이도 인정하듯 "쓸데없는 것을 바꾸거나 방어 코드만 추가"하는 경우도 있지만, 버그 자체를 잡아내는 실효성은 분명했습니다. 다만 이 과정을 수동으로 반복하는 건 비효율적이라 자동화를 고민 중이라고 하더군요.
다른 하나는 pytest 실패를 분석해 자동 수정을 제안하는 CLI 도구(I Built a CLI That Auto-Fixes Failing Python Tests)입니다. 테스트 실행 → 실패 패턴 분석 → diff 형태 수정 제안 → 사람의 승인/거부 → 재실행으로 회귀 확인. 핵심은 패턴 기반의 결정론적 엔진이 먼저 돌고, 복잡한 케이스에만 LLM 폴백을 쓴다는 설계입니다. 이 도구가 보여주는 원칙은 명확합니다 — 자동화는 '제안'까지, 최종 결정은 사람. 이게 AI-First 팀에서 자동화의 올바른 경계입니다.
시사점: AI-First 워크플로우의 세 가지 실전 규칙
네 가지 소스를 종합하면, AI-First 팀이 실제로 지켜야 할 규칙이 선명해집니다.
첫째, 컨텍스트 파일은 '설정'이 아니라 '설계'입니다. silent failure를 방지하려면 CI에 cursor-lint 같은 구조 검증을 넣고, 규칙은 모호하게 쓰지 말고 코드 수준으로 구체화해야 합니다. 팀 내에서 컨텍스트 파일의 코드 리뷰를 프로덕션 코드와 동일한 수준으로 올리세요.
둘째, AI의 출력을 '코드'가 아니라 '비즈니스 의미'로 검증합니다. line-by-line 코드 리뷰 대신, 출력이 사용자에게 올바른 의미를 전달하는지, 파이프라인이 조용히 실패하고 있진 않은지를 점검하는 'Harness Engineering' 역량이 팀의 핵심 스킬이 됩니다.
셋째, 자동화의 경계는 '제안'과 '결정' 사이에 긋습니다. 테스트 자동 수정 CLI든, AI 교차 검증이든, 최종 approve/reject은 사람이 합니다. 이 루프를 없애는 게 아니라 루프의 속도를 높이는 것이 AI-First 자동화의 정의입니다.
결국 AI-First는 "AI가 다 해준다"가 아닙니다. AI가 생성하고, 사람이 사양과 신뢰 경계를 설계하며, 그 사이에 검증 루프를 자동화하는 것 — 이 삼각구조를 팀 워크플로우에 제도화하는 게 진짜 AI-First 리빌딩입니다. 컨텍스트 파일 하나 제대로 못 쓰면서 AI-First를 외치는 건, 설계도 없이 건물 올리겠다는 것과 같습니다.