0Pricing
Claude Architect · 강의

예시를 활용한 심각도 기준

각 심각도 수준을 코드 예시로 구체화합니다

예시를 활용한 심각도 기준은(는) CoddyKit의 무료 Claude Architect 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Claude Architect 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Claude Architect 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

Why Severity Needs Criteria

When you ask Claude to review code, the weakest instruction you can give is a vague one: be more precise or only flag important issues. The model has no shared definition of "important", so its bar drifts from file to file.

The exam principle is blunt: explicit criteria beat vague adjectives. A severity scale (Critical / High / Medium / Low) is only useful if each level has a written rule the model can apply consistently — and the most reliable way to pin down a rule is to anchor it with a concrete code example.

This lesson builds a severity rubric for a CI/CD review agent, one level at a time, each level tied to an example.

The Failure Mode: Adjectives Without Anchors

Here is the kind of prompt that looks fine but performs badly. It names severity levels but never defines them, so the model guesses — and guesses differently each run.

The result is exactly the anti-pattern the exam warns about: noisy reviews where a missing null-check and a misspelled comment both get tagged "High". Reviewers stop trusting the labels.

system = (
    "You are a code reviewer. "
    "Rate each issue as Critical, High, Medium, or Low. "
    "Be precise and only report important problems."
)

# Problem: 'important', 'precise', and the four levels are
# never defined. The bar is whatever the model infers today.

The Fix: One Rule + One Example per Level

The repair is structural. For every severity level, give the model two things:

  • A rule — a testable condition ("causes data loss, security breach, or a crash in production").
  • An anchor example — a short snippet that unambiguously sits at that level.

This is few-shot prompting applied to a rubric: 2-4 targeted examples per ambiguity. The model generalizes from the anchors — it does not just echo them — so a handful of well-chosen examples calibrates the whole scale.

Critical — Anchor with a Security Example

Critical is reserved for issues that cause data loss, a security breach, or a production crash. Anchor it with something undeniable — here, raw string interpolation into SQL.

Notice the anchor does double duty: it defines the ceiling of the scale, so the model knows nothing milder should reach this level.

CRITICAL = """
Critical: causes data loss, a security breach, or a
production crash. Always report, even if low-confidence.

Example (SQL injection):
    query = f"SELECT * FROM users WHERE id = {user_input}"
    db.execute(query)
Why: user_input is interpolated unescaped -> injectable.
"""

High — Anchor with a Logic Bug

High covers wrong behavior that won't crash the process but produces incorrect results — a logic error, a broken edge case, an off-by-one. The anchor makes the boundary with Critical concrete: no breach, no crash, but the output is wrong.

HIGH = """
High: produces incorrect results or a test failure, but
does not breach security or crash production.

Example (off-by-one):
    for i in range(len(items) - 1):
        process(items[i])     # last item never processed
Why: range stops one element early; silent wrong output.
"""

Medium and Low — Anchor the Quiet End

The low end of the scale is where vague prompts leak the most false positives, so anchor it just as carefully.

  • Medium — maintainability or reliability risk that isn't yet a bug (a missing timeout, an unhandled-but-rare error path).
  • Low — style and naming only; no behavioral impact.

Defining Low explicitly is what lets you later say "don't report Low in pre-merge gates" without the model arguing.

MEDIUM = """
Medium: reliability or maintainability risk, not yet a bug.
Example:
    requests.get(url)        # no timeout -> can hang forever
"""

LOW = """
Low: style or naming only, no behavioral impact.
Example:
    def calc(x): return x*2  # name 'calc' is unclear
"""

Assemble the Rubric into the System Prompt

The anchored levels become one block in the system prompt. Keep this block stable and first — it's the same for every file you review, which makes it a perfect prompt-caching prefix. The per-file diff goes in the user turn, after the cached rubric.

import anthropic

client = anthropic.Anthropic()

system = [{
    "type": "text",
    "text": "You are a code reviewer.\n"
            + CRITICAL + HIGH + MEDIUM + LOW
            + "\nAssign exactly one level per finding using the\n"
              "rules and examples above. When unsure between two\n"
              "levels, pick the lower one.",
    "cache_control": {"type": "ephemeral"},
}]

