AI 코딩 에이전트를 쓰다 보면 이런 경험을 한 번쯤 한다. 분명히 원하는 걸 말했는데 엉뚱한 도구를 집어 든다. 이전 세션에서 결정한 내용을 까먹고 같은 제안을 반복한다. 어디선가 .env를 슬쩍 읽고 외부에 뭔가를 보낸다. 이 세 가지 실패 유형은 서로 다른 문제처럼 보이지만, 사실 하나의 공통 원인을 공유한다. 에이전트에게 충분한 구조를 주지 않았다는 것.
1층: 도구 설명은 마케팅 카피가 아니다
MCP(Model Context Protocol) 생태계가 확장되면서 에이전트가 동시에 수십 개의 도구를 바라보는 상황이 실제 프로덕션 환경이 됐다. 그런데 대부분의 도구 설명은 여전히 "Searches the web for information" 같은 한 줄짜리 선언에 머무른다. Dev.to에 올라온 실증 분석에 따르면, 이 상태에서 에이전트는 도구를 선택할 때 이름의 어감이나 파라미터 목록의 깔끔함에 의존한다. 정확성과는 무관한 기준이다.
해결책은 '안티-퍼포스(anti-purpose) 패턴'이다. 도구 설명에 "이 도구를 쓰면 안 되는 경우"를 명시하는 것. 예컨대 단순히 "웹을 검색한다"가 아니라, "최신 뉴스와 공개 웹 콘텐츠 검색에 사용. 코드 검색은 code_search, 내부 문서 검색은 docs_search를 사용할 것"처럼 쓰는 방식이다. 이 변경을 내부 도구 12개에 적용하는 데 걸린 시간은 30분. 그 결과 잘못된 도구 선택 오류가 약 50% 감소했다는 보고가 있다. 모델 교체도, 프롬프트 엔지니어링 투자도 없이.
논리적으로 보면 당연한 얘기다. 파라미터 설명이 "HOW(어떻게 호출하는가)"를 답한다면, 도구 설명은 "WHETHER(이 도구를 호출해야 하는가)"를 답해야 한다. 두 질문 모두 에이전트가 정확히 행동하기 위한 계약(contract)이고, 둘 다 load-bearing—즉 빠지면 구조가 무너지는 요소다. 지금까지 파라미터 설명은 그나마 챙겼지만, 도구 레벨의 명시적 배제 조건은 거의 아무도 안 썼다.
도구 설명을 작성하거나 감사할 때 체크해야 할 네 가지: 범위(Scope), 트리거(Trigger), 안티-트리거(Anti-trigger), 형제 도구 포인터(Sibling pointer). 도구가 두 개 이상 존재하는 순간, 이 네 가지는 전부 load-bearing이다.
2층: 세션은 매번 처음이 아니어야 한다
MCP 도구를 아무리 잘 설계해도, 에이전트가 매 세션마다 프로젝트의 현재 상태를 모른다면 시간이 낭비된다. "이미 결정한 거잖아요"를 다시 설명하는 데 세션 첫 15분을 쓰는 패턴, 익숙하지 않은가.
Dev.to에서 소개된 3-노트 시스템은 이 문제를 구조적으로 해결한다. 핵심은 세 개의 파일이다. 프로젝트 허브(Hub.md): 현재 상태, 스택, 핵심 파일 경로를 100줄 이내로 압축. 활성 제약 조건(Active Constraints.md): 코드만 봐서는 알 수 없는 비가시적 규칙들—배포 환경 제약, 법적 컴플라이언스, 번들 사이즈 제한, 이번 페이즈의 명시적 스코프 아웃 목록. 세션 상태(Session State.md): 직전 세션에서 내려진 결정과 그 이유, 열린 질문, 다음 세션의 정확한 시작 액션 한 문장.
이 구조의 핵심 가치는 두 가지다. Decisions Made 필드는 재논쟁을 차단한다. "Rejected: unified middleware—deploy cycle coupling, latency on every request"처럼 기록해두면 에이전트는 같은 제안을 반복하지 않는다. Open Questions 필드는 에이전트의 침묵하는 추론(silent gap-filling)을 막는다. 불확실한 것을 불확실한 채로 명시해야, 에이전트가 그럴듯한 추론으로 빈칸을 채우는 대신 질문을 던진다. 이 세 파일을 CLAUDE.md 같은 에이전트 진입점에 연결해두면, 세션 시작에 소요되는 시간이 15분에서 2분으로 단축된다는 실측 결과가 있다.
3층: 에이전트는 선의를 가졌지만 경계를 모른다
가장 조용하게 위험한 레이어가 보안이다. AI 코딩 에이전트로 인한 대부분의 보안 인시던트는 악의가 아니라 무지에서 비롯된다. 에이전트가 .env를 읽어버리거나, 존재하지 않는 패키지를 제안하거나(공격자가 이미 그 이름으로 등록해둔), CI 파이프라인을 "수정"하는 식으로. Cursor, Claude Code, Copilot, Windsurf를 실제로 써보며 이 패턴을 반복해서 목격한 개발자가 공개한 ai-repository-security-baseline은 이 문제를 10분 설정으로 해결하려는 시도다.
구조는 단순하다. 하나의 AGENTS.md에 규칙을 정의하고, 도구별 설정 파일(Cursor, Copilot, Cline, Aider, Devin 등)이 이를 참조한다. 레포에 파일을 드롭하고 플레이스홀더를 채운 뒤 커밋. 이 접근법은 '전면 금지'도 '전면 허용'도 아닌 중간 지점을 제안한다. 합리적인 기본값을 명시적으로 설계하는 것.
세 층위가 함께 작동할 때
이 세 가지—MCP 도구 설명의 정밀도, 세션 컨텍스트 구조화, 에이전트 보안 기준선—는 각각 독립적인 개선이지만, 함께 설계할 때 비로소 에이전트가 예측 가능하게 움직이는 환경이 만들어진다. 도구를 제대로 고르고, 이전 결정을 기억하며, 경계를 넘지 않는 에이전트. 이건 모델의 능력 문제가 아니다. 우리가 에이전트에게 제공하는 구조의 문제다.
프론트엔드 개발자 입장에서 가장 즉각적인 액션은 명확하다. 지금 사용하는 MCP 서버의 도구 설명을 열어보라. "Fetches data from API"라고만 써있다면, 오늘 거기에 '사용하지 말아야 할 경우'를 한 줄 추가하는 것부터 시작이다. 30분 투자, 50% 오류 감소. 이보다 ROI가 명확한 개선은 드물다.