에이전트를 위한 Tool 경계: 언제 Tool을 호출할까 + Tool I/O 설계 방법 (시스템이 추측을 멈추게 하려면)
Source: Dev.to
문제
도구 경계를 정의하지 않으면, 에이전트는 프로덕션에서 두 가지 중 하나를 수행합니다:
- 과도한 호출: 모든 것에 대해 도구를 호출 → 느림, 비용 많이 들고, 시끄러움.
- 부족한 호출: 도구를 거의 호출하지 않음 → 자신감 있는 환각.
“도구 호출은 ‘데모 에이전트’가 사라지는 곳이다.”
최근 실패 사례
사용자가 물었습니다: “왜 내 주문이 배송되지 않았나요?”
- 에이전트는 주문 데이터를 가지고 있지 않아 *“날씨 지연”*이라고 추측했습니다.
- 그 후 자신감 있는 사과문을 작성하고 넘어갔습니다.
결과: 도구 호출도, 검증도 없고, 분위기만 있었습니다.
해결책
도구 사용을 계약으로 전환했습니다.
다음 실행에서 에이전트가 말했습니다:
“주문 상태를 확인할 수 있습니다. 주문 ID가 무엇인가요?”
누락된 전제 조건을 요청하고, 준비가 되면 도구를 호출하며, 실패를 깔끔하게 처리했습니다. 이것이 어시스턴트와 프로덕션 시스템의 차이점입니다.
Why this fails in production
Tool behavior breaks for two predictable reasons:
| Issue | Symptom |
|---|---|
| Over‑calling | Every question triggers a tool → latency, cost, messy traces |
| Under‑calling | The agent answers without required data → hallucinations with confidence |
In production you need tool usage that is:
- Testable – you can write evals for it.
- Auditable – you can trace and debug it.
- Repeatable – it behaves the same across runs.
This only happens when you treat tool usage like an API contract, not a suggestion.
정의 – “툴 경계”가 실제 의미하는 바
툴 경계는 다음을 결정하는 규칙입니다:
- Trigger – 툴을 반드시 호출해야 하는 경우와 절대 호출하면 안 되는 경우.
- Prerequisites – 호출 전에 필요한 입력(예: order_id, query, file_id, …).
- I/O Contract – 툴 입력에 대한 엄격한 JSON 및 출력에 대한 엄격한 JSON.
- Failure Policy – 재시도 vs 사용자에게 문의 vs 대체 vs 에스컬레이션.
- Auditability – 로그에 기록할 항목(trace_id, tool_name, latency, status, cost).
이를 정의하면 에이전트가 진행 중에 임의로 워크플로를 만들어내는 일을 멈춥니다.
드롭‑인 표준 (복사/붙여넣기) – 툴 경계 계약
시스템 프롬프트 또는 라우터‑에이전트 지시문에 붙여넣으세요.
TOOL BOUNDARY STANDARD (binding rules)
You may call tools only when the user's goal cannot be satisfied safely with internal reasoning alone.
1) MUST_CALL conditions:
- The answer requires private/user‑specific data (account, orders, tickets, files, DB records).
- The answer requires up‑to‑date or externally verifiable facts (news, prices, weather, availability).
- The answer requires computation or transformation best done by a tool (calc, parsing, file ops).
- The agent has insufficient inputs and the tool is the only way to obtain them.
2) MUST_NOT_CALL conditions:
- The user is asking for explanation, brainstorming, writing, or strategy that does not depend on external data.
- Tool prerequisites are missing (e.g., no order_id, no query, no file_id).
- A tool result would not materially change the answer.
3) BEFORE_CALL checklist:
- Identify required tool inputs.
- If missing: ask ONE targeted question to obtain them.
- Choose exactly ONE tool. Do not chain tools unless explicitly needed.
4) TOOL_IO:
- Tool inputs MUST match the declared JSON schema.
- Tool outputs MUST be treated as source of truth.
- Never fabricate tool outputs.
5) ON_ERROR policy:
- If retryable (timeout/429): retry up to 2 times with backoff.
- If not retryable (4xx validation): ask for corrected input.
- If tool unavailable: provide a safe fallback + explicit limitation + next step.
Router decision schema (strict JSON)
가장 작은 스키마로, 도구 호출 평가에 친화적입니다.
{
"decision": "CALL_TOOL | ASK_USER | ANSWER_DIRECT | REFUSE",
"reason": "string",
"tool_name": "string | null",
"tool_input": "object | null",
"missing_inputs": ["string"],
"success_criteria": ["string"],
"fallback_plan": ["string"]
}
다른 작업을 하지 않고 이 스키마를 강제 적용하십시오. 이는 에이전트가 결정을 확정하도록 하여 “도구 분위기”를 없애줍니다.
도구 I/O 템플릿 (도구당)
모든 도구는 자동으로 생성되더라도 다음과 같이 요구사항을 공개해야 합니다.
{
"tool_name": "string",
"required_inputs": ["string"],
"optional_inputs": ["string"],
"input_example": {},
"output_schema": {},
"error_shapes": [
{ "type": "timeout", "retryable": true },
{ "type": "validation_error", "retryable": false }
]
}
이는 고전적인 실패를 방지합니다: “도구가 반쯤 입력된 상태로 호출 → 쓰레기 같은 출력 → 하위 시스템 혼란.”
예시
1️⃣ RAG 또는 직접 답변?
사용자: “임베딩과 재랭커의 차이점을 설명해 주세요.”
| 결과 | 판정 | 이유 |
|---|---|---|
| ✅ ANSWER_DIRECT | 좋음 | 외부/사용자 특정 데이터가 필요 없으며, 단순히 설명을 제공하면 됩니다. |
| ❌ CALL_TOOL | 나쁨 | “검색해 보겠습니다…”는 지연을 초래하고 가치가 없습니다. 경계: 개념적 설명에 대해 MUST_NOT_CALL. |
2️⃣ 사용자‑특정 데이터 → 도구가 필수
사용자: “왜 내 주문이 배송되지 않았나요?”
| 결과 | 판정 | 이유 |
|---|---|---|
| ✅ ASK_USER → CALL_TOOL | 좋음 | order_id를 요청하고, get_order_status(order_id)를 호출한 뒤 결과를 기반으로 설명합니다; 정책에 따라 실패를 처리합니다. |
| ❌ ANSWER_DIRECT | 나쁨 | “아마도 날씨 지연 때문일 겁니다” → 환각. 답변이 개인 데이터에 의존할 경우 MUST_CALL. |
3️⃣ 전제 조건 누락 (추측 금지)
사용자: “로그를 확인해 주세요”
| 결과 | 판정 | 이유 |
|---|---|---|
| ✅ ASK_USER | 좋음 | 필요한 로그 식별자를 요청하고, 적절한 로그 가져오기 도구를 호출합니다. |
| ❌ ANSWER_DIRECT | 나쁨 | 추측은 의미 없는 결과를 초래합니다. |
TL;DR
툴 사용을 계약으로 간주하세요.
- Define when a tool must be called and when it must not. → 툴을 언제 호출해야 하는지와 언제 호출하면 안 되는지 정의합니다.
- Require all inputs before a call; ask the user if anything is missing. → 호출 전에 모든 입력을 요구하고, 누락된 것이 있으면 사용자에게 물어봅니다.
- Enforce strict JSON I/O and a clear error‑handling policy. → 엄격한 JSON 입출력 및 명확한 오류 처리 정책을 강제합니다.
- Log everything for auditability. → 감사 가능성을 위해 모든 것을 로그합니다.
Copy the Tool Boundary Contract and Router decision schema into your system prompt, and your agents will stop guessing and start behaving like reliable software. → Tool Boundary Contract와 Router decision schema를 시스템 프롬프트에 복사하면, 에이전트가 추측을 멈추고 신뢰할 수 있는 소프트웨어처럼 동작하게 됩니다.
도구 사용 지침
✅ 좋은 경우 (ASK_USER)
- “로그 발췌를 붙여넣거나
trace_id를 공유하세요.” - 그런 다음 올바른 도구/분석 경로로 라우팅합니다.
❌ 나쁜 경우 (CALL_TOOL)
- 빈 입력으로 “로그 도구”를 호출합니다.
- 혹은 그럴듯한 스택 트레이스를 만들어냅니다.
- 경계 초과: 전제 조건이 없을 때
MUST_NOT_CALL.
Example 4 – Handling Tool Errors
Tool returns:
{
"status": "error",
"error_type": "timeout",
"message": "upstream timed out"
}
✅ Good
- 최대 2 회 재시도합니다.
- 여전히 실패하면: 제한 사항과 다음 단계를 설명합니다.
- 사용자에게 제공할 대체 방안을 제시합니다 (수동 확인, 나중에 재시도, 대체 소스).
❌ Bad
- 작동한 것처럼 가장합니다.
- “Your order is delivered” (치명적).
Boundary hit: 도구 출력물을 절대로 조작하지 마세요; ON_ERROR를 적용합니다.
What Can Be Automated Safely (without losing correctness)
Once boundaries are explicit, automation becomes safe:
- Tool‑registry generation from code (필수 입력, 출력 스키마, 오류 형태).
- Tool‑call linting (필수 입력이 없을 때 호출 차단).
- Boundary‑based routing (라우터 에이전트가 엄격한 JSON을 출력).
- Structured traces (
trace_id,tool_name, 지연 시간, 상태, 비용). - Eval harness
MUST_CALL와MUST_NOT_CALL결정에 사용. - Fallback templates 타임아웃 / 429 / 검증 오류에 대한 대체 템플릿.
Here teams stop “debugging prompts” and start debugging systems.
HuTouch + Work2.0 (새로운 빌딩 방식)
저는 HuTouch를 구축하여 AI‑엔지니어 라우터, 스코프, 스키마 및 평가 세트에 대한 프롬프트 설계의 지루한 부분을 자동화하고, 기본적으로 에이전트에 가드레일이 적용되도록 합니다.
작동 방식:
지침 및 프롬프트 설계
Work2.0 원칙
- 노력과 가치를 혼동하지 마세요.
- 깊은 기술이 필요 없는 반복 가능한 단계를 자동화합니다.
- 실제로 중요한 일(그리고 삶)을 위해 시간을 회복합니다.
얼리 액세스 요청:
얼리 액세스 양식 링크
Quick Checklist (print this)
- 명시적인
MUST_CALL및MUST_NOT_CALL규칙이 있나요? - 모든 도구가
required_inputs와output_schema를 선언하고 있나요? - 라우터가 엄격한 JSON을 반환하나요 (
CALL_TOOL/ASK_USER/ANSWER_DIRECT/REFUSE)? - 전제 조건이 없을 때 도구 호출을 차단하나요?
- 오류 정책이 있나요 (재시도 / 사용자에게 문의 / 대체 / 에스컬레이션)?
- 도구 호출이 감사 가능합니까 (
trace_id, latency, status, cost)? - 나쁜 행동을 강제하려는 평가 프롬프트로 경계 테스트를 수행하나요?
