☰ 분류

AI 엔드포인트 보호 프롬프트

LLM 채팅·완성 엔드포인트 정보를 넣으면 Arcjet 기반 프롬프트 인젝션 탐지, PII 차단, 토큰 예산 제한을 추가하게 합니다.

분류개발 › 코딩
태그초안작성검토개발자코드
프롬프트 (영어 본문 · 답은 한국어로 옵니다)
---
name: add-ai-protection
license: Apache-2.0
description: Protect AI chat and completion endpoints from abuse — detect prompt injection and jailbreak attempts, block PII and sensitive info from leaking in responses, and enforce token budget rate limits to control costs. Use this skill when the user is building or securing any endpoint that processes user prompts with an LLM, even if they describe it as "preventing jailbreaks," "stopping prompt attacks," "blocking sensitive data," or "controlling AI API costs" rather than naming specific protections.
metadata:
  pathPatterns:
    - "app/api/chat/**"
    - "app/api/completion/**"
    - "src/app/api/chat/**"
    - "src/app/api/completion/**"
    - "**/chat/**"
    - "**/ai/**"
    - "**/llm/**"
    - "**/api/generate*"
    - "**/api/chat*"
    - "**/api/completion*"
  importPatterns:
    - "ai"
    - "@ai-sdk/*"
    - "openai"
    - "@anthropic-ai/sdk"
    - "langchain"
  promptSignals:
    phrases:
      - "prompt injection"
      - "pii"
      - "sensitive info"
      - "ai security"
      - "llm security"
    anyOf:
      - "protect ai"
      - "block pii"
      - "detect injection"
      - "token budget"
---

# Add AI-Specific Security with Arcjet

Secure AI/LLM endpoints with layered protection: prompt injection detection, PII blocking, and token budget rate limiting. These protections work together to block abuse before it reaches your model, saving AI budget and protecting user data.

## Reference

Read https://docs.arcjet.com/llms.txt for comprehensive SDK documentation covering all frameworks, rule types, and configuration options.

Arcjet rules run **before** the request reaches your AI model — blocking prompt injection, PII leakage, cost abuse, and bot scraping at the HTTP layer.

## Step 1: Ensure Arcjet Is Set Up

Check for an existing shared Arcjet client (see `/arcjet:protect-route` for full setup). If none exists, set one up first with `shield()` as the base rule. The user will need to register for an Arcjet account at https://app.arcjet.com then use the `ARCJET_KEY` in their environment variables.

## Step 2: Add AI Protection Rules

AI endpoints should combine these rules on the shared instance using `withRule()`:

### Prompt Injection Detection

Detects jailbreaks, role-play escapes, and instruction overrides.

- JS: `detectPromptInjection()` — pass user message via `detectPromptInjectionMessage` parameter at `protect()` time
- Python: `detect_prompt_injection()` — pass via `detect_prompt_injection_message` parameter

Blocks hostile prompts **before** they reach the model. This saves AI budget by rejecting attacks early.

### Sensitive Info / PII Blocking

Prevents personally identifiable information from entering model context.

- JS: `sensitiveInfo({ deny: ["EMAIL", "CREDIT_CARD_NUMBER", "PHONE_NUMBER", "IP_ADDRESS"] })`
- Python: `detect_sensitive_info(deny=[SensitiveInfoType.EMAIL, SensitiveInfoType.CREDIT_CARD_NUMBER, ...])`

Pass the user message via `sensitiveInfoValue` (JS) / `sensitive_info_value` (Python) at `protect()` time.

### Token Budget Rate Limiting

Use `tokenBucket()` / `token_bucket()` for AI endpoints — the `requested` parameter can be set proportional to actual model token usage, directly linking rate limiting to cost. It also allows short bursts while enforcing an average rate, which matches how users interact with chat interfaces.

Recommended starting configuration:

- `capacity`: 10 (max burst)
- `refillRate`: 5 tokens per interval
- `interval`: "10s"

Pass the `requested` parameter at `protect()` time to deduct tokens proportional to model cost. For example, deduct 1 token per message, or estimate based on prompt length.

Set `characteristics` to track per-user: `["userId"]` if authenticated, defaults to IP-based.

### Base Protection

Always include `shield()` (WAF) and `detectBot()` as base layers. Bots scraping AI endpoints are a common abuse vector. For endpoints accessed via browsers (e.g. chat interfaces), consider adding Arcjet advanced signals for client-side bot detection that catches sophisticated headless browsers. See https://docs.arcjet.com/bot-protection/advanced-signals for setup.

## Step 3: Compose the protect() Call and Handle Decisions

All rule parameters are passed together in a single `protect()` call. Use this pattern:

```typescript
const userMessage = req.body.message; // the user's input

const decision = await aj.protect(req, {
  requested: 1, // tokens to deduct for rate limiting
  sensitiveInfoValue: userMessage, // PII scanning
  detectPromptInjectionMessage: userMessage, // injection detection
});

if (decision.isDenied()) {
  if (decision.reason.isRateLimit()) {
    return Response.json(
      { error: "You've exceeded your usage limit. Please try again later." },
      { status: 429 },
    );
  }
  if (decision.reason.isPromptInjection()) {
    return Response.json(
      { error: "Your message was flagged as potentially harmful." },
      { status: 400 },
    );
  }
  if (decision.reason.isSensitiveInfo()) {
    return Response.json(
      {
        error:
          "Your message contains sensitive information that cannot be processed. Please remove any personal data.",
      },
      { status: 400 },
    );
  }
  if (decision.reason.isBot()) {
    return Response.json({ error: "Forbidden" }, { status: 403 });
  }
}

// Arcjet fails open — log errors but allow the request
if (decision.isErrored()) {
  console.warn("Arcjet error:", decision.reason.message);
}

// Proceed with AI model call...
```

