본문으로 건너뛰기
Google Genkit Middleware 해설: 에이전트 앱은 프롬프트보다 모델·도구 호출 경계를 먼저 코드로 고정해야 하는 이유
← 블로그로 돌아가기

Google Genkit Middleware 해설: 에이전트 앱은 프롬프트보다 모델·도구 호출 경계를 먼저 코드로 고정해야 하는 이유

개발정보·10분

Google Genkit Middleware는 에이전트 앱의 재시도, 모델 폴백, 도구 승인, 파일 접근, 스킬 주입을 generate() 호출 주변의 공통 계층으로 분리합니다. 이 글은 프롬프트 규칙·직접 if문·그래프형 오케스트레이션과 비교해 실제 도입 기준을 정리합니다.

Google Genkit Middleware로 에이전트 앱의 모델 호출과 도구 호출 경계를 설계하는 개념 이미지
Genkit Middleware의 핵심은 모델 호출, 도구 실행, 생성 루프 사이에 공통 통제 계층을 두는 것입니다.

1. 한 줄 문제 정의

핵심 요약: 에이전트 앱은 모델이 똑똑해질수록 실패 지점도 프롬프트 밖으로 넓어집니다.

AI 에이전트 앱을 만들 때 초반에는 보통 프롬프트에 규칙을 길게 적습니다. "실패하면 다시 시도해", "위험한 도구는 실행하지 마", "이 파일 밖은 읽지 마" 같은 문장을 시스템 프롬프트에 넣는 방식입니다. 문제는 이런 규칙이 모델의 답변 습관을 바꿀 수는 있어도, 실제 API 장애·도구 실행·파일 접근·승인 흐름을 확정적으로 통제하지는 못한다는 점입니다.

Google이 2026년 5월 14일 발표한 Genkit Middleware는 이 문제를 코드 계층에서 다룹니다. Genkit의 generate() 호출과 도구 실행 루프 사이에 미들웨어를 끼워 넣어 재시도, 모델 폴백, 도구 승인, 스킬 주입, 파일 접근, 로깅을 공통 정책으로 처리합니다.

적용 범위는 명확합니다. 여러 모델과 도구를 묶어 제품 기능을 만들고, 실패·비용·권한·로그를 운영 기준으로 관리해야 하는 팀에 맞습니다. 반대로 단순 요약 챗봇, 일회성 데모, 내부 PoC 수준이라면 미들웨어 설계가 오히려 과할 수 있습니다.

2. 먼저 결론

핵심 요약: Genkit Middleware는 "프롬프트 규칙"을 "실행 계약"으로 끌어내리는 도구입니다.

저라면 Genkit Middleware를 모델 성능 개선 기능으로 보지 않겠습니다. 더 정확한 이름은 에이전트 실행 경계 계층입니다. 모델이 어떤 말을 하느냐보다, 모델 호출이 실패했을 때 어디까지 다시 시도할지, 어떤 도구는 사람 승인을 받아야 할지, 파일 접근은 어느 디렉터리 안으로 제한할지, 어떤 로그를 남길지를 코드로 고정하는 역할에 가깝습니다.

  • 에이전트가 파일 쓰기, 삭제, 배포, 결제, CRM 수정처럼 되돌리기 어려운 도구를 호출한다면 도입 가치가 큽니다.
  • Gemini, Claude, OpenAI, 로컬 모델 등 여러 모델을 상황에 따라 바꿔야 한다면 폴백 정책을 공통화할 수 있습니다.
  • 장애가 났을 때 어느 계층에서 실패했는지 추적해야 한다면 Developer UI와 미들웨어 로그가 도움이 됩니다.

아직 관찰만 해도 되는 경우도 있습니다. 단일 모델에 단일 프롬프트만 호출하는 앱, 도구 실행이 없는 콘텐츠 생성 앱, 트래픽이 적어 장애 복구를 사람이 해도 되는 앱은 먼저 단순한 구조로 시작하는 편이 낫습니다.

