에이전트 인지 정책을 배포할 때 무엇이 잘못될 수 있나요?
에이전트 인지 정책은 누가 또는 무엇이 동작하는지에 따라 애플리케이션이 응답하는 방식을 바꿉니다. 제대로 적용하면 사람에게는 매끄러운 경험을 제공하고, 정상적인 에이전트에는 구조화된 경로를 제공하며, 중요한 지점에만 마찰을 더합니다. 잘못 적용하면 실제 사용자를 차단하고, 고객이 의존하는 통합을 깨뜨리며, 누구도 설명할 수 없는 지원 티켓을 만듭니다.
그 차이는 대개 정책 로직이 아니라 배포 방식에 있습니다. (정책 모델 자체는 사람과 AI 에이전트를 위한 앱 수준 정책 설계하기를 참조하세요.) 이 가이드는 어떤 경로에도 적용할 수 있는 단계적 프로세스를 설명합니다. 관찰, 미리 보기, 일부에 적용, سپس 확장입니다. 각 단계에는 명확한 종료 기준과 빠른 복구 방법이 있습니다.
세 가지 모드
각 정책은 경로별로 세 가지 모드 중 하나로 동작한다고 생각하면 됩니다.
- 관찰. 분류가 기록됩니다. 애플리케이션은 분류가 없을 때와 정확히 같은 방식으로 응답합니다.
- 미리 보기. 정책이 평가되고 그 결정이 기록되지만 적용되지는 않습니다. 실제로 어떤 일이 일어났을지 볼 수 있습니다.
- 적용. 결정이 실제 요청에 적용됩니다.
모드는 전체 애플리케이션이 아니라 경로와 정책의 조합에 속합니다. 문서 페이지는 적용 중일 수 있지만 체크아웃은 아직 관찰 중일 수 있습니다.
1단계: 기준선을 알 때까지 관찰하세요
모든 경로를 관찰 모드로 시작하세요. 최소한 다음을 수집합니다.
- 경로와 메서드,
- actor class(Human, Human + AI, Agent 또는 Unknown)와 그 근거(verified, declared, inferred 또는 unknown), 애플리케이션 트래픽 분류 체계에서 정의한 대로,
- 응답 상태와 해당 경로의 간단한 결과 표시, 예를 들어 "계정 생성됨" 또는 "검색 결과 반환됨".
정상적인 주간 주기와 해당 기간에 배포하는 모든 릴리스를 포함할 만큼 충분히 오래 실행하세요. 그런 다음 중요하게 보는 각 경로에 대해 기준선을 기록합니다. class mix, Unknown 비율, class별 결과 비율입니다. 이후의 모든 것을 이 수치와 비교하게 됩니다.
종료 기준: 후보 경로마다 누가 사용하는지, 그리고 class별 결과가 어떻게 다른지 설명할 수 있습니다.
2단계: 정책을 데이터로 작성하세요
정책은 여기저기 흩어진 if 문장이 아니라 데이터일 때 검토, 테스트, 롤백이 훨씬 쉽습니다.
type ActorClass = "human" | "human_ai" | "agent" | "unknown";
type Basis = "verified" | "declared" | "inferred" | "unknown";
type Action = "allow" | "adapt" | "challenge" | "review" | "limit";
type Mode = "observe" | "preview" | "enforce";
interface Rule {
actor: ActorClass | "*";
basis?: Basis[];
action: Action;
}
interface RoutePolicy {
route: string;
mode: Mode;
enforcePercent: number;
rules: Rule[];
fallback: Action;
}
export const policies: RoutePolicy[] = [
{
route: "GET /api/catalog",
mode: "preview",
enforcePercent: 0,
rules: [
{ actor: "agent", basis: ["verified"], action: "allow" },
{ actor: "agent", basis: ["declared", "inferred"], action: "limit" },
],
fallback: "allow",
},
];모든 정책에는 명시적인 fallback가 있습니다. 이것은 Unknown 결과, 타임아웃, 그리고 어떤 규칙도 다루지 않는 경우에 사용하는 동작입니다. 이를 의도적으로 선택하는 것이 전체 과정에서 가장 중요한 안전 결정입니다.
3단계: 한 곳에서 평가하세요
단일 평가 함수는 모드 전반에서 동작을 일관되게 유지합니다.
export function decide(policy: RoutePolicy, actor: ActorClass, basis: Basis): Action {
for (const rule of policy.rules) {
const actorMatch = rule.actor === "*" || rule.actor === actor;
const basisMatch = !rule.basis || rule.basis.includes(basis);
if (actorMatch && basisMatch) return rule.action;
}
return policy.fallback;
}그다음 모드를 적용합니다.
export function applyPolicy(policy: RoutePolicy, actor: ActorClass, basis: Basis, requestKey: string) {
const decision = decide(policy, actor, basis);
const inSlice = bucket(requestKey) < policy.enforcePercent;
const enforced = policy.mode === "enforce" && inSlice;
record({ route: policy.route, mode: policy.mode, actor, basis, decision, enforced });
return enforced ? decision : "allow";
}
function bucket(key: string): number {
let h = 0;
for (const c of key) h = (h * 31 + c.charCodeAt(0)) >>> 0;
return h % 100;
}안정적인 버킷은 같은 세션 또는 클라이언트가 적용된 범위 안팎을 오가며 바뀌지 않도록 해 주므로, 사람들은 요청마다 동작이 뒤집히는 현상을 보지 않습니다.
4단계: 적용하기 전에 거짓 양성은 어떻게 측정하나요?
한 경로를 미리 보기로 전환하세요. 이제 모든 요청은 받게 될 결정이 무엇이었는지 기록합니다. 여기서 정책이 맞는지 알 수 있습니다.
거짓 양성은 정책이 제한했을 요청이지만 실제로는 허용되었어야 하는 요청입니다. 분류만으로는 측정할 수 없습니다. 분류 자체가 테스트 대상이기 때문입니다. 독립적인 정상 사용 신호와 비교해 측정하세요.
- 로그인한 사용자가 작업을 저장하는 등 정상적인 성공 흐름이 완료됨,
- 클라이언트가 알려진 파트너 통합이거나, 제공하기로 합의한 검증된 운영자임,
- 지원 티켓 또는 사용자 보고가 영향을 받은 경로를 언급함,
- 제한되었을 가능성이 있는 요청 샘플에 대한 수동 검토.
샘플은 직접 검토하세요. 정책이 challenge했을 실제 요청 20개를 읽는 것이 지나치게 넓은 규칙을 찾는 가장 빠른 방법입니다.
종료 기준: 제한될 가능성이 있는 집합이 실제로 제한하려는 트래픽이 대부분이며, 발견한 모든 거짓 양성 범주에 대한 설명이 있습니다.
5단계: 일부에만 적용하세요
작은 enforcePercent와 함께 경로를 적용 모드로 전환하세요. 실수가 적은 요청에만 영향을 주고, 하루나 이틀 안에 측정 가능한 신호를 만들 만큼은 충분히 크게 유지하세요.
기준선으로 설정한 동일한 지표를 지켜보세요.
- 해당 경로의 class별 결과 비율,
- 오류 및 challenge 완료율,
- 해당 경로를 언급하는 지원량,
- 평가가 요청 경로에 있으므로 지연 시간.
적용된 범위에서 Human 트래픽의 결과가 나머지와 비교해 떨어지면, 확장하기 전에 중단하고 조사하세요.
6단계: 점진적으로 확장하세요
예를 들어 작은 비율에서 4분의 1, 그다음 절반, 그다음 전체 트래픽으로 단계적으로 늘리세요. 각 단계에서 충분히 오래 유지해 정상 주기를 확인합니다. 앞선 단계가 잘 수행되었다면 확장은 지루해야 합니다. 그게 목표입니다.
대체 경로와 실패 동작을 선택하는 방법
증거가 없거나 평가를 실행할 수 없을 때 무슨 일이 일어날지 미리 결정하세요.
- fail open은 actor context가 없을 때와 동일하게 요청이 진행된다는 뜻입니다. 공개 페이지, 문서, 읽기 전용 카탈로그 endpoint 같은 저위험 경로에 사용하세요.
- fail closed는 기존의 더 강한 검사가 적용된다는 뜻입니다. 예를 들어 재인증이나 검토 대기열입니다. 이미 그런 검사가 있는 고영향 작업에 사용하세요.
타임아웃이나 오류가 Human 결과를 만들도록 두지 마세요. 누락된 증거는 Unknown이며, Unknown은 경로의 fallback을 따릅니다. AI 트래픽을 분류할 때 Unknown이 유효한 결과인 이유에 대한 우리의 글이 이 규칙이 왜 중요한지 설명합니다.
async function actorWithTimeout(evaluate: () => Promise<{ actor: ActorClass; basis: Basis }>) {
const timeout = new Promise<{ actor: ActorClass; basis: Basis }>((resolve) =>
setTimeout(() => resolve({ actor: "unknown", basis: "unknown" }), 150),
);
return Promise.race([evaluate(), timeout]);
}정책을 빠르게 롤백하려면 어떻게 해야 하나요?
롤백은 배포가 아니라 구성 변경이어야 합니다. 팀이 빠르게 편집할 수 있는 저장소에 정책을 보관하고, 다음 작업을 즉시 가능하게 만드세요.
- 경로를 다시 미리 보기로 설정해 적용은 멈추고 측정은 유지합니다.
enforcePercent를 0으로 설정합니다.- 다른 규칙은 건드리지 않고 단일 규칙만 비활성화합니다.
모든 정책 변경은 누가 언제 변경했는지 기록하세요. 결과가 바뀔 때 가장 먼저 묻는 질문은 항상 무엇이 바뀌었는가입니다.
사람에 대한 중대한 결정을 피하세요
actor 분류는 상호작용에 대한 증거를 설명합니다. 사람에 대한 판단이 아닙니다. 추론된 class를 누군가의 고용, 신용, 교육, 주거 또는 필수 서비스 접근에 영향을 주는 결정의 유일한 근거로 사용하지 마세요. 그런 흐름에서는 결과를 결정하는 대신, 예를 들어 인간 검토로 라우팅하는 식으로 actor context를 사용해 프로세스를 선택하세요.
적용하기 전에 커뮤니케이션하세요
자동화된 클라이언트에 영향을 주는 정책은 이를 운영하는 사람과 회사에도 영향을 줍니다. 약간의 커뮤니케이션만으로도 많은 지원 업무를 줄일 수 있습니다.
- 자동화된 접근에 대한 규칙을 공개하세요. 어떤 경로가 열려 있는지, 어떤 제한이 적용되는지, 그리고 클라이언트가 HTTP Message Signatures (RFC 9421)와 IETF Web Bot Auth protocol draft를 사용한 서명 요청으로 어떻게 자신을 식별할 수 있는지 명시하세요.
- 파트너와 통합 담당자에게 미리 알리세요. 알려진 통합이 미리 보기 중 제한된 범위에 들어가면, 적용 전에 소유자에게 연락하세요.
- 유용한 응답을 반환하세요. 정책이 요청을 제한하거나 challenge할 때는
429 Too Many Requests와Retry-After같은 명확한 상태 코드와 문서 링크를 포함해 응답하세요. Problem Details 형식의 기계 판독 가능한 본문은 자동화된 클라이언트에 구조화된 이유를 제공합니다. 잘 만들어진 에이전트는 이유를 이해하면 적응합니다. - 지원팀에 증거를 제공하세요. 차단된 요청에 대한 티켓이 들어오면, 지원팀이 엔지니어링에 묻지 않고도 경로, class, basis, 정책 결정을 조회할 수 있어야 합니다.
변경을 공지하고 설명하는 팀은 조용히 규칙을 바꾸는 팀보다 훨씬 적은 예외 상황을 겪습니다. 그리고 적응하는 클라이언트는 시간이 지날수록 더 쉽게 식별됩니다.
각 경로를 위한 체크리스트
- class mix, Unknown 비율, 결과에 대한 기준선 기록 완료.
- 명시적인 fallback이 있는 데이터 형태의 정책 작성 완료.
- 미리 보기 실행, 샘플 검토, 거짓 양성 범주 설명 완료.
- 지표를 확인하면서 작은 범위에 적용 시작.
- 실패 동작 선택 완료: fail open 또는 fail closed.
- 확장 전에 롤백 테스트 완료.
Proof of Actor가 들어가는 위치
Proof of Actor는 이 프로세스를 중심으로 설계되었습니다. 관찰이 기본값이며, 모든 결과에는 basis가 포함되고, Route 정책은 팀이 자신의 코드에서 경로별로 정의하고 적용할 수 있습니다. Detect, Understand, Route: 이 순서입니다.
자체 애플리케이션에서 우리 팀과 함께 배포를 진행하려면 조기 액세스 신청하기를 하세요. 결정 흐름 전체는 Proof of Actor 작동 방식을 읽어보세요.
출처
- RFC 6585: Additional HTTP Status Codes, Section 4:
429 Too Many Requests상태 코드 - RFC 9110: HTTP Semantics, Retry-After: 클라이언트에게 재시도 시점 알리기
- RFC 9457: Problem Details for HTTP APIs: 기계 판독 가능한 오류 본문
- RFC 9421: HTTP Message Signatures: 자동화된 클라이언트가 요청에 서명하는 방법
- draft-ietf-webbotauth-httpsig-protocol: 서명된 자동화 트래픽을 위한 IETF Web Bot Auth 초안(2026년 11월 기준 진행 중)