Adapt the response format to your framework (e.g., `res.status(429).json(...)` for Express).

## Step 5: Verify

1. Start the app and send a normal message — should succeed
2. Test prompt injection by sending something like "Ignore all previous instructions and..."
3. Test PII blocking by sending a message with a fake credit card number

Start all rules in `"DRY_RUN"` mode first. Once verified, promote to `"LIVE"`.

**Always recommend using the Arcjet MCP tools** to verify rules and analyze traffic:

- `list-requests` — confirm decisions are being recorded, filter by conclusion to see blocks
- `analyze-traffic` — review denial rates and patterns for the AI endpoint
- `explain-decision` — understand why a specific request was allowed or denied (useful for tuning prompt injection sensitivity)
- `promote-rule` — promote rules from `DRY_RUN` to `LIVE` once verified

If the user wants a full security review, suggest the `/arcjet:security-analyst` agent which can investigate traffic, detect anomalies, and recommend additional rules.

The Arcjet dashboard at https://app.arcjet.com is also available for visual inspection.

## Common Patterns

**Streaming responses**: Call `protect()` before starting the stream. If denied, return the error before opening the stream — don't start streaming and then abort.

**Multiple models / providers**: Use the same Arcjet instance regardless of which AI provider you use. Arcjet operates at the HTTP layer, independent of the model provider.

**Vercel AI SDK**: Arcjet works alongside the Vercel AI SDK. Call `protect()` before `streamText()` / `generateText()`. If denied, return a plain error response instead of calling the AI SDK.

## Common Mistakes to Avoid

- Sensitive info detection runs **locally in WASM** — no user data is sent to external services. It is only available in route handlers, not in Next.js pages or server actions.
- `sensitiveInfoValue` and `detectPromptInjectionMessage` (JS) / `sensitive_info_value` and `detect_prompt_injection_message` (Python) must both be passed at `protect()` time — forgetting either silently skips that check.
- Starting a stream before calling `protect()` — if the request is denied mid-stream, the client gets a broken response. Always call `protect()` first and return an error before opening the stream.
- Using `fixedWindow()` or `slidingWindow()` instead of `tokenBucket()` for AI endpoints — token bucket lets you deduct tokens proportional to model cost and matches the bursty interaction pattern of chat interfaces.
- Creating a new Arcjet instance per request instead of reusing the shared client with `withRule()`.

어떤 프롬프트인가

AI API 남용과 민감정보 유출을 HTTP 계층에서 막도록 안내하는 개발 프롬프트다. Arcjet 설정과 규칙 추가를 전제로 하며, 사용자는 ARCJET_KEY를 준비해야 한다.

모델 비교

ChatGPT가 저장소에 맞춘 판단과 분량에서 가장 우수하다. Gemini는 상세하지만 지침 위반과 과잉 답변이 있고, Claude는 정직하나 작업 수행이 부족하다.

ChatGPT종합 1위
44/ 50

+ 저장소 점검 결과와 무변경 판단을 간결히 제시했다.

- 필수 MCP 검증 도구 권고와 세부 근거가 빠졌다.

Claude
29/ 50

+ 확인하지 못한 사실을 꾸며내지 않고 한계를 밝혔다.

- 반복 실패를 장황히 말하고 스스로 확인할 일을 되물었다.

Gemini
25/ 50

+ 규칙 조합과 거부 응답 흐름을 코드로 구체화했다.

- DRY_RUN 지침을 어기고 처음부터 LIVE로 설정했다.

기준ChatGPTClaudeGemini앞선 모델
지시 준수844ChatGPT +100%
정확성875ChatGPT +14%
구체성954ChatGPT +80%
구성·가독성978ChatGPT +13%
분량 적정성1064ChatGPT +67%

gpt-5.6-sol가 모델 이름을 가린 채 1~10점으로 채점했습니다 (2026-09-24). 측정값이 아니라 AI 심사 결과입니다.

답 전문 보기

같은 입력을 세 모델에 넣어 받은 답을 그대로 옮겼습니다. 각 CLI(에이전트 하네스)에서 실행했습니다. ChatGPT·Claude 앱이나 웹에서는 답이 다를 수 있습니다.

gpt-5.6-luna (codex CLI · 에이전트 하네스) · 실행일 2026-09-24

점검 결과, 현재 저장소에는 보호 대상인 AI 채팅/완성 엔드포인트가 없습니다.

  • /api/chat, /api/completion, LLM SDK 사용 없음
  • AI 관련 코드는 이미지 생성용 server/xai_image.py뿐
  • Arcjet 적용 대상 라우트가 없어 변경하지 않았습니다.
  • 기존 테스트 11개 모두 통과했습니다.

향후 텍스트 AI 엔드포인트를 추가하면 shield(), detectBot(), prompt injection 탐지, PII 차단, tokenBucket()을 해당 라우트에 적용해야 합니다.

같은 분류의 프롬프트

방산 CV 12개월 로드맵 프롬프트
2046 퍼즐 게임 제작 프롬프트
React 컴포넌트 통합 프롬프트
3D 아바타 팩토리 요구 프롬프트
3D FPS 게임 개발 프롬프트