3. 핵심 구조 분해

핵심 요약: Genkit Middleware는 생성 루프를 세 구간으로 나눠서 각각 다른 통제 지점을 제공합니다.

Genkit의 generate() 호출은 단순히 모델에게 한 번 질문하고 끝나는 구조가 아닙니다. 도구가 연결되어 있으면 모델이 답을 만들고, 필요한 도구를 요청하고, 애플리케이션이 도구를 실행하고, 그 결과를 다시 모델에 넘기는 루프가 반복됩니다.

계층실행 시점적합한 정책실무 예시
Generate 훅도구 루프의 각 반복컨텍스트 주입, 메시지 재작성, 대화 단위 정책사용자 등급에 따라 참고 문서 범위 변경
Model 훅모델 API 호출마다재시도, 폴백, 캐싱, 지연 시간 로깅쿼터 초과 시 다른 모델로 전환
Tool 훅도구 하나가 실행될 때마다승인 게이트, 샌드박스, 도구별 감사 로그deleteFile, deployProduction 승인 요구

이 구조가 중요한 이유는 실패 범위를 좁히기 때문입니다. 모델 API가 RESOURCE_EXHAUSTED로 실패했을 때 전체 도구 루프를 처음부터 다시 실행하면 이미 실행된 도구가 중복 호출될 수 있습니다. Genkit의 Retry 미들웨어는 공식 설명상 모델 호출만 재시도하고 주변 도구 루프는 재실행하지 않습니다.

4. 설계 의도 해설

핵심 요약: 미들웨어 설계의 핵심은 에이전트의 예측 불가능성을 줄이되, 모든 것을 프레임워크에 숨기지 않는 것입니다.

Genkit Middleware가 선택한 설계는 웹 서버 미들웨어와 비슷합니다. 요청이 들어오면 인증, 로깅, 검증, 라우팅이 순서대로 실행되듯이, 모델 호출도 재시도, 필터링, 도구 승인, 파일 접근 제한 같은 공통 처리를 체인으로 통과합니다.

얻는 것은 세 가지입니다. 첫째, 정책을 프롬프트에서 빼내 코드로 고정합니다. 둘째, 같은 정책을 여러 플로우와 여러 팀에서 재사용합니다. 셋째, Developer UI에서 미들웨어 실행 흔적을 보고 디버깅할 수 있습니다.

대신 포기하는 것도 있습니다. 미들웨어 순서를 잘못 잡으면 의도와 다르게 동작합니다. 공식 발표는 스택이 왼쪽에서 오른쪽으로 쌓이며 첫 번째 항목이 가장 바깥 래퍼가 된다고 설명합니다. 즉 미들웨어는 마법 자동화가 아니라 실행 순서가 있는 정책 코드입니다.

5. 근거 및 비교

핵심 요약: Genkit Middleware의 경쟁 상대는 다른 모델이 아니라, 흩어진 예외 처리와 프롬프트 기반 운영 규칙입니다.

접근장점한계추천 상황
프롬프트 규칙가장 빠르고 별도 코드가 적음모델이 반드시 지킨다는 보장이 약함읽기 전용 챗봇, 데모
직접 if문과 try/catch프레임워크 의존이 적고 즉시 이해 가능플로우가 늘면 정책이 흩어짐작은 서비스, 단일 모델
그래프형 오케스트레이션복잡한 상태 전이와 장기 작업에 강함초기 학습 비용이 높음멀티스텝 워크플로, 상태 머신
Genkit Middlewaregenerate()와 도구 루프 가까이에서 정책 적용Genkit 생태계와 순서 설계에 의존Genkit 기반 제품 기능, 도구 호출 에이전트

공식 자료 기준으로 현재 제공되는 대표 미들웨어는 Retry, Fallback, Tool approval, Skills, Filesystem입니다. JavaScript에서는 @genkit-ai/middleware 패키지로 사용할 수 있고, Go에서는 core Genkit 모듈과 middleware 플러그인 경로가 안내됩니다. 발표문 기준으로 TypeScript, Go, Dart를 지원하며 Python 지원은 추후 예정입니다.

