AI 에이전트는 더 이상 “프롬프트를 넣고 답을 받는 기능”이 아닙니다. 실제 서비스에 들어가면 모델 호출 실패, quota 초과, 도구 실행 승인, 응답 필터링, 로깅, fallback, observability가 같이 필요합니다. 이 부분을 매번 비즈니스 코드 안에 섞으면 에이전트는 금방 복잡해집니다.
Google Developers Blog는 2026년 5월 14일 Genkit Middleware를 공개했습니다. Genkit은 TypeScript, Go, Dart, Python을 지원하는 오픈소스 프레임워크이며, 이번 미들웨어는 generation call과 tool execution loop 사이에 composable hook을 넣는 방식입니다. 공식 글 기준으로 TypeScript, Go, Dart에서 사용할 수 있고 Python 지원은 예정입니다.
핵심은 간단합니다. 모델 호출을 그대로 믿지 말고, 모델 호출 전후와 도구 실행 앞뒤에 운영 정책을 끼워 넣습니다. retries, model fallback, human-in-the-loop tool approval, sandboxing, logging, content filtering 같은 기능을 프롬프트가 아니라 코드 레벨의 미들웨어로 다룹니다.
Genkit의 generate() 호출은 tool loop를 실행합니다. 모델이 출력을 만들고, 필요한 도구를 요청하면 도구가 실행됩니다. 도구 결과는 다시 모델에 들어가고, 이 과정이 끝날 때까지 반복됩니다. Genkit Middleware는 이 루프의 세 계층에 hook을 붙입니다.
첫째는 Generate hook입니다. tool-loop iteration마다 한 번 실행됩니다. 대화 수준의 context injection, message rewriting, conversation-level logic에 적합합니다. 예를 들어 고객 등급, 조직 정책, 현재 세션 상태를 매 반복마다 주입할 수 있습니다.
둘째는 Model hook입니다. 실제 model API call마다 실행됩니다. retry, fallback, caching, latency logging에 적합합니다. quota 초과나 일시적 장애가 났을 때 같은 프롬프트를 다시 던질지, 다른 모델로 바꿀지 결정하는 계층입니다.
셋째는 Tool hook입니다. 도구가 실행될 때마다 동작합니다. 파일 삭제, 결제 취소, 이메일 전송, 배포 실행처럼 외부 효과가 있는 작업에 human approval을 붙일 수 있습니다. tool-level logging이나 sandboxing도 이 지점에서 처리합니다.
이 구조의 장점은 정책이 분리된다는 점입니다. “고객 지원 에이전트는 경쟁사명을 말하면 안 된다”, “삭제 도구는 항상 승인받아야 한다”, “Gemini 호출이 RESOURCE_EXHAUSTED면 다른 모델로 fallback한다” 같은 정책이 프롬프트 문장에 묻히지 않습니다.
공식 글이 소개한 pre-built middleware는 Retry, Fallback, Tool approval, Skills, Filesystem입니다. 각각은 실제 운영에서 자주 터지는 문제를 겨냥합니다.
Retry는 transient error에 대해 exponential backoff와 jitter로 모델 API call만 재시도합니다. 여기서 중요한 점은 “주변 tool loop 전체를 재생하지 않는다”는 설명입니다. 도구 실행까지 다시 replay하면 중복 결제, 중복 이메일, 중복 파일 쓰기 같은 문제가 생길 수 있습니다. 모델 호출 재시도와 side effect 재실행은 분리해야 합니다.
Fallback은 primary model이 지정된 error code에서 실패할 때 다른 모델로 바꿉니다. 예를 들어 quota 초과 시 다른 provider 또는 다른 모델로 넘어갈 수 있습니다. 단, fallback은 단순 장애 대응이 아닙니다. 모델별 출력 형식, 비용, latency, 보안 정책이 다를 수 있으므로 fallback 결과도 같은 validator를 통과해야 합니다.
Tool approval은 allow-list 밖의 도구 실행을 interrupt로 바꿉니다. 삭제, 전송, 결제, 권한 변경처럼 되돌리기 어려운 작업에는 필수입니다. 에이전트가 도구를 “쓸 수 있다”와 “자동으로 써도 된다”는 완전히 다른 문제입니다.
Skills는 SKILL.md 파일을 읽어 system prompt에 주입하거나 필요한 skill을 도구로 로드하게 합니다. 프롬프트를 코드 밖 문서로 관리하려는 팀에 유용합니다. Filesystem은 root directory를 벗어나지 못하게 경로 안전성을 강제하면서 list/read/write/edit 도구를 제공합니다.
이번 발표의 의미는 “Genkit이 기능을 많이 추가했다”보다 큽니다. 에이전트 개발의 중심이 프롬프트 엔지니어링에서 정책 엔지니어링으로 이동하고 있다는 신호입니다.
프롬프트만으로는 운영 요구사항을 안정적으로 지키기 어렵습니다. 모델에게 “민감 정보를 출력하지 마”라고 쓰는 것보다 출력 직후 content filter를 통과시키는 편이 낫습니다. “실패하면 다시 시도해”라고 쓰는 것보다 retry middleware가 error code, backoff, 최대 횟수를 관리하는 편이 낫습니다. “삭제 전에 물어봐”라고 쓰는 것보다 tool approval이 interrupt를 발생시키는 편이 낫습니다.
실무팀은 에이전트 기능을 세 층으로 나눠야 합니다.
이 구분이 없으면 에이전트는 데모에서는 잘 작동하지만 운영에서는 불안정해집니다. 특히 고객지원, 내부 자동화, DevOps, 데이터 분석 에이전트는 외부 시스템을 건드리기 때문에 미들웨어 계층이 필수에 가깝습니다.
가장 작은 도입 단위는 model call 주위에 retry와 latency logging을 붙이는 것입니다. 그 다음 quota error에 fallback을 붙이고, 마지막으로 destructive tool에 approval을 붙입니다. 처음부터 모든 도구를 막으면 생산성이 떨어지고, 아무것도 막지 않으면 사고가 납니다.
예를 들어 사내 문서 검색 에이전트라면 다음 구조가 현실적입니다.
이 설계에서는 프롬프트가 짧아집니다. 모델에게 모든 정책을 외우게 하지 않고, 정책은 코드와 hook이 강제합니다. 프롬프트는 사용자 의도와 업무 맥락을 설명하는 데 집중할 수 있습니다.
Genkit Middleware는 에이전트를 더 똑똑하게 만드는 기능이라기보다, 에이전트를 운영 가능한 소프트웨어로 만드는 계층입니다. 다음 에이전트 프로젝트를 시작한다면 먼저 물어봐야 합니다. “이 기능은 모델에게 부탁할 일인가, 미들웨어가 강제할 일인가?”