소르테크
인턴·신입근거: AI가 더 똑똑하고 안정적으로 동작하도록 기능 개선
※ 실제 산출물이 아닌 AI 예측 시안입니다.
공고는 Google 인프라 위에서 Agentic AI 를 활용한 개발과 Google Cloud 운영·배포를 한 자리의 업무로 두고, AI 도구로 개발 생산성을 올리는 방식을 함께 만들어 가자고 적습니다. 이 포트폴리오는 그 운영 쪽을 골랐습니다. 입력이 사내 기록이 아니라 OpenTelemetry GenAI 규약을 따르는 공개 형식이라, 지원자가 오픈소스 에이전트를 직접 돌려 뽑은 트레이스로 면접에서 그대로 시연합니다. 다만 이 포트폴리오는 트레이스 비용 계산과 CLI 구현을 보여줍니다. Google Cloud 비용 최적화나 대규모 인프라 운영에 대한 전문성은 주장하지 않습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
Google 인프라 환경에 맞춰 Agentic AI 를 활용하고 Google Cloud 기반 인프라 운영과 배포를 담당한다고 주요업무에 적습니다. 모델을 만드는 자리가 아니라 돌아가는 에이전트를 운영하는 자리입니다.
AI 가 더 똑똑하고 안정적으로 동작하도록 기능을 개선한다고 주요업무 두 번째 줄에 적습니다. 무엇을 고칠지 정하려면 돌아간 결과가 숫자로 남아 있어야 합니다.
경력 무관으로 열려 있고 팀의 핵심 업무를 처음부터 직접 맡아 볼 수 있는 자리라고 적습니다. 규모가 큰 시스템보다 혼자 끝까지 만든 작은 도구가 그대로 근거가 됩니다.
AI Native 개발자가 명령 한 줄을 실행하면, 오픈소스 에이전트가 남긴 실행 트레이스를 읽어 스팬마다 토큰에 모델 단가를 곱해 실행 한 번의 비용을 내고, 작업별 비용 분포에서 잡은 기준선과 견줘 비용을 키운 실행을 원인별로 표로 냅니다. 원인 판정은 분포에서 나온 기준선이 정하고, 모델은 어느 스팬에서 비용이 불어났는지 트레이스 값을 들어 원인으로 적습니다.
저는 사내 업무에 오픈소스 에이전트를 붙여 쓰고 있습니다. OpenTelemetry 내보내기를 켜 둬서 실행 트레이스는 파일로 쌓이는데, 스팬이 하루 수천 줄이라 어느 작업이 돈을 쓰는지 열어 봐도 안 보입니다. 결제 화면은 하루 합계만 주고 작업 이름은 없습니다.
원인을 못 찾는 이유는 기록이 없어서가 아니라 합계가 작업 단위로 나뉘지 않기 때문입니다. 실행마다 비용을 계산해 같은 작업의 비용 분포와 견주면, 손볼 작업이 목록으로 좁혀집니다.
CLI 하나가 완결됩니다. 실행 트레이스 파일과 모델 단가표를 받아 스팬마다 비용을 계산해 실행 단위로 합치고, 작업별 비용 분포에서 잡은 기준선과 견줘 비용을 키운 실행을 원인과 같이 표로 냅니다. 클라우드 저장소 연동은 로컬 파일을 읽는 것으로 대신하고 3주차로 미룹니다.
재시도를 강제하거나 컨텍스트를 키우는 식으로 조건을 바꿔 직접 돌린 실행 60건과 규칙의 원인 판정을 맞춰 보고, 어느 조합에서 갈리는지 표로 냅니다. 자주 틀리는 조합은 기준선을 작업별로 나눕니다.
트레이스를 Google Cloud Storage 에서 직접 읽어 매일 돌고, 결과를 조회 API 로 내며 비용을 키운 실행의 비율이 기준을 넘으면 개발자에게 알립니다.
AI Native 개발자가 명령 한 줄을 실행하면 작업별 비용 순위가 나오고, 실행마다 계산한 비용과 그 작업의 중앙값이 같이 보입니다.
토큰 값이 비어 있는 도구 스팬, 입력 토큰이 극단으로 큰 스팬, 모델 표기가 흔들린 스팬을 섞은 트레이스 30종을 넘겨도 실행이 멈추지 않고, 단가를 붙이지 못한 실행은 미매핑으로 남습니다.
조건을 바꿔 직접 돌린 실행 60건으로 원인 판정의 일치율을 냅니다. 단, 정답과 데이터를 모두 작성자가 만든 합성 기준이라 성능 검증이 아니라 데모 조건 동작입니다.
위 수치는 지원자가 직접 돌린 실행의 자가채점이며 실제 운영 비용 적중률은 소르테크의 사내 에이전트 트레이스가 있어야 측정됩니다. 이 포트폴리오는 그 검증을 바로 돌릴 수 있는 상태로 만듭니다.
수치는 지원자가 만든 트레이스의 자가채점이라 성능 증명이 아닙니다. 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다.
조건을 알고 돌린 실행이라 잘 맞는 것이 당연합니다. 토큰 속성이 비어 있는 스팬과 출력 없이 끝난 오류 스팬을 트레이스에 남겨 쉬운 문제만 푸는 함정을 피합니다.
비용이 큰 실행이 곧 낭비라는 뜻은 아닙니다. 입력이 원래 큰 작업도 있으므로 판정을 결론으로 읽지 않게 실행 비용과 작업 중앙값을 항상 같이 냅니다.
자체 호스팅 모델은 토큰 단가가 0 이라 이 계산에서 비용이 잡히지 않습니다. GPU 시간으로 환산한 단가는 다른 축이므로 도입 단계 과제로 분리합니다.
단가는 자주 바뀌고 규약 속성 이름도 판올림마다 달라집니다. 단가표와 속성 이름 표를 코드 밖 파일로 두어 갱신이 코드 수정 없이 되게 합니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
OpenTelemetry GenAI 시맨틱 규약으로 내보낸 실행 스팬을 한 줄씩 편 표입니다. 오픈소스 에이전트에 OTLP 파일 내보내기를 켜면 지원자가 자기 실행으로 그대로 만들 수 있습니다. 토큰 속성이 비어 있는 스팬과 입력 토큰이 극단으로 큰 스팬, 모델 표기가 흔들린 스팬을 의도적으로 포함합니다.
| span_id | trace_id | parent_span_id | start_time | duration_ms | gen_ai_operation_name | gen_ai_agent_name | gen_ai_request_model_raw | gen_ai_usage_input_tokens | gen_ai_usage_output_tokens | span_status_code |
|---|---|---|---|---|---|---|---|---|---|---|
| sp-4a91c07-01 | tr-4a91c07 | — | 2026-08-18T09:02:11Z | 8,120 | invoke_agent | repo-triage | — | — | — | OK |
| sp-4a91c07-02 | tr-4a91c07 | sp-4a91c07-01 | 2026-08-18T09:02:11Z | 2,100 | chat | repo-triage | claude-haiku-4-5 | 12,400 | 640 | OK |
| sp-4a91c07-03 | tr-4a91c07 | sp-4a91c07-01 | 2026-08-18T09:02:14Z | 340 | execute_tool | repo-triage | — | — | — | OK |
| sp-4a91c19-01 | tr-4a91c19 | — | 2026-08-18T10:15:03Z | 41,230 | invoke_agent | repo-triage | — | — | — | OK |
| sp-4a91c19-02 | tr-4a91c19 | sp-4a91c19-01 | 2026-08-18T10:15:04Z | 21,400 | chat | repo-triage | claude-haiku-4-5 | 146,200 | 980 | OK |
아래 JSON Schema 에 맞는 OpenTelemetry GenAI 스팬 행을 더 만들어 주세요. {"type": "object", "properties": {"span_id": {"type": "string"}, "trace_id": {"type": "string"}, "parent_span_id": {"type": ["string", "null"]}, "start_time": {"type": "string"}, "duration_ms": {"type": "integer", "minimum": 0}, "gen_ai_operation_name": {"type": "string", "enum": ["invoke_agent", "chat", "execute_tool", "embeddings"]}, "gen_ai_agent_name": {"type": "string"}, "gen_ai_request_model_raw": {"type": ["string", "null"]}, "gen_ai_usage_input_tokens": {"type": ["integer", "null"], "minimum": 0}, "gen_ai_usage_output_tokens": {"type": ["integer", "null"], "minimum": 0}, "span_status_code": {"type": "string", "enum": ["OK", "ERROR", "UNSET"]}}, "required": ["span_id", "trace_id", "start_time", "duration_ms", "gen_ai_operation_name", "gen_ai_agent_name", "span_status_code"]} 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) gen_ai_usage_input_tokens 가 null 인 도구 실행 스팬, (2) 출력 토큰이 0 인 오류 스팬과 입력 토큰이 십수만에 이르는 스팬, (3) 같은 모델을 대소문자와 구분자만 바꿔 적은 gen_ai_request_model_raw, (4) 단가표에 없는 모델 이름. 한 trace_id 안에서 parent_span_id 가 같은 chat 스팬을 두 번 이상 두어 재시도가 계산으로 드러나게 하고, 판정 결과나 기준값은 열로 넣지 마세요. 생성한 행은 반드시 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도는 별도로 3건만 표시해 두세요.{"type": "object", "properties": {"span_id": {"type": "string"}, "trace_id": {"type": "string"}, "parent_span_id": {"type": ["string", "null"]}, "start_time": {"type": "string"}, "duration_ms": {"type": "integer", "minimum": 0}, "gen_ai_operation_name": {"type": "string", "enum": ["invoke_agent", "chat", "execute_tool", "embeddings"]}, "gen_ai_agent_name": {"type": "string"}, "gen_ai_request_model_raw": {"type": ["string", "null"]}, "gen_ai_usage_input_tokens": {"type": ["integer", "null"], "minimum": 0}, "gen_ai_usage_output_tokens": {"type": ["integer", "null"], "minimum": 0}, "span_status_code": {"type": "string", "enum": ["OK", "ERROR", "UNSET"]}}, "required": ["span_id", "trace_id", "start_time", "duration_ms", "gen_ai_operation_name", "gen_ai_agent_name", "span_status_code"]}모델별 100 만 토큰 단가를 적은 계수 표입니다. 판정을 담지 않고 곱셈의 계수로만 쓰이며, 공개된 가격표를 옮긴 것이라 지원자가 직접 채울 수 있습니다. 자체 호스팅 모델은 토큰 단가가 0 으로 들어옵니다.
| model_code | provider | input_usd_per_mtok | output_usd_per_mtok | context_window_tokens | effective_from |
|---|---|---|---|---|---|
| claude-haiku-4-5 | anthropic | 1 | 5 | 200,000 | 2026-01-05 |
| claude-sonnet-4-6 | anthropic | 3 | 15 | 1,000,000 | 2026-01-05 |
| claude-sonnet-5 | anthropic | 3 | 15 | 1,000,000 | 2026-06-24 |
| claude-opus-4-6 | anthropic | 5 | 25 | 1,000,000 | 2026-01-05 |
| claude-opus-4-7 | anthropic | 5 | 25 | 1,000,000 | 2026-02-18 |
아래 JSON Schema 에 맞는 모델 단가 행을 더 만들어 주세요. {"type": "object", "properties": {"model_code": {"type": "string"}, "provider": {"type": "string", "enum": ["anthropic", "self_hosted"]}, "input_usd_per_mtok": {"type": "number", "minimum": 0}, "output_usd_per_mtok": {"type": "number", "minimum": 0}, "context_window_tokens": {"type": "integer", "minimum": 0}, "effective_from": {"type": "string"}}, "required": ["model_code", "provider", "input_usd_per_mtok", "output_usd_per_mtok", "effective_from"]} 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) 토큰 단가가 0 인 자체 호스팅 모델, (2) 같은 계열인데 판올림마다 effective_from 이 다른 행, (3) 입력 단가와 출력 단가의 배수가 크게 다른 행. 이 표는 계수만 담습니다 — 어느 모델이 비싼지 같은 판정 열이나 기준값 열을 넣지 마세요. 생성한 행은 반드시 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도는 별도로 3건만 표시해 두세요.{"type": "object", "properties": {"model_code": {"type": "string"}, "provider": {"type": "string", "enum": ["anthropic", "self_hosted"]}, "input_usd_per_mtok": {"type": "number", "minimum": 0}, "output_usd_per_mtok": {"type": "number", "minimum": 0}, "context_window_tokens": {"type": "integer", "minimum": 0}, "effective_from": {"type": "string"}}, "required": ["model_code", "provider", "input_usd_per_mtok", "output_usd_per_mtok", "effective_from"]}| Python | CLI 본체의 언어입니다. 단가를 곱해 비용을 내는 계산과 작업별 분포에서 기준선을 잡는 코드가 여기 있습니다. |
| OpenTelemetry | 입력 형식입니다. GenAI 시맨틱 규약의 속성 이름을 그대로 컬럼으로 읽어, 규약을 따르는 어떤 에이전트의 트레이스든 같은 코드로 처리합니다. |
| FastAPI | 3주차에 판정 결과를 다른 도구가 읽어 갈 수 있게 내주는 조회 API 입니다. |
| TypeScript | 결과를 사내 도구에 붙일 때를 대비해 같은 형식의 JSON 으로도 냅니다. |
| React | 판정 결과를 표로 보는 확인 화면을 3주차에 붙입니다. |
| Google Cloud | 3주차에 트레이스를 저장소에서 직접 읽고 일정에 맞춰 CLI 를 돌립니다. |
| LLM | 판정이 끝난 뒤 어느 스팬에서 비용이 불어났는지 원인으로 적습니다. 비용과 기준선은 계산이 정합니다. |
✓ pass → 그대로 멈춰도 완결입니다. 더 키우려면 조건을 아는 실행으로 판정을 맞춰 보는 단계로 넘어갑니다.
✓ pass → 여기까지도 완결입니다. 더 키우려면 매일 자동으로 돌고 기준 초과 시 알리는 단계로 확장합니다.
에이전트 실행 한 번(트레이스 한 건)의 비용 판정입니다. 계산한 실행 비용과 그 작업의 기준선을 함께 남깁니다.
{"type": "object", "properties": {"verdict_id": {"type": "string"}, "trace_id": {"type": "string"}, "agent_task": {"type": "string"}, "cost_code": {"type": "string", "enum": ["within_band", "above_task_fence", "retry_cost_share_high", "oversized_context", "model_price_tier_shift", "usage_missing", "model_unmapped"]}, "run_cost_usd": {"type": ["number", "null"], "description": "그 trace_id 에 속한 스팬마다 gen_ai_usage_input_tokens 나누기 1,000,000 곱하기 input_usd_per_mtok 에 gen_ai_usage_output_tokens 나누기 1,000,000 곱하기 output_usd_per_mtok 을 더하고, 트레이스 단위로 합한 값입니다."}, "task_median_cost_usd": {"type": ["number", "null"], "description": "같은 gen_ai_agent_name 을 가진 트레이스들의 run_cost_usd 중앙값입니다."}, "task_upper_fence_usd": {"type": ["number", "null"], "description": "같은 작업의 run_cost_usd 3사분위수에 사분위 범위의 1.5 배를 더한 값입니다. 배수는 실행 옵션이며 작업별 절대 금액을 코드에 두지 않습니다."}, "retry_cost_share": {"type": ["number", "null"], "description": "한 트레이스 안에서 parent_span_id 와 gen_ai_request_model_raw 가 같은 chat 스팬 가운데 두 번째 이후 호출의 비용 합을 run_cost_usd 로 나눈 값입니다."}, "evidence": {"type": "array", "items": {"type": "object", "properties": {"dataset": {"type": "string", "enum": ["otel_genai_spans", "model_price_catalog"]}, "field": {"type": "string"}, "agg": {"type": ["string", "null"], "enum": ["count", "sum", "avg", "min", "max", null]}, "value": {"type": ["string", "number", "null"]}}, "required": ["dataset", "field", "value"]}}, "summary": {"type": "string"}, "hedge": {"type": ["string", "null"]}}, "required": ["verdict_id", "trace_id", "agent_task", "cost_code", "evidence", "summary"]}[
{
"verdict_id": "vd0001",
"trace_id": "tr-4a91c07",
"agent_task": "repo-triage",
"cost_code": "within_band",
"run_cost_usd": 0.0156,
"task_median_cost_usd": 0.0169,
"task_upper_fence_usd": 0.0521,
"retry_cost_share": 0,
"evidence": [
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_input_tokens",
"agg": null,
"value": 12400
},
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_output_tokens",
"agg": null,
"value": 640
},
{
"dataset": "model_price_catalog",
"field": "input_usd_per_mtok",
"agg": null,
"value": 1
},
{
"dataset": "model_price_catalog",
"field": "output_usd_per_mtok",
"agg": null,
"value": 5
}
],
"summary": "repo-triage 작업의 중앙값 부근이라 손댈 곳이 없습니다.",
"hedge": null
},
{
"verdict_id": "vd0002",
"trace_id": "tr-4a91c52",
"agent_task": "doc-writer",
"cost_code": "within_band",
"run_cost_usd": 0.015,
"task_median_cost_usd": 0.0151,
"task_upper_fence_usd": 0.0233,
"retry_cost_share": 0,
"evidence": [
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_input_tokens",
"agg": null,
"value": 8100
},
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_output_tokens",
"agg": null,
"value": 1380
},
{
"dataset": "model_price_catalog",
"field": "output_usd_per_mtok",
"agg": null,
"value": 5
}
],
"summary": "doc-writer 작업의 상한 울타리 안에서 돌았습니다.",
"hedge": null
},
{
"verdict_id": "vd0003",
"trace_id": "tr-4a91c31",
"agent_task": "doc-writer",
"cost_code": "within_band",
"run_cost_usd": 0.0155,
"task_median_cost_usd": 0.0151,
"task_upper_fence_usd": 0.0233,
"retry_cost_share": 0,
"evidence": [
{
"dataset": "otel_genai_spans",
"field": "gen_ai_request_model_raw",
"agg": null,
"value": "Claude Haiku 4.5"
},
{
"dataset": "model_price_catalog",
"field": "model_code",
"agg": null,
"value": "claude-haiku-4-5"
},
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_input_tokens",
"agg": null,
"value": 8200
},
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_output_tokens",
"agg": null,
"value": 1450
}
],
"summary": "모델 표기가 달랐지만 정규화 뒤 단가표의 같은 모델로 붙었고 비용도 작업 범위 안입니다.",
"hedge": null
},
{
"verdict_id": "vd0004",
"trace_id": "tr-4a91c19",
"agent_task": "repo-triage",
"cost_code": "oversized_context",
"run_cost_usd": 0.1511,
"task_median_cost_usd": 0.0169,
"task_upper_fence_usd": 0.0521,
"retry_cost_share": 0,
"evidence": [
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_input_tokens",
"agg": null,
"value": 146200
},
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_input_tokens",
"agg": "avg",
"value": 12012.5
},
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_output_tokens",
"agg": null,
"value": 980
},
{
"dataset": "model_price_catalog",
"field": "input_usd_per_mtok",
"agg": null,
"value": 1
}
],
"summary": "같은 작업의 평균 입력 토큰이 12,012.5 인데 이 실행만 146,200 이라 넣는 범위를 좁혀야 합니다.",
"hedge": null
},
{
"verdict_id": "vd0005",
"trace_id": "tr-4a91c23",
"agent_task": "repo-triage",
"cost_code": "retry_cost_share_high",
"run_cost_usd": 0.0392,
"task_median_cost_usd": 0.0169,
"task_upper_fence_usd": 0.0521,
"retry_cost_share": 0.602,
"evidence": [
{
"dataset": "otel_genai_spans",
"field": "span_id",
"agg": "count",
"value": 3
},
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_output_tokens",
"agg": null,
"value": 0
},
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_input_tokens",
"agg": null,
"value": 11800
},
{
"dataset": "model_price_catalog",
"field": "input_usd_per_mtok",
"agg": null,
"value": 1
}
],
"summary": "같은 부모 아래 세 번 호출됐고 출력 없이 끝난 두 번이 비용의 60%를 차지합니다.",
"hedge": null
},
{
"verdict_id": "vd0006",
"trace_id": "tr-4a91c44",
"agent_task": "doc-writer",
"cost_code": "model_price_tier_shift",
"run_cost_usd": 0.081,
"task_median_cost_usd": 0.0151,
"task_upper_fence_usd": 0.0233,
"retry_cost_share": 0,
"evidence": [
{
"dataset": "model_price_catalog",
"field": "model_code",
"agg": null,
"value": "claude-opus-5"
},
{
"dataset": "model_price_catalog",
"field": "output_usd_per_mtok",
"agg": null,
"value": 25
},
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_output_tokens",
"agg": null,
"value": 1520
}
],
"summary": "doc-writer 작업이 평소 쓰던 등급보다 출력 단가가 다섯 배인 모델로 돌았습니다.",
"hedge": "합성 기준 판정이라 품질 때문에 일부러 올려 잡은 실행일 수 있습니다."
},
{
"verdict_id": "vd0007",
"trace_id": "tr-4a91c68",
"agent_task": "log-summarizer",
"cost_code": "usage_missing",
"run_cost_usd": null,
"task_median_cost_usd": null,
"task_upper_fence_usd": null,
"retry_cost_share": null,
"evidence": [
{
"dataset": "otel_genai_spans",
"field": "gen_ai_usage_input_tokens",
"agg": null,
"value": null
},
{
"dataset": "otel_genai_spans",
"field": "gen_ai_operation_name",
"agg": null,
"value": "chat"
}
],
"summary": "토큰 사용량 속성이 비어 있어 비용을 계산하지 않고 판정에서 뺍니다.",
"hedge": null
},
{
"verdict_id": "vd0008",
"trace_id": "tr-4a91c60",
"agent_task": "log-summarizer",
"cost_code": "model_unmapped",
"run_cost_usd": null,
"task_median_cost_usd": null,
"task_upper_fence_usd": null,
"retry_cost_share": null,
"evidence": [
{
"dataset": "otel_genai_spans",
"field": "gen_ai_request_model_raw",
"agg": null,
"value": "mistral-large-2411"
},
{
"dataset": "model_price_catalog",
"field": "model_code",
"agg": "count",
"value": 11
}
],
"summary": "단가표에 실린 11 종 가운데 짝이 없는 모델이라 단가를 붙이지 못해 미매핑으로 남깁니다.",
"hedge": null
}
][자동 검증 · 코드가 판정합니다] 1. cost_code 가 enum 일곱 값 중 하나인지 확인합니다. 2. verdict_id·trace_id·agent_task·cost_code·evidence·summary 가 모두 채워졌는지 확인합니다. 3. gen_ai_usage_input_tokens 와 gen_ai_usage_output_tokens 가 0 이상인지, duration_ms 가 0 이상인지 확인합니다. 4. evidence 의 field 이름이 실행 트레이스나 단가표에 실재하는 컬럼인지 대조합니다. 5. agg 가 없는 evidence 의 value 가 그 span_id 행 또는 그 model_code 행의 값과 같은지 확인합니다. 6. run_cost_usd 를 evidence 의 토큰 수와 단가로 다시 계산해 소수점 넷째 자리까지 맞는지 확인합니다. 토큰이 비어 있으면 run_cost_usd 도 null 인지 확인합니다. 7. task_upper_fence_usd 가 그 작업 트레이스 비용의 3사분위수에 사분위 범위의 1.5 배를 더한 값과 같은지 다시 계산합니다. 8. summary 가 존댓말로 끝나는지 확인합니다. [평가 러너 · 2주차] 재시도를 강제하거나 컨텍스트를 키워 조건을 알고 돌린 실행 60건과 규칙의 cost_code 를 비교해 일치율과 갈리는 조합을 냅니다. [수동 검증 · 사람이 봅니다] 1. 평소보다 비싼 등급으로 돈 실행이 의도된 것인지 표본 20건을 눈으로 확인합니다. 2. 단가가 0 인 자체 호스팅 모델을 비용 순위에 넣을지 뺄지는 운영 기준을 따라 개발자가 정합니다.