본문으로 건너뛰기

조회하고 진단하기

앞선 문서들에서는 실행 중에 기록을 수집하고, 아티팩트를 등록하며, 여러 후보의 측정값을 비교했습니다.

이 문서에서는 새 점수를 계산하는 과정이 넘어, 로컬 워크스페이스에 이미 저장된 실행과 기록을 다시 읽어 다음 질문에 답하는 과정을 설명합니다.

  • 어떤 실행이 저장되어 있나요?
  • 한 실행에는 어떤 단계와 기록이 포함되어 있나요?
  • 평가 결과는 저장된 기록에서 다시 확인할 수 있나요?
  • 실행 기록에서 빠졌거나 확인해야 할 부분이 있나요?

실행 가능한 예제

아래의 예제를 통해 Contexta가 어떻게 실행을 조회하고 진단하는지 알아봅시다.

"""Query a measured model run and diagnose missing package-stage evidence."""

from pathlib import Path

from sklearn.datasets import load_diabetes
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
from sklearn.model_selection import train_test_split

from contexta import Contexta
from contexta.contract import MetricPayload, MetricRecord, Project, RecordEnvelope, Run, StageExecution


PROJECT_NAME = "diabetes-review"
RUN_NAME = "linear-candidate"
RUN_REF = f"run:{PROJECT_NAME}.{RUN_NAME}"
STARTED_AT = "2026-05-27T09:00:00Z"
ENDED_AT = "2026-05-27T09:05:00Z"


def metric_record(metric_key: str, value: float, stage_name: str, record_name: str) -> MetricRecord:
stage_ref = f"stage:{PROJECT_NAME}.{RUN_NAME}.{stage_name}"
return MetricRecord(
envelope=RecordEnvelope(
record_ref=f"record:{PROJECT_NAME}.{RUN_NAME}.{record_name}",
record_type="metric",
recorded_at=ENDED_AT,
observed_at=ENDED_AT,
producer_ref="sdk.python.local",
run_ref=RUN_REF,
stage_execution_ref=stage_ref,
),
payload=MetricPayload(
metric_key=metric_key,
value=value,
value_type="float",
unit="ratio" if metric_key == "r2" else "rows",
aggregation_scope="stage",
subject_ref=stage_ref,
summary_basis="raw_observation",
),
)


features, targets = load_diabetes(return_X_y=True)
train_x, test_x, train_y, test_y = train_test_split(
features, targets, test_size=0.2, random_state=42
)
model = LinearRegression().fit(train_x, train_y)
r2 = r2_score(test_y, model.predict(test_x))

workspace = Path(".contexta")
ctx = Contexta(workspace=str(workspace), config={"project_name": PROJECT_NAME})
metadata = ctx.metadata_store

try:
metadata.projects.put_project(
Project(project_ref=f"project:{PROJECT_NAME}", name=PROJECT_NAME, created_at=STARTED_AT)
)
metadata.runs.put_run(
Run(
run_ref=RUN_REF,
project_ref=f"project:{PROJECT_NAME}",
name=RUN_NAME,
status="completed",
started_at=STARTED_AT,
ended_at=ENDED_AT,
)
)
for order, stage_name in enumerate(("train", "evaluate", "package")):
metadata.stages.put_stage_execution(
StageExecution(
stage_execution_ref=f"stage:{PROJECT_NAME}.{RUN_NAME}.{stage_name}",
run_ref=RUN_REF,
stage_name=stage_name,
status="completed",
started_at=STARTED_AT,
ended_at=ENDED_AT,
order_index=order,
)
)

ctx.record_store.append(metric_record("training.rows", float(len(train_x)), "train", "training-rows"))
ctx.record_store.append(metric_record("r2", r2, "evaluate", "r2"))
# No package-stage metric is written: diagnostics should make this gap visible.

runs = ctx.list_runs(PROJECT_NAME)
snapshot = ctx.get_run_snapshot(RUN_REF)
queried_r2 = next(record.value for record in snapshot.records if record.key == "r2")
diagnostics = ctx.diagnose_run(RUN_REF)

print(f"Queried runs: {', '.join(run.run_id for run in runs)}")
print(f"Snapshot: {len(snapshot.stages)} stages, {len(snapshot.records)} records")
print(f"Queried r2: {queried_r2:.3f}")
print(f"Diagnostics issues: {len(diagnostics.issues)}")
for issue in diagnostics.issues:
print(f"- {issue.severity}: {issue.code} ({issue.subject_ref})")
finally:
metadata.close()

코드를 query_diagnostics.py로 저장한 뒤, Contexta가 설치된 환경에서 실행하세요.

uv run query_diagnostics.py

이 예제에서는 package 단계에 일부러 메트릭 기록을 남기지 않습니다.


예제에서 수행하는 조사 흐름


이 예제에는 기록 생성과 기록 조회가 함께 들어 있습니다. 각 부분의 역할은 다음과 같습니다.

코드 구간역할
LinearRegression().fit(...)r2_score(...)실제 학습 모델의 평가값을 계산합니다.
metadata.projects.put_project(...)조회할 프로젝트의 기준점을 표준 스토어에 저장합니다.
metadata.runs.put_run(...)평가 결과가 속하는 실행을 저장합니다.
metadata.stages.put_stage_execution(...)train, evaluate, package 단계를 저장합니다.
ctx.record_store.append(...)계산한 r2와 학습 데이터 행 수를 각 단계의 메트릭 기록으로 저장합니다.
ctx.list_runs(PROJECT_NAME)프로젝트에 저장된 실행 목록을 조회합니다.
ctx.get_run_snapshot(RUN_REF)실행의 단계와 기록을 하나의 스냅샷으로 조립해 읽습니다.
ctx.diagnose_run(RUN_REF)스냅샷의 기록 구성을 검사해 확인할 항목을 찾습니다.

실행 결과 확인하기

머신러닝 예제에서는 터미널에 다음과 같은 출력이 표시됩니다.

Queried runs: run:diabetes-review.linear-candidate
Snapshot: 3 stages, 2 records
Queried r2: 0.453
Diagnostics issues: 1
- info: missing_stage_metrics (stage:diabetes-review.linear-candidate.package)

이 예제는 diabete 데이터셋을 사용하여 선형 회귀를 진행한 결과를 기반으로 여러가지 조회와 진단이 이루어집니다.

출력의미
Queried runsctx.list_runs(...)가 표준 메타데이터 스토어에서 찾은 실행입니다.
Snapshot: 3 stages, 2 records저장된 실행에는 train, evaluate, package 세 단계가 있지만 메트릭 기록은 두 개뿐입니다.
Queried r2ctx.get_run_snapshot(...)으로 불러온 저장 기록 중 r2 값을 다시 읽은 결과입니다.
Diagnostics issues: 1ctx.diagnose_run(...)이 이 실행에서 확인할 항목을 한 건 발견했습니다.
missing_stage_metricspackage 단계가 완료로 저장되었지만, 그 단계에 연결된 메트릭 기록이 없습니다.

실행 목록 조회


runs = ctx.list_runs(PROJECT_NAME)

이 조회는 특정 프로젝트에 어떤 실행이 저장되어 있는지 확인하는 시작점입니다.

예제에서는 run:diabetes-review.linear-candidate 한 건만 저장했으므로, 터미널에도 그 실행 하나가 표시됩니다.

실제 프로젝트에서는 이 목록에서 조사하려는 실행을 고른 뒤, 실행 참조를 get_run_snapshot() 또는 diagnose_run()에 전달할 수 있습니다.


실행 스냅샷 조회


snapshot = ctx.get_run_snapshot(RUN_REF)
queried_r2 = next(record.value for record in snapshot.records if record.key == "r2")

스냅샷은 해당 실행에 연결된 단계 · 레코드 · 아티팩트 · 배치 · 샘플 · 배포와 같은 재료를 한 위치에서 읽을 수 있게 조립한 결과입니다.


이 예제에서는 다음과 같은 구조가 조회됩니다.

run:diabetes-review.linear-candidate
├─ stage:train
│ └─ metric: training.rows = 353
├─ stage:evaluate
│ └─ metric: r2 = 0.453
└─ stage:package
└─ metric: 없음

따라서 Queried r2: 0.453은 실제로 계산되어 스토어에 저장된 메트릭 기록을 스냅샷에서 다시 찾아 읽은 값입니다.


실행 진단


diagnostics = ctx.diagnose_run(RUN_REF)

for issue in diagnostics.issues:
print(issue.severity, issue.code, issue.subject_ref)

진단은 스냅샷에 저장된 구조와 기록을 검사합니다. 기본 정책에서는 완료된 단계에 메트릭 기록이 있는지 살펴봅니다.

이 예제의 train 단계에는 training.rows가 있고, evaluate 단계에는 r2가 있으므로 문제가 없습니다.

하지만 package 단계는 completed 상태이지만 연결된 메트릭 기록을 일부러 남기지 않았습니다. 그 결과 아래 이슈가 반환됩니다.

진단 필드읽는 방법
severityinfo실행 자체가 실패하지는 않았지만, 확인할 항목이 있습니다.
codemissing_stage_metrics완료된 단계에 메트릭 기록이 없습니다.
subject_refstage:diabetes-review.linear-candidate.package어느 단계의 기록을 보완하거나 검토해야 하는지 가리킵니다.

여기서 r2 = 0.453이라는 성능 결과와 missing_stage_metrics라는 진단 결과는 서로 다른 질문에 답합니다.

기능답하는 질문
조회저장된 실행과 그 안의 기록은 무엇인가요?
비교여러 실행의 측정 결과는 어떻게 달라졌나요?
진단저장된 기록에서 누락되었거나 의심스러운 지점은 어디인가요?

즉, 점수가 낮다고 자동으로 진단 이슈가 되는 것은 아닙니다.

반대로 점수가 좋더라도 필요한 단계 기록이 빠져 있다면, 결과를 승인하거나 전달하기 전에 그 빈 부분을 확인해야 합니다.


주요 조회 및 진단 API


API사용 시점
ctx.list_runs(...)프로젝트에 어떤 실행이 저장되어 있는지 찾을 때
ctx.get_run_snapshot(...)하나의 실행에 연결된 단계와 기록을 모아 읽을 때
ctx.compare_runs(...)두 저장 실행의 메트릭과 구조 차이를 볼 때
ctx.select_best_run(...)같은 메트릭 기준으로 후보 실행을 선택할 때
ctx.diagnose_run(...)누락, 불완전 상태, 실패한 하위 단위 같은 조사 단서를 찾을 때
ctx.traverse_lineage(...)실행, 결과물, 배포 사이의 연결을 따라갈 때
ctx.build_snapshot_report(...)조사 결과를 사람이 읽기 쉬운 리포트로 만들 때

관련 문서