Harness Academy
Tài liệu gốc 27 7 phútTiếng Việt + English
docs/adr/0017-decode-eval-suite.mdXem bản gốc
Ngôn ngữ bài đọc
Bản dịch tiếng Việt

Bản dịch đầy đủ theo đúng cấu trúc tài liệu; code, liên kết và định danh kỹ thuật được giữ nguyên.

0017 — bộ decode eval: demo, benchmark, thăm dò hồi quy, khai thác Opik

Trạng thái: Đã chấp nhận Ngày: 2026-07-13

Bối cảnh

decode có dấu vết (ADR-0014) nhưng không có cách nào để trả lời "sự thay đổi này làm cho agent tốt hơn hay tệ hơn?". Chúng tôi muốn: (a) bản trình diễn giới thiệu do con người đánh giá, (b) điểm chuẩn kết quả ("nó có thể thực hiện được nhiệm vụ?"), (c) bộ hồi quy hành vi khai thác ("nó có hoạt động ĐÚNG không?" - công cụ phù hợp, khác biệt tối thiểu, cổng được tôn trọng) và (d) thúc đẩy cơ sở hạ tầng đánh giá Opik (b) và (c) — trong một cơ sở mã giáo dục nơi logic chấm điểm phải dễ đọc và cơ sở hạ tầng được nhập khẩu, không trừu tượng. Hạn chế: tests/ gương src/ 1:1; bánh xe chỉ tàu src/decode; việc truy tìm Opik hiện tại không được bị xáo trộn; make ci phải không có đánh giá (evals cần khóa API và tốn tiền). Không phải mục tiêu: Bộ điều hợp băng ghế đầu cuối/bàn ghế SWE, giao diện người dùng bảng xếp hạng, sự tham gia của proxy thông tin xác thực, best@k/majority-vote, mô phỏng người dùng.

