도구 및 오류 안티 패턴
최소한의 설명, 지나치게 많은 도구 및 일반적인 오류를 다룹니다
도구 및 오류 안티 패턴은(는) CoddyKit의 무료 Claude Architect 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Claude Architect 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Claude Architect 강의에는 총 4개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
Why Tools and Errors Fail Quietly
Most agent failures aren't dramatic crashes. They're quiet misroutes: the model picks the wrong tool, or a tool fails with a vague message the model can't recover from. The agent then improvises, fabricates, or silently abandons the task.
This lesson dissects three anti-patterns that ship constantly in production:
- Minimal tool descriptions that leave the model guessing
- Too many tools per agent, which degrades selection reliability
- Generic error statuses that block intelligent recovery
Each one is a frequent wrong answer on the exam. Learn to spot and fix them.
Descriptions Are the Selection Mechanism
A common misconception: the model routes by tool name. It does not. The tool description is the primary selection mechanism. Names are labels; descriptions are where the model decides whether a tool fits the situation.
A minimal description like "Looks up an order" tells the model almost nothing. When two tools have thin, overlapping descriptions, the model misroutes — it calls lookup_order when it needed get_customer, and the whole agentic loop drifts.
Anatomy of a Strong Description
A good tool description carries five things:
- Purpose — what it does and when to use it
- Return values — the shape of what comes back
- Input formats with examples — concrete, not abstract
- Edge cases — empty results, ambiguity, multiple matches
- Applicability boundaries — when NOT to use it
That last point is what disambiguates overlapping tools. Below is the weak version most teams ship.
lookup_order = {
"name": "lookup_order",
# Anti-pattern: minimal, ambiguous description
"description": "Looks up an order.",
"input_schema": {
"type": "object",
"properties": {"id": {"type": "string"}},
"required": ["id"],
},
}Rewriting for Disambiguation
Now the strong version. Notice how the description states the input format with an example, the return shape, the empty-result case, and an explicit boundary that prevents collision with get_customer.
This is the single highest-leverage fix for misrouting: you change the description, not the model.
lookup_order = {
"name": "lookup_order",
"description": (
"Retrieve a single order by its order ID. "
"Input: order_id as a string like 'ORD-48213' (NOT a customer ID). "
"Returns: {order_id, status, items[], total, placed_at}. "
"If no order matches, returns an empty result (not an error). "
"Use get_customer first if you only have a name or email; "
"do NOT use this to look up a customer's full order history."
),
"input_schema": {
"type": "object",
"properties": {
"order_id": {"type": "string", "description": "e.g. 'ORD-48213'"}
},
"required": ["order_id"],
},
}Too Many Tools Degrades Selection
The second anti-pattern: handing one agent a giant toolbox. Selection reliability isn't constant — it degrades as the tool count grows.
- 4-5 tools per agent is the optimal range
- 18+ tools measurably degrades selection reliability
More tools mean more chances for overlapping descriptions, more surface area for ambiguity, and a longer list the model must reason over every turn. Breadth is not a feature here — it's a liability.
Scope Tools to the Role
The fix is architectural: scope tools to the role instead of giving every agent every capability. In a hub-and-spoke multi-agent system, the coordinator decomposes work and delegates to subagents — each subagent gets only the handful of tools its job needs, following least privilege.
A focused 4-tool support agent outperforms a 20-tool generalist because each tool is unambiguous within its small, role-scoped set.
support_agent = AgentDefinition(
name="order_support",
description="Handles order status and refund requests for a verified customer.",
system_prompt="You resolve order issues. Verify identity before any refund.",
# 4 tools, scoped to the role — not the whole company API
allowed_tools=[
"get_customer",
"lookup_order",
"process_refund",
"escalate_to_human",
],
)Split, Don't Stuff
When a workflow genuinely needs many capabilities, the answer is not one bloated agent — it's decomposition. Split responsibilities across role-scoped subagents and let the coordinator route between them.
Remember the multi-agent rule: subagents do not inherit the coordinator's conversation history. So when you delegate, pass all needed context explicitly in the subagent prompt. A clean split keeps each agent's tool set small AND keeps its context focused.
Generic Errors Block Recovery
The third anti-pattern lives in the error path. A tool that fails with "Operation failed" or a bare isError: true gives the model nothing to act on. It can't tell a transient network blip from a validation mistake from an empty result — so it either retries blindly, gives up, or fabricates an answer.
Generic error statuses block intelligent routing. Structured errors enable it.
# Anti-pattern: generic, unrecoverable error
return {
"isError": True,
"message": "Operation failed",
}Structured MCP Errors
A recoverable error carries structure. The MCP convention bundles the fields the model needs to decide what to do next:
isError: trueplus anerrorCategory: transient / validation / business / permissionisRetryable— should the model try again at all?message,attempted_query, andpartial_results
With these, the model routes intelligently: retry a transient fault, fix a validation error, escalate a permission denial, or surface partial results instead of nothing.
# Structured error: enables intelligent routing
return {
"isError": True,
"errorCategory": "transient", # transient|validation|business|permission
"isRetryable": True,
"message": "Order DB timed out after 5s",
"attempted_query": {"order_id": "ORD-48213"},
"partial_results": [],
}Failure Is Not the Same as Empty
One subtle distinction the exam loves: an access FAILURE (the tool couldn't run — timeout, permission) is not the same as a valid EMPTY result (the query ran fine and matched nothing).
Collapsing both into a generic error is a recovery-killer. A failure may be worth a retry; an empty result means "no matches" and should be reported as fact, not retried forever. Your lookup_order earlier got this right: no match returns an empty result, not an error.
Recover Locally, Escalate with Context
Put it together into an error-propagation strategy:
- Recover transient faults locally in the subagent — retry the timeout, don't bubble it up
- Escalate non-recoverable failures with structured context: failure type, attempted query, partial results, and alternatives
- Never silently suppress errors, and never abort the whole workflow because one subagent failed
The coordinator can then route around a single failed branch and still aggregate a useful answer — which is exactly what generic errors make impossible.
# Subagent error handling
if err["errorCategory"] == "transient" and err["isRetryable"]:
result = retry(call) # recover locally
else:
return { # escalate WITH context
"status": "failed",
"failure_type": err["errorCategory"],
"attempted_query": err["attempted_query"],
"partial_results": err["partial_results"],
"alternatives": ["try search_orders by date range"],
}Quick Check: Misrouting Fix
Apply the lesson to a concrete failure.
Recap: Three Anti-Patterns, Three Fixes
You can now spot and fix the tool-and-error anti-patterns that show up as wrong answers on the exam:
- Minimal descriptions cause misrouting. Fix: descriptions are the selection mechanism — state purpose, return values, input formats with examples, edge cases, and applicability boundaries.
- Too many tools degrade selection. Fix: 4-5 tools per agent is optimal, 18+ degrades reliability — scope tools to the role and split across subagents under least privilege.
- Generic errors block recovery. Fix: structured errors with errorCategory (transient/validation/business/permission), isRetryable, attempted_query, and partial_results — distinguish access failure from a valid empty result, recover transient faults locally, escalate the rest with context, and never silently suppress or abort the whole workflow.
자주 묻는 질문
“도구 및 오류 안티 패턴” 강의는 무료인가요?
네 — “도구 및 오류 안티 패턴” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Claude Architect 강의 전체를 잠금 해제할 수 있습니다. Claude Architect 강의에는 총 4개의 강의가 포함되어 있습니다.
“도구 및 오류 안티 패턴”에서 뭘 배우나요?
최소한의 설명, 지나치게 많은 도구 및 일반적인 오류를 다룹니다 브라우저에서 직접 실행하는 실습 코드로 Claude Architect을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Claude Architect을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Claude Architect은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.
“도구 및 오류 안티 패턴” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Claude Architect 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Claude Architect 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 루프 및 오케스트레이션 안티 패턴
- 도구 및 오류 안티 패턴
- 프롬프트 및 검토 안티 패턴
- 에스컬레이션 및 지표 안티 패턴