본문으로 건너뛰기

실패 분류

실패는 구조화되어야 합니다. product는 모든 실패를 "agent 실패" 하나로 뭉개면 안 됩니다.

이 taxonomy는 Planflow event, Quality Lab result, log, trace learning record에서 사용됩니다. 목표는 다음 액션을 분명하게 만드는 것입니다. search metadata를 고칠지, contract를 repair할지, 사용자 입력을 요청할지, auth를 설정할지, downstream API를 재시도할지, learning suggestion을 거절할지 바로 보여야 합니다.

Mental Model

Tool-call workflow의 실패는 stage, reason, evidence로 나누어 봅니다. 이 셋을 섞지 않는 것이 핵심입니다.

Field의미예시
stage실패가 발생한 위치synthesize, auth_preflight, execute
reason안정적인 machine-readable reason codeunsatisfied_field, auth_context_required
evidence디버깅에 필요한 compact proofmissing field, selected target, HTTP status

Exception message를 계약으로 쓰지 마세요. 메시지는 바뀔 수 있지만 reason code는 안정적으로 유지되어야 합니다.

Failure Lifecycle

Stage대표 Reason Codes보통 수정하는 곳
retrieveno_candidates, not_retrieved, low_confidencesemantic metadata, alias, OpenAPI summary, graph edge
select_targetllm_target_mismatch, llm_target_not_in_candidates, ambiguous_target, selector_mismatchtarget selector evidence, result shape, contract fit, LLM catalog prompt
synthesizeunknown_target, unsatisfied_field, enum_required, dynamic_option_required, cycle, max_depth, user_input_fallbackIO contract, producer edge, context default, user input UX
bind_requestbinding_failed, argument_coercion_failed, missing_required_argumentschema contract, field mapping, runtime argument builder
auth_preflightauth_context_required, auth_profile_missing, auth_header_resolution_failedcollection auth profile, product session, session header resolver
executeauth_failed, http_4xx, http_5xx, timeout, network_errordownstream API, request construction, credential, retry policy
cleanupcleanup_failed, cleanup_not_configuredQuality Lab mutation case owner
learnscrub_failed, promotion_rejected, insufficient_repeated_successtrace scrubbing, promotion policy, human review
serviceuncaught_server_erroradapter 또는 service bug

엔진은 product-neutral stage만 책임집니다. Product adapter는 transport나 UI-specific stage를 추가할 수 있지만, stage, reason, compact evidence는 보존해야 합니다.

Engine Synthesis Errors

PathSynthesizer는 synthesis 실패 시 PlanSynthesisError와 하위 exception을 발생시킵니다. Adapter는 exception 문자열을 파싱하지 말고 to_dict()를 호출해야 합니다.

from graph_tool_call.plan import PathSynthesizer, PlanSynthesisError

synthesizer = PathSynthesizer(graph_artifact)

try:
plan = synthesizer.synthesize(
target="getOrderDetail",
goal="주문 상세를 보여줘",
entities={},
)
except PlanSynthesisError as exc:
diagnostic = exc.to_dict()
# {"stage": "synthesize", "reason": "unsatisfied_field", ...}

to_dict()는 안정적인 envelope을 반환합니다.

{
"stage": "synthesize",
"reason": "unsatisfied_field",
"message": "required field cannot be supplied",
"field_name": "orderNo",
"semantic_tag": "order_id",
"target_tool": "getOrderDetail"
}

detail key는 reason에 따라 달라질 수 있습니다. 새 field는 additive로 취급하세요.

Reason Code Catalog

Search and Selection

Reason의미저장할 Evidence일반적인 조치
no_candidatesretrieval이 사용할 tool을 반환하지 못함query, filter, top_kcatalog build와 index coverage 점검
not_retrieved기대 target이 Top-K에 없음expected target, returned tool namessemantic metadata 또는 alias 보강
low_confidencecandidate score가 약함score distribution, thresholdTop-K 확대 또는 evidence 추가
llm_target_mismatchLLM이 기대 target과 다른 tool을 고름LLM target, expected target, selected targettarget selector diagnostic 확인
llm_target_not_in_candidatesLLM이 retrieved catalog 밖의 tool을 고름LLM target, candidate namesselector-ranked catalog를 LLM에 전달
ambiguous_target여러 tool의 evidence가 비슷함margin, tied candidates사용자 확인 또는 LLM target 유지
selector_mismatchdeterministic selector가 잘못된 target을 선택함rank signals, override flaggeneric selector policy 또는 metadata 조정

Plan Synthesis

Reason의미저장할 Evidence일반적인 조치
unknown_targettarget tool이 graph artifact에 없음target tool, graph versionartifact rebuild 또는 target selection repair
unsatisfied_fieldrequired consume field를 채울 수 없음field name, semantic tag, target toolproducer edge, context default, user slot 추가
enum_requiredrequired enum field 값이 선택되지 않음field name, safe enum valuesenum label mapping 또는 사용자 선택
dynamic_option_required누락 field의 runtime option을 가져올 producer가 있음producer name, options path, label hints최종 plan 전에 option picker 표시
cycletool dependency chain이 같은 tool을 다시 방문함chain, tool namegraph edge와 producer ranking 점검
max_depthdependency search가 synthesizer depth를 초과함max depth, current toolgraph noise를 줄이거나 depth를 의도적으로 조정
user_input_fallbackplanner가 사용자 입력 슬롯으로 계속 진행함field name, required flagUX slot 또는 context default 추가

Auth and Execution