6. 실제 동작 흐름 / 단계별 실행 방법

핵심 요약: 작게 시작하려면 재시도, 도구 승인, 파일 접근 제한 세 가지만 먼저 붙이면 됩니다.

mkdir my-genkit-app
cd my-genkit-app
npm init -y
npm pkg set type=module
npm install genkit @genkit-ai/google-genai @genkit-ai/middleware
npm install -D typescript tsx
export GEMINI_API_KEY=<your_key>

그 다음 모델 호출에 미들웨어를 붙입니다. 아래 코드는 개념 예시입니다. 실제 프로젝트에서는 도구 이름과 승인 UI를 서비스에 맞게 바꿔야 합니다.

import { genkit } from 'genkit';
import { googleAI } from '@genkit-ai/google-genai';
import { retry, fallback, toolApproval, filesystem } from '@genkit-ai/middleware';

const ai = genkit({
  plugins: [googleAI()],
  model: googleAI.model('gemini-2.5-flash'),
});

const response = await ai.generate({
  prompt: 'workspace 안에 README 초안을 만들고 필요한 파일만 수정해줘.',
  tools: [writeFileTool],
  use: [
    retry({ maxRetries: 3, initialDelayMs: 1000, backoffFactor: 2 }),
    fallback({
      models: [googleAI.model('gemini-flash-latest')],
      statuses: ['RESOURCE_EXHAUSTED', 'UNAVAILABLE'],
    }),
    toolApproval({ approved: ['readFileTool'] }),
    filesystem({ rootDirectory: './workspace', allowWriteAccess: false })
  ],
});
  1. 먼저 모델 호출 실패율과 평균 지연 시간을 기록합니다.
  2. 실패율이 높은 요청에만 Retry를 붙입니다.
  3. 쿼터 또는 공급자 장애가 실제 문제일 때 Fallback을 붙입니다.
  4. 쓰기·삭제·배포·결제 도구에는 Tool approval을 기본값으로 둡니다.
  5. 파일 접근은 프로젝트 루트가 아니라 작업 디렉터리 단위로 제한합니다.
  6. Developer UI에서 미들웨어 순서와 실행 흔적을 확인합니다.

7. 실수/함정(Pitfalls)

핵심 요약: 미들웨어는 안전장치가 될 수도 있고, 잘못 쓰면 장애를 숨기는 계층이 될 수도 있습니다.

함정 1: Retry를 만능 복구로 착각한다

일시적 네트워크 오류에는 Retry가 도움이 됩니다. 하지만 프롬프트가 잘못됐거나 도구 입력 스키마가 틀렸다면 세 번 반복해도 같은 실패가 반복됩니다. 재시도 대상 상태 코드를 제한하고, 재시도 후에도 실패하면 원인을 로그에 남겨야 합니다.

함정 2: Fallback 모델의 성격 차이를 무시한다

큰 모델에서 작은 모델로 폴백하면 비용과 가용성은 좋아질 수 있지만 출력 형식과 추론 품질이 달라질 수 있습니다. 폴백 후 결과에는 스키마 검증을 걸고, 중요한 작업은 임시 응답 상태로 표시하는 편이 안전합니다.

함정 3: Tool approval을 UI 이벤트로만 생각한다

도구 승인은 버튼 하나가 아니라 감사 로그입니다. 누가, 언제, 어떤 입력으로, 어떤 도구를 승인했는지 남지 않으면 사고 후 복구가 어렵습니다.

함정 4: Filesystem 루트를 너무 넓게 잡는다

rootDirectory: './'처럼 프로젝트 전체를 열면 에이전트가 불필요한 파일까지 읽을 수 있습니다. 작업별 임시 디렉터리를 만들고, 쓰기 권한은 기본적으로 꺼두는 편이 낫습니다.

8. 강점과 한계