Quyết định

  1. Vị trí: cấp cao nhất evals/, không src/decode/evals/. Mã đánh giá là tài liệu khóa học về agent, không phải một phần của nó - [tool.hatch.build.targets.wheel] đã chỉ giao hàng src/decode, vì vậy bánh xe không bị ảnh hưởng với cấu hình xây dựng bằng không. Kiểm tra đơn vị cho mã khai thác trực tiếp tests/unit/evals/ (phản chiếu evals/ chính xác như tests/unit/decode/ gương src/decode/): MỘT gốc pytest có nghĩa là make unit-tests, pre-commit hooks và CI bao gồm khai thác ngoại tuyến logic miễn phí. Một ngoại lệ có chủ ý là evals/regression/test_thresholds.py - một mô-đun tốn tiền, yêu cầu chìa khóa được giữ BÊN NGOÀI testpaths và chỉ được gọi bởi make eval-regression.
  2. Bốn đường đua, ba phong cách phán đoán. Kỹ năng demo (do con người đánh giá, không có Opik, đơn giản .decode/skills/demo-N-*/ theo ADR-0004); Điểm chuẩn 20 nhiệm vụ (kết quả dự đoán); 20 đầu dò Bộ hồi quy (số liệu hành vi + một số đánh giá); harness Opik bên dưới. Demo chứng minh điều đó gây ấn tượng; điểm chuẩn chứng minh nó hoạt động; các cuộc thăm dò chứng tỏ nó hoạt động theo cách chúng tôi thiết kế (ADR-0002..0013 hành vi: kỷ luật công cụ đọc, chế độ kế hoạch, tôn trọng cổng, tồn tại khi nén).
  3. Việc thực thi sử dụng lại đường nối hộp cát của chính bộ decode — không có cơ sở hạ tầng chạy mới. Các lần chạy điểm chuẩn nhận được một Không gian làm việc mới cho mỗi tác vụ thông qua không gian làm việc hiện có SandboxExecutor/DockerBackend (executor.start(tmp_workspace) + cái decode.tools.bash đường may thi hành - chính xác runtime/flow.py::_warm_headless_executor mẫu); --sandbox modal trao đổi trong ModalBackend trên cùng một đường may. Đầu dò hồi quy chạy trên máy chủ gốc (none mode) trên các thư mục tạm thời - đủ nhanh cho nghi thức theo từng nhánh tính năng. Cơ chế tối thiểu sự lựa chọn: đường nối đã tồn tại và cách ly eval cũng là vấn đề tương tự cách ly hộp cát giải quyết.
  4. Lái xe agent trong quá trình; công cụ gọi từ tin nhắn, không bao giờ gọi từ dấu vết. Một trình điều khiển (evals/harness/driver.py) chạy THỰC SỰ build_agent() + AgentDeps + AgentTurnHandler + Runner (mô hình đã được chứng minh bởi tests/integration/test_milestone1_capstone.py), với chế độ cổng/bộ phân giải/lịch sử điền sẵn có thể định cấu hình. Các lệnh gọi công cụ được trích xuất từ pydantic-ai ToolCallParts trong lịch sử tin nhắn và cách sử dụng từ phần tóm tắt ModelResponse.usage — phân tích cú pháp Dấu vết Opik cho sự thật cơ bản sẽ kết hợp với việc phân loại theo quy trình có thể quan sát được và nằm dưới độ trễ lấy mẫu/xuất. ý kiến evaluate() nhiệm vụ fns được đồng bộ hóa, vì vậy trình điều khiển sẽ gửi một asyncio.run() giấy gói.
  5. Xác minh rằng các lời tiên tri được ẩn giấu nhưng trung thực. verify/ tài sản chỉ được tiêm qua đường may SAU KHI agent kết thúc (agent không bao giờ có thể grep học sinh của chính mình); verify.sh LÀ sự chấm điểm logic - một tập lệnh bash có thể đọc được, kiểu Terminal-Bench. Mỗi nhiệm vụ cam kết một solution/ và Khai thác pytest oracle-sanity chứng minh mỗi oracle CẢ HAI hướng (giải pháp→PASS, untouched→FAIL) trong CI thông thường, do đó, một oracle bị hỏng không thể âm thầm xếp loại mọi thứ lên hoặc xuống.
  6. Hai bề mặt hồi quy, có chủ ý. (a) Bộ dữ liệu đơn giản + số liệu mã thông qua evaluate() với cổng ngưỡng pytest (aggregate_evaluation_scores() ≥ ngưỡng; vùng đồng bằng cơ sở thông qua get_experiments_by_name như cảnh báo); (b) Bộ thử nghiệm Opik 2.0 (get_or_create_test_suite khẳng định bằng ngôn ngữ tự nhiên, run_tests → pass_rate) trên một tập con thăm dò nhỏ. Dự phòng trên mục đích: sự tương phản giữa các số liệu xác định và các xác nhận NL là điểm giảng dạy.
  7. Định tuyến thẩm phán tuân theo nhà cung cấp decode. Xây dựng một nhà máy thẩm phán GEval(model=<LiteLLM string>): mặc định gemini/gemini-2.5-flash; openrouter → openrouter/<model>; modal → openai/<model> + điểm cuối base_url. EVAL_JUDGE_MODEL ghi đè. Giám khảo được dành riêng cho những gì mã không thể cho điểm (chất lượng, tính căn cứ, sự khác biệt tối thiểu về nhiệm vụ 19/15/20 và thẩm phán thăm dò); mọi thứ máy móc vẫn là một BaseMetric → ScoreResult.
  8. Thử nghiệm + tổng hợp trên trục riêng của Opik. --trials k → evaluate(trial_count=k); pass@1 / pass@k / pass^k / flakiness-rate và chi phí thành công trên mỗi đô la được chuẩn hóa theo chi phí được tính như sau các hàm thuần post-hoc trên evaluate() kết quả test_results (đã cài đặt opik==1.9.8 có không experiment_scoring_functions param) và được đính kèm vào thử nghiệm dưới dạng dấu vết cho mỗi mục điểm phản hồi, có điểm trung bình cho mỗi thử nghiệm sẽ hiển thị chúng trên hàng thử nghiệm; experiment_config mô hình agent hồ sơ, nhà cung cấp, git sha. Chi phí đến từ việc sử dụng được ghi lại (+ dấu vết Opik total_cost ở đâu có sẵn).
  9. Nhịp: thủ công, không bao giờ trong make ci. make eval-benchmark / make eval-regression cần GEMINI_API_KEY + OPIK_API_KEY; nghi thức hồi quy được hợp nhất trước trên mỗi nhánh tính năng và mô-đun ngưỡng có thể trỏ tới CI sau này. Eval chạy đăng nhập dưới EVAL_PROJECT_NAME (decode-evals), do đó, việc theo dõi REPL trực tiếp (ADR-0014, dự án decode/decode-<env>) không bao giờ bị ô nhiễm - harness không được chiến đấu init_tracing().
  10. Đánh giá trực tuyến vẫn ở mức nhỏ. Một quy tắc đánh giá LLM trực tuyến của Opik được ghi lại + một quy tắc được viết theo kịch bản cấp độ chủ đề evaluate_threads chuyển qua các chủ đề của dự án TRỰC TIẾP - đánh giá sản xuất câu chuyện được kể ở quy mô demo.