ReasonAPI 호출 여부의미일반적인 조치
auth_context_requirednoauth가 필요하지만 runtime user/session context가 없음로그인 UI 또는 service account에서 실행
auth_profile_missingnocollection/tool은 auth가 필요한데 profile이 없음collection auth profile 설정
auth_header_resolution_failednoprofile은 있지만 adapter가 header를 만들지 못함session header resolver 점검
auth_failedyesdownstream API가 401 또는 403 반환credential refresh 또는 downstream policy 점검
http_4xxyesdownstream API가 request를 거절함request argument와 business validation 확인
http_5xxyesdownstream API server-side 실패안전할 때만 retry, API log 확인
timeoutmayberequest가 timeout을 초과함timeout, paging, downstream latency 점검
network_errormaybe유의미한 HTTP response 전에 transport 실패DNS, TLS, proxy, allowlist 확인

Quality Lab and Learning

Reason의미일반적인 조치
cleanup_failedmutating validation case가 상태를 원복하지 못함case 활성화 전에 cleanup step 수정
cleanup_not_configuredmutating execute case에 cleanup plan이 없음case를 비활성으로 두거나 cleanup 추가
scrub_failedtrace payload를 안전하게 compact하지 못함learning record 거절
insufficient_repeated_successpromotion threshold를 아직 만족하지 못함shadow mode 유지
promotion_rejected사람 또는 policy가 suggestion을 거절함rejection reason 저장, boost 적용 금지

Normalized Failure Record

Adapter는 Quality Lab result, log, learning attempt에 저장하기 전에 실패를 compact record로 정규화해야 합니다.

{
"stage": "synthesize",
"reason": "unsatisfied_field",
"message": "Required field orderNo cannot be supplied",
"tool": "getOrderDetail",
"plan_id": "plan_01HZ...",
"step_id": null,
"retryable": false,
"operator_action": "ask_user_or_add_context_default",
"evidence": {
"field_name": "orderNo",
"semantic_tag": "order_id",
"target_tool": "getOrderDetail"
}
}

retryable은 신중하게 설정하세요. Auth header refresh, network error, 5xx response는 retry 가능할 수 있습니다. 사용자 입력 누락, auth profile 누락, unsupported contract는 product action 없이는 보통 retryable이 아닙니다.

Runner Event Example

Runner event는 transport-neutral data입니다. XGEN 같은 adapter는 보통 dataclasses.asdict(event)를 SSE, log, Quality Lab result로 forwarding합니다.

{
"type": "step.failed",
"stage": "execute",
"plan_id": "plan_01HZ...",
"step_id": "step_2",
"tool": "getOrderDetail",
"graph_tool_call_version": "0.32.1",
"trace_metadata": {
"failure_reason": "http_4xx",
"http_status": 400,
"auth_readiness": {
"required": true,
"auth_profile_id_present": true,
"session_station_header_names": ["Authorization"],
"failure_reason": null
}
}
}

Event에는 추가 field가 들어갈 수 있습니다. Consumer는 자신이 이해하는 field만 읽고, 알 수 없는 metadata는 forwarding할 때 보존하는 편이 안전합니다.

Security Boundary

Failure record에는 raw credential이나 개인정보를 저장하면 안 됩니다. Boolean, header name, field path, status, scrub된 value만 저장합니다.

저장 가능저장 금지
xgen_auth_token_present: truebearer token value
session_station_header_names: ["Authorization"]Authorization: Bearer ...
field_name: "orderNo"raw order response body
http_status: 403cookie 또는 API key
session_id_hashraw user id, email, phone number

이 boundary는 failure record가 나중에 trace learning input으로 쓰이기 때문에 특히 중요합니다.

Triage Guide

증상먼저 볼 것보완
expected tool이 Top-K에 없음retrieval evidence와 semantic metadataalias, summary, contract, graph edge 개선
expected tool은 Top-K에 있는데 선택 안 됨target_selector.rank_signals와 LLM targetaction/resource/shape evidence 또는 selector policy 개선
obvious field인데 plan이 사용자 입력을 요청함api_contract.consumes, producer edge, context defaultcontext default, field mapping, producer 추가
API 호출 전에 execute가 차단됨auth_readiness.failure_reasonauth profile 또는 session header resolution 설정
API가 401/403 반환downstream request header name과 auth profile freshnessauth refresh 또는 downstream policy 점검
API가 400 반환rendered request argumentschema binding, enum mapping, user input 수정
write case가 data를 남김cleanup resultmutation 허용 전에 cleanup assertion 추가
실패 후 재시도에서 반복 성공함learning attempt와 suggestionpromotion gate 통과 전까지 shadow 유지

Quality Lab Assertions

Quality Lab은 pass/fail boolean만 보지 말고 failure reason을 assertion해야 합니다.

{
"mode": "execute",
"query": "주문 상세를 보여줘",
"expected_target": "getOrderDetail",
"assertions": {
"selected_target": "getOrderDetail",
"allowed_failure_reasons": [
"auth_context_required",
"auth_failed",
"http_4xx"
],
"uncaught_server_error": false
}
}

이렇게 하면 credential이 없는 dev collection도 유용합니다. Search와 plan이 동작한다는 것을 증명하고, execute는 server error가 아니라 알려진 auth reason으로 실패해야 합니다.

검증

Runner, plan, auth, Quality Lab test에 failure taxonomy assertion을 둡니다.

poetry run pytest tests/ -q -k "failure or quality_lab or runner or auth"

문서만 수정한 경우에도 아래를 실행합니다.

cd website
npm run typecheck
npm run build

관련 문서