Force Structure: Severity as an Enum

A written rubric tells the model how to decide; structured output guarantees the shape of the answer. Bind severity to a JSON Schema enum so the field can never be a free-text adjective like "prettyBad".

Exam rule to remember: mark a field required only if it is always present. severity and line always exist for a real finding, so they are required; an optional suggested_fix is not.

finding_schema = {
    "type": "object",
    "properties": {
        "line": {"type": "integer"},
        "severity": {
            "type": "string",
            "enum": ["critical", "high", "medium", "low"],
        },
        "rule": {"type": "string"},
        "suggested_fix": {"type": "string"},
    },
    "required": ["line", "severity", "rule"],
    "additionalProperties": False,
}

Wire the Rubric to the Review Call

Now combine the cached, anchored rubric with the enum-constrained schema in one request. The diff is the only volatile part, so it sits last in the user turn.

This pairing — explicit criteria for the decision, structured output for the format — is the exam's recommended pattern for reliable extraction and classification.

resp = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=4096,
    thinking={"type": "adaptive"},
    system=system,                      # cached rubric prefix
    output_config={
        "format": {
            "type": "json_schema",
            "schema": {
                "type": "object",
                "properties": {"findings": {
                    "type": "array", "items": finding_schema}},
                "required": ["findings"],
                "additionalProperties": False,
            },
        }
    },
    messages=[{"role": "user", "content": diff_text}],
)

Severity Drives Gating, Not the Model

Once severity is a clean enum, the decision to block a merge is deterministic code, not a model judgment. The model classifies; your pipeline thresholds.

This mirrors the exam's hook principle: when a failure has real consequences (a broken merge), enforce it with deterministic code, not a probabilistic prompt. The rubric makes the model's labels trustworthy enough to gate on.

import json

findings = json.loads(resp.content[0].text)["findings"]

BLOCKING = {"critical", "high"}
blockers = [f for f in findings if f["severity"] in BLOCKING]

if blockers:
    print(f"BLOCK MERGE: {len(blockers)} issue(s)")
    raise SystemExit(1)
print("OK to merge (medium/low only)")

Don't Let the Model Self-Filter Severity

One subtle trap: telling the model at the finding stage to "only report Critical and High" suppresses recall — it silently drops issues it judged lower, and you lose coverage you might have wanted.

The robust pattern: have the model report every finding with its severity, then filter in a separate downstream step (your BLOCKING set, or an independent review pass). Coverage first, ranking second. Anchored criteria are what make that downstream ranking reliable.

Quick Check: Anchoring Severity

Apply the lesson to a realistic design choice.

Recap: Criteria You Can Point To

Key takeaways:

  • Vague adjectives drift; written rules don't. Replace "important" with a testable condition per severity level.
  • Anchor every level with a code example. 2-4 targeted few-shot anchors calibrate the scale — the model generalizes from them.
  • Lock the label with an enum. Structured output makes severity always one of the valid values; require only fields that are always present.
  • Cache the rubric, vary the diff. Keep the stable criteria first in the system prompt; put the per-file code last.
  • Classify in the model, gate in code. Report all findings with severity, then filter/block deterministically downstream — never self-filter at the finding stage.

자주 묻는 질문

“예시를 활용한 심각도 기준” 강의는 무료인가요?

네 — “예시를 활용한 심각도 기준” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Claude Architect 강의 전체를 잠금 해제할 수 있습니다. Claude Architect 강의에는 총 4개의 강의가 포함되어 있습니다.

“예시를 활용한 심각도 기준”에서 뭘 배우나요?

각 심각도 수준을 코드 예시로 구체화합니다 브라우저에서 직접 실행하는 실습 코드로 Claude Architect을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Claude Architect을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Claude Architect은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.

“예시를 활용한 심각도 기준” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Claude Architect 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Claude Architect 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 모호한 지시보다 명시적인 기준
  2. 범주별 예시
  3. 예시를 활용한 심각도 기준
  4. 거짓 양성 줄이기
← Claude Architect(으)로 돌아가기