핵심 요약: Genkit Middleware는 Genkit을 쓰는 팀에는 실용적이지만, 모든 에이전트 시스템의 표준 답은 아닙니다.

강점은 분명합니다. 모델 호출과 도구 호출 사이에 개입할 수 있어 프롬프트보다 강한 통제가 가능합니다. Retry·Fallback·Tool approval 같은 흔한 운영 기능을 직접 매번 만들 필요가 줄어듭니다. Developer UI에서 실행 흐름을 볼 수 있어 초보 개발자도 왜 이 응답이 나왔는지 추적하기 쉽습니다.

한계도 있습니다. 이미 LangGraph나 자체 워크플로 엔진으로 상태 전이를 촘촘하게 설계한 팀은 Genkit Middleware가 중복 계층처럼 느껴질 수 있습니다. Python 지원이 아직 예정 단계인 점도 Python 중심 팀에는 현실적인 제약입니다. 또한 미들웨어가 있다고 해서 보안이 자동으로 완성되지는 않습니다. 비밀 관리, 감사 로그 저장소, 배포 승인 프로세스는 별도로 설계해야 합니다.

9. 더 깊게 공부할 포인트

핵심 요약: 미들웨어를 제대로 쓰려면 Genkit 자체보다 도구 호출 루프와 승인 재개 흐름을 먼저 이해해야 합니다.

  • 도구 호출 루프: 모델이 도구 요청을 만들고, 앱이 도구를 실행하고, 결과를 다시 모델에 넣는 반복 구조입니다.
  • Interrupt와 resume: 위험 도구를 멈추고 사람 승인을 받은 뒤 같은 대화 기록으로 재개하는 흐름입니다.
  • 스키마 검증: 폴백 모델이나 커스텀 필터를 붙이면 출력 형식을 다시 검증해야 합니다.
  • 관측성: Developer UI뿐 아니라 운영 로그에 요청 ID, 모델명, 미들웨어 이름, 도구명, 승인자를 남겨야 합니다.

10. 실행 체크리스트 + 작성자 관점

핵심 요약: 에이전트 앱의 품질은 모델 선택보다 실패·권한·로그 기준을 얼마나 빨리 코드로 내렸는지에서 갈립니다.

  • 도구를 읽기 전용, 쓰기 가능, 파괴 가능, 외부 비용 발생으로 분류했는가?
  • 파괴 가능 도구는 기본적으로 Tool approval 또는 별도 승인 게이트를 통과하는가?
  • Retry가 모델 호출만 재시도하는지, 도구 실행까지 중복하지 않는지 확인했는가?
  • Fallback 모델을 쓸 때 출력 스키마와 품질 저하 기준을 따로 검증하는가?
  • 파일 접근 루트가 작업 디렉터리로 제한되어 있고 기본 쓰기 권한이 꺼져 있는가?
  • 미들웨어 순서가 팀 템플릿에 고정되어 있고, 순서를 바꿀 때 리뷰를 받는가?
  • Developer UI와 운영 로그 양쪽에서 모델명, 도구명, 승인 상태, 실패 코드를 추적할 수 있는가?

Definition of Done: 위험 도구 하나를 실제로 차단하고, 승인 후 재개하며, 실패 로그에서 어떤 미들웨어가 개입했는지 재현할 수 있으면 1차 도입은 완료입니다.

제 결론은 선명합니다. Genkit Middleware는 에이전트를 더 똑똑하게 만드는 기능이 아닙니다. 에이전트가 이미 충분히 많은 일을 하게 됐을 때, 그 일을 제품 안에서 감당 가능한 형태로 묶는 운영 계층입니다.

공유하기

관련 글

AQ 테스트 해보기

지금 내 AI 활용 능력이 어느 수준인지 3분 안에 확인해보세요. 인지력, 활용력, 검증력, 통합력, 윤리감을 한 번에 진단하고 맞춤형 인사이트를 받아볼 수 있습니다.

무료 AQ 테스트 시작하기