pcq 실험 contract

Apache-2.0 · Python · MCP 지원

당신의 AI 에이전트에게는 evidence가 필요하다.
당신의 실험에는 contract가 필요하다.

pcq가 그 contract입니다. cq.yaml이 실행을 선언하고, 학습 코드는 그대로 둡니다. pcq는 매 실행을 구조화된 evidence로 바꿉니다 — config, metrics, manifest, validation, lineage, run record. 그리고 14개의 Model Context Protocol 도구를 노출해서 Claude Code, Codex, 또는 MCP 호환 에이전트가 stdout을 파싱하지 않고도 그 evidence를 읽을 수 있게 합니다.

PyPI 버전 월간 다운로드 License: Apache-2.0 CI 상태 (main 브랜치) Glama에서 검증된 pcq MCP server
pcq agent install --target both --mcp

Connect

명령 하나. 두 runtime. 동일한 표면.

연결 절차는 Claude Code, Codex, 그리고 모든 MCP 호환 runtime에 대해 동일합니다 — --target 플래그만 다릅니다. 기존 .mcp.json 항목은 보존되고, pcq 서버만 추가됩니다.

Claude Code · Codex · 모든 MCP runtime

stdio · sse

설치 & 실행

uv add 'pcq[mcp]'
pcq agent install --target both --mcp     # 또는: --target claude / --target codex
pcq mcp serve                             # stdio 기본; HTTP는 --transport sse --port 8765

.mcp.json (프로젝트 루트)

{
  "mcpServers": {
    "pcq": {
      "command": "pcq",
      "args": ["mcp", "serve"]
    }
  }
}

첫 호출: inspect_project

{
  "schema_version": 1,
  "project_root": "/path/to/my-exp",
  "selected_yaml": "cq.yaml",
  "name": "sklearn-baseline",
  "cmd": "uv run python train.py",
  "metrics": ["epoch", "eval_acc"],
  "output_dir": "output",
  "artifacts": ["output/"]
}

--target both는 Claude Code와 Codex 두 runtime의 Model Context Protocol 연결을 한 번에 처리합니다. 다른 MCP 호환 runtime도 마찬가지 — pcq mcp serve를 가리키게 하면 됩니다. 14개의 read-only / mutating 도구는 에이전트 매니페스트Tools → 섹션에 모두 나열되어 있습니다.

도구 응답 · 실제 캡처

당신의 에이전트가 받는 응답.

아래 네 개는 examples/contract_sklearn의 실제 실행에서 캡처한 MCP 도구 응답입니다. 환경 종속 필드 (timestamps, git SHA, env hash, 절대 경로)만 "..."로 축약했고, 구조와 값은 변경하지 않았습니다. JSON contracts →

describe_run

read-only

호출

pcq describe-run output --json
# MCP: mcp__pcq__describe_run({"path": "output"})

응답

{
  "schema_version": 1,
  "run_id": "run_20260510_001107_c87d7d",
  "name": "sklearn-iris-contract",
  "status": "completed",
  "output_dir": "...",
  "cmd": "uv run python train.py",
  "target_metric": "eval_acc",
  "mode": "max",
  "best":  { "epoch": 0, "value": 1.0, "metrics": {"eval_acc": 1.0}, "checkpoint": "best.ckpt" },
  "best_value": 1.0,
  "best_epoch": 0,
  "last":  { "epoch": 0, "value": 1.0, "metrics": {"eval_acc": 1.0}, "checkpoint": "last.ckpt" },
  "epochs_completed": 1,
  "partial": false,
  "last_updated_at": "...",
  "git_sha": "...",
  "dirty": true,
  "python": "3.12.10",
  "platform": "Darwin-arm64",
  "metrics_declared": [{"name": "epoch"}, {"name": "eval_acc"}],
  "artifacts": [
    {"path": "config.json",      "kind": "config",  "sha256": "...", "size_bytes": 250,    "created_at": "..."},
    {"path": "metrics.json",     "kind": "metrics", "sha256": "...", "size_bytes": 74,     "created_at": "..."},
    {"path": "model.pkl",        "kind": "model",   "sha256": "...", "size_bytes": 186929, "created_at": "..."},
    {"path": "run_summary.json", "kind": "summary", "sha256": "...", "size_bytes": 586,    "created_at": "..."}
  ],
  "artifacts_summary": {"config": 1, "metrics": 1, "model": 1, "summary": 1},
  "validation_status": "pass",
  "decision_facts": {
    "run_completed": true,
    "validation_passed": true,
    "has_target_metric": true,
    "has_best": true,
    "has_parent": false,
    "artifact_count": 4,
    "metric_count": 2,
    "dirty_source": true,
    "has_lockfile": true
  }
}

compare_runs

read-only

호출

pcq compare-runs output_a output_b --json
# MCP: mcp__pcq__compare_runs({"a": "output_a", "b": "output_b"})

응답

{
  "schema_version": 1,
  "a_run_id": "run_20260510_001106_26fbda",
  "b_run_id": "run_20260510_001107_c87d7d",
  "target_metric": "eval_acc",
  "mode": "min",
  "best":  { "a": 1.0, "b": 1.0, "delta": 0.0, "direction": "tied", "epoch_a": 0, "epoch_b": 0 },
  "metric_delta": 0.0,
  "metric_direction": "tied",
  "last":  { "a": 1.0, "b": 1.0, "delta": 0.0, "direction": "tied", "epoch_a": 0, "epoch_b": 0 },
  "validation": { "a": "fail", "b": "pass", "same": false },
  "artifacts": { "a_count": 6, "b_count": 4 },
  "source":    { "same_git_sha": true, "same_cq_yaml_sha256": true, "dirty_changed": false },
  "a_status": "completed",
  "b_status": "completed",
  "a_is_ancestor_of_b": false,
  "notes": [
    "both runs picked epoch 0 as best — likely same initial weights (seed) and no improvement during training. agent should consider this a 'no learning' signal."
  ],
  "decision_facts": {
    "comparable": true,
    "best_improved": false,
    "best_tied": true,
    "candidate_completed": true,
    "candidate_validated": true,
    "config_changed": false,
    "has_lineage_relation": false
  }
}

validate_run

read-only

호출

pcq validate-run output --strictness 3 --json
# MCP: mcp__pcq__validate_run({"path": "output", "strictness": 3})

응답

{
  "schema_version": 1,
  "status": "pass",
  "strictness": 3,
  "strictness_name": "reproducible",
  "checks": [
    { "id": "manifest_evidence",           "status": "pass", "detail": "schema v2, 4 entries verified" },
    { "id": "metrics_well_formed",         "status": "pass", "detail": "1 epoch(s) recorded" },
    { "id": "summary_metrics_consistent",  "status": "pass", "detail": "run_summary best/last align with metrics history" },
    { "id": "run_record_complete",         "status": "pass", "detail": "run_record schema v1, all required keys present" },
    { "id": "run_finalized",               "status": "pass", "detail": "run finalized with status='completed'" },
    { "id": "source_reproducibility",      "status": "pass", "detail": "git_sha=..., dirty=True" },
    { "id": "environment_reproducibility", "status": "pass", "detail": "python/platform environment evidence recorded" },
    { "id": "lockfile_evidence",           "status": "pass", "detail": "lockfile recorded: uv.lock" },
    { "id": "seed_evidence",               "status": "pass", "detail": "seed recorded: 42" },
    { "id": "metrics_schema_evidence",     "status": "pass", "detail": "2 metric declaration(s) recorded" }
  ],
  "blocking_count": 0,
  "warning_count": 0
}

lineage_chain

read-only

호출

pcq lineage output --json
# MCP: mcp__pcq__lineage_chain({"path": "output"})

응답

{
  "schema_version": 1,
  "chain": [
    {
      "run_id": "run_20260510_001107_c87d7d",
      "output_dir": "...",
      "depth": 0,
      "name": "sklearn-iris-contract",
      "status": "completed",
      "target_metric": "eval_acc",
      "best_value": 1.0
    }
  ],
  "truncated": false,
  "notes": []
}

캡처 절차 (재현 가능): pcq run --path examples/_sklearn_run --json을 두 번 실행하고 그 사이에 outputoutput_a로 이름 바꾸기, 그 다음 네 개 도구를 각 디렉토리에 대해 호출. 여기서는 환경 종속 필드를 축약했지만, 실제 에이전트가 받는 JSON은 모든 필드를 보존합니다.

비교

pcq는 MLflow / W&B / Neptune과 어떻게 다른가.

서로 다른 작업을 위한 서로 다른 도구입니다. 아래 표는 각 도구가 "무엇을 소유하고 무엇을 노출하는지"를 적은 것이지, "어느 쪽이 더 낫다"가 아닙니다. 본인 워크플로에 맞는 것을 선택하세요. pcq는 공존을 전제로 설계됐습니다 (CQ 서비스는 다른 도구와 함께 생성된 run record도 ingest 가능).

도구 학습 루프 소유 MCP 지원 Self-host vs SaaS 에이전트 친화 표면
pcq 소유 안 함 — 사용자의 stack 그대로 내장 (14 도구, v4.1.0) self-host (OSS, Apache-2.0) JSON / JSONL / MCP, llms.txt, agent-manifest.json
MLflow 소유 안 함 — 모든 framework 래핑 내장 없음 self-host (OSS, Apache-2.0) REST API, Python SDK
Weights & Biases 소유 안 함 — framework별 SDK 콜백 내장 없음 SaaS (Enterprise는 self-host) REST API, Python SDK, GraphQL
Neptune.ai 소유 안 함 — SDK 통합 내장 없음 SaaS (Enterprise는 self-host) REST API, Python SDK

가장 차이가 큰 행은 "MCP 지원" — 이 표에서 pcq만이 first-class Model Context Protocol 도구를 가지고 있습니다. 이건 pcq의 설계 중심이지 다른 도구에 대한 가치 판단이 아닙니다. 완전한 실험 대시보드나 팀 RBAC이 필요하다면 MLflow와 W&B가 그 자리를 채웁니다 — pcq는 그러지 않습니다.

사례 · 프로덕션 dogfood

contract를 end-to-end로 실증한 실제 실행들.

네 개 모두 프로덕션 dogfood입니다 — 외부 고객 사례가 아니라 pcq 자체의 검증 사이클이 실제 ML 워크로드에서 돈 결과입니다. 각 문서는 셋업, 발견된 마찰, 그리고 라이브러리에 반영된 구체적 수정 사항을 기록합니다.

MNIST Dogfood

2026-05-08 · pcq v2.11 · MNIST · Claude Code

첫 end-to-end dogfood. 9개의 새 에이전트 generation, ML→DL 진화, eval_acc 0.9583 → 1.0. v2.12 fix 라운드를 견인한 첫 마찰 표면.

사례 읽기 →

Tabular Dogfood

2026-05-09 · pcq 3.0.1 · breast-cancer · TabPFN/PyCaret/FLAML/XGBoost/sklearn

PyPI 발행 이후 첫 설치 경로 검증 (git URL workaround 없음). 다른 도메인, framework 다양성 테스트. fresh-user uv add pcq 진입점을 검증.

사례 읽기 →

MCP Dogfood

2026-05-10 · pcq[mcp] 4.1.0 · Claude Code MCP

v4.1.0 MCP 루프의 첫 end-to-end — 에이전트가 subprocess CLI 대신 mcp__pcq__* 도구로 실험을 운용. 3개 sequential generation, generation마다 fresh context.

사례 읽기 →

CQ Worker Dogfood

2026-05-10 · pcq[mcp] 4.2.0 · CQ Go worker (RTX 5080)

CQ Go service worker dispatch의 첫 production end-to-end. cq.yaml + CQ_CONFIG_JSON + 6-artifact 프로토콜을 실제 production 인프라에서 검증.

사례 읽기 →

로드맵

pcq가 향하는 곳 (날짜가 아닌 방향).

명제는 그대로입니다: pcq는 학습의 수단과 경쟁하지 않는다. 앞으로의 작업은 framework 중립적인 evidence와 control 계층을 강화합니다 — 더 넓은 실제 contract 커버리지, 더 깊은 validation/lineage 사실, 에이전트 runtime을 위한 더 많은 기계 가독 표면, 그리고 CQ managed consumer와의 더 긴밀한 통합. 내장 모델, 손실, 데이터셋, framework별 어댑터 매트릭스는 의도적으로 범위 밖에 둡니다.

최근 (2026-05-12): pcq가 이제 Glama에서 검증됨 — stdio MCP server가 빌드·시작되고 14개 tool 전체가 catalog에 노출됨. awesome-mcp-servers 등재 PR 진행 중.
2026-05-10: spec/ foundation 완료 — contract spec을 docs/에서 spec/로 이동, versioning + conformance 정책과 자동 export되는 JSON Schema 추가. 1·2·3 (spec 분리 · schema versioning · conformance) arc의 첫 벽돌.

왜 pcq

당신의 에이전트가 pcq를 선호하는 세 가지 이유.

Framework 중립

PyTorch, HF Trainer, Lightning, sklearn, XGBoost, shell, 혹은 사용자 정의 Python. pcq는 학습 루프가 아니라 그 주변의 evidence를 표준화합니다.

에이전트 친화

JSON/JSONL CLI 표면과 14개 MCP 도구 — 산문이 아닌 사실입니다. --events로 라이브 evidence를 사후 감사를 위해 영구 보존합니다.

MCP 지원

pcq[mcp]가 Claude Code, Codex, 그리고 모든 MCP 호환 runtime에 연결됩니다. v2.13부터 frozen JSON contract.

예제

같은 contract, 어떤 framework든.