Sơ đồ

flowchart LR
    subgraph tracks["Eval tracks"]
        D["Demo Skills<br/>.decode/skills/demo-N<br/>(human-judged)"]:::demo
        B["Benchmark<br/>evals/benchmark/tasks/NNN<br/>task.yaml + setup/ + verify/ + solution/"]:::bench
        R["Regression Probes<br/>evals/regression/cases<br/>fixtures + metrics"]:::reg
    end

    subgraph harness["evals/harness (not in wheel)"]
        DRV["driver.py<br/>build_agent + Runner<br/>ToolCallParts + usage"]:::infra
        MET["metrics.py<br/>BaseMetric → ScoreResult"]:::infra
        JDG["judges.py<br/>GEval ← LiteLLM routing"]:::infra
        AGG["aggregates.py<br/>pass@k · pass^k · $/success"]:::infra
    end

    subgraph exec["Execution"]
        DK["SandboxExecutor<br/>DockerBackend (default)"]:::sbx
        MD["ModalBackend<br/>--sandbox modal"]:::sbx
        HN["Host-native none mode<br/>temp dirs"]:::sbx
    end

    subgraph opik["Opik"]
        DS["datasets<br/>decode-benchmark-v1<br/>decode-regression-v1"]:::opik
        EV["evaluate(trial_count)<br/>+ post-hoc aggregates<br/>→ trace feedback scores"]:::opik
        TS["Test Suites<br/>run_tests → pass_rate"]:::opik
        ON["online rule +<br/>evaluate_threads"]:::opik
    end

    GATE["pytest threshold gate<br/>make eval-regression<br/>(outside testpaths)"]:::gate

    B --> DRV
    R --> DRV
    DRV --> DK
    DRV -.-> MD
    DRV --> HN
    B -->|"verify.sh at grade time"| DK
    DRV --> EV
    MET --> EV
    JDG --> EV
    AGG --> EV
    DS --> EV
    EV --> GATE
    R -.->|subset| TS
    ON -.->|live traces| opik

    classDef demo fill:#f9e79f,stroke:#b7950b,color:#1c2833
    classDef bench fill:#aed6f1,stroke:#2471a3,color:#1c2833
    classDef reg fill:#a9dfbf,stroke:#1e8449,color:#1c2833
    classDef infra fill:#d7bde2,stroke:#7d3c98,color:#1c2833
    classDef sbx fill:#f5b7b1,stroke:#c0392b,color:#1c2833
    classDef opik fill:#fad7a0,stroke:#ca6f1e,color:#1c2833
    classDef gate fill:#e5e8e8,stroke:#566573,color:#1c2833

hậu quả

  • Tích cực: hồi quy về HÀNH VI của agent (không chỉ kết quả) trở nên có thể đo lường được trên mỗi đặc điểm chi nhánh; việc chấm điểm vẫn minh bạch (verify.sh + số liệu có thể đọc được); không có sự cô lập mới cơ sở hạ tầng (đường nối hộp cát được tái sử dụng); bánh xe, make ci, và truy tìm trực tiếp đều không bị ảnh hưởng; oracle-sanity giúp 20 học sinh viết tay luôn trung thực.
  • Phủ định / được chấp nhận: Việc chạy eval tốn tiền thật và cần có khóa — do đó, nhịp điệu thủ công, có nghĩa là bộ phần mềm chỉ bắt những gì ai đó chạy; Thẩm phán LLM ồn ào (giảm nhẹ: chỉ có thẩm phán nơi mã không thể quyết định, ngưỡng không khớp chính xác, vượt qua^k để đảm bảo độ tin cậy); chạy thử k nhân chi phí một cách tuyến tính; hai bề mặt hồi quy có nghĩa là có sự trùng lặp nào đó (được chấp nhận cho tương phản); evals/ phát triển nguồn gốc thứ hai mà các cuộc kiểm tra phải phản ánh theo quy ước, được thực thi chỉ bằng cách xem xét.
  • Đường dẫn hoãn lại/nâng cấp: trỏ CI vào mô-đun ngưỡng; một --sandbox modal mặc định một lần ma sát docker cắn; đầu dò 12 (MCP) kích hoạt khi nhà máy sản xuất công cụ MCP của bộ decode xuất xưởng; Bộ điều hợp băng ghế dự bị đầu cuối/SWE chỉ khi 20 nội bộ ngừng phân biệt đối xử giữa các agent các phiên bản.
Mục lục nguồn