학습 코드는 그대로 둡니다. pcq는 세 개의 호출만 필요합니다: pcq.config(), pcq.log(...), pcq.save_all(...). 최소 cq.yaml, NumPy, post-run 명령 목록까지 전체는 examples/ 에 있습니다.

sklearn — Iris RandomForest

어댑터 없음, Trainer 서브클래스 없음. pcq 호출 세 줄.

# train.py
import pcq
import joblib
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split

cfg = pcq.config()
out = pcq.output_dir()
pcq.seed_everything(cfg.get("seed", 42))

X, y = load_iris(return_X_y=True)
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2,
                                          random_state=cfg["seed"])

model = RandomForestClassifier(n_estimators=cfg.get("n_estimators", 100))
model.fit(X_tr, y_tr)
acc = float(model.score(X_te, y_te))

pcq.log(epoch=0, eval_acc=acc)
joblib.dump(model, out / "model.pkl")
pcq.save_all(history=[{"epoch": 0, "eval_acc": acc}],
             artifacts={"model": "model.pkl"})

PyTorch — 학습 루프

모델, optimizer, dataloader는 사용자 코드. pcq는 경계에 자리합니다.

# train.py
import pcq, torch
from torch import nn

cfg = pcq.config()
out = pcq.output_dir()
pcq.seed_everything(cfg.get("seed", 42))

model = nn.Linear(cfg["in_dim"], cfg["out_dim"])
opt = torch.optim.Adam(model.parameters(), lr=cfg["lr"])

history = []
for epoch in range(cfg["epochs"]):
    train_loss = train_one_epoch(model, opt)        # 사용자 코드
    val_acc = evaluate(model)                       # 사용자 코드
    pcq.log(epoch=epoch, train_loss=train_loss, val_acc=val_acc)
    history.append({"epoch": epoch,
                    "train_loss": train_loss,
                    "val_acc": val_acc})

torch.save(model.state_dict(), out / "model.pt")
pcq.save_all(history=history, artifacts={"model": "model.pt"})

에이전트 친화 설계

에이전트가 inspect, run, validate, decide하기에 충분한 구조.

pcq는 에이전트에게 안정적인 기계 가독 표면을 제공하면서, 정책 결정은 에이전트나 서비스에 맡깁니다. 라이브러리는 사실만 보고합니다: 무엇이 실행됐는지, 무엇이 바뀌었는지, 무엇이 통과했고 무엇이 실패했는지, 어떤 artifact가 있는지, 그리고 후보가 부모와 어떻게 비교되는지.

resolve inspect validate run --json run --jsonl validate-run describe-run compare-runs lineage apply-plan agent install mcp serve

빠른 시작

contract 프로젝트를 만들고 run record를 생성한다.

uv add 'pcq[mcp]'
pcq init-experiment --style script --output ./my-exp --with-pyproject --agent claude
cd ./my-exp
uv sync
pcq agent install --target claude --path . --mcp
pcq run --json
pcq validate-run output --json
pcq describe-run output --json

FAQ

사람들이 실제로 묻는 세 가지.

더 긴 FAQ + JSON contract + strictness 레퍼런스는 docs/ 에 있습니다.

pcq는 PyTorch / HF Trainer / Lightning / sklearn을 대체하나요?

아닙니다. pcq는 학습 루프를 소유하지 않습니다. 어떤 framework든 그대로 쓰세요. pcq는 그 주변의 evidence만 표준화합니다 — cq.yaml, 메트릭 emit, artifact 레이아웃, validation, comparison, lineage, 그리고 최종 run_record.json.

pcq를 Claude Code나 Codex에 어떻게 연결하나요?

pcq[mcp]를 설치하고 pcq agent install --target both --path . --mcp.mcp.json을 작성한 뒤 pcq mcp serve를 실행하세요. 두 runtime 모두 14개 mcp__pcq__* 도구를 인식하고, stdout 파싱 대신 구조화된 인자로 호출합니다. 도구 응답 보기 →

에이전트는 run이 통과했는지 어떻게 판단하나요?

pcq validate-run output --strictness 3 --json으로 pass/warn/fail 사실을, pcq describe-run output --json으로 의사결정 사실을 받습니다. pcq는 의도적으로 사실만 보고합니다. 정책은 에이전트나 서비스가 결정합니다.

CQ와의 관계

pcq는 공개 contract. CQ는 하나의 managed consumer.

pcq

오픈소스 저작, validation, artifact, run-evidence 라이브러리. Apache-2.0. 단독으로도 유용합니다.

CQ

Managed 실행, 큐, artifact 수집, 대시보드, 에이전트 루프. 같은 contract를 consume합니다.