Harness Academy
Tài liệu gốc 20 10 phútTiếng Việt + English
docs/adr/0010-runtime-replay.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.

0010. Kitaru phát lại cho người headless decode run — tái sử dụng tính năng phát lại gốc, chỉ xây dựng các công cụ hỗ trợ

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

Bối cảnh

ADR-0008 đã decode runtime headless: Kitaru @flow (runtime/flow.py) chạy tương tự build_agent() tự động, ghi lại Điểm kiểm tra bền bỉ và nhận Phát lại/Chờ trong nơi của vòng lặp tương tác. ADR đó đã đóng khung Phát lại trong phạm vi hẹp - tiếp tục sự cố (các điểm kiểm tra đã hoàn thành được cung cấp từ bộ đệm) và phát lại câu trả lời HITL. Tính năng phát lại của Kitaru có khả năng cao hơn nhiều: flow.replay(exec_id, từ_=<cp>, <flow-input-overrides>, ghi đè={…}) thực hiện lại một lần chạy đã ghi từ bất kỳ điểm kiểm tra nào với một điều đã thay đổi, vì vậy bạn có thể hỏi chuyện gì sẽ xảy ra nếu bạn giao một mẫu khác hoặc nhắc nhở - và sau đó phân biệt ngã ba với điều khiển trung thực. Đây là khả năng nổi bật của Kitaru ("đây là phần mà các công cụ khác không thể làm được"), đã được chứng minh là hoạt động ngoại tuyến trên ngăn xếp cục bộ trong tests/integration/test_runtime_capstone.py (run_agent_task_hitl.replay(exec_id, from_=…) phục vụ điểm kiểm tra mô hình ngược dòng từ bộ nhớ đệm trong khi bước cuối cùng chạy lại).

Người dùng muốn vòng lặp what-if đó cho decode run. Nguyên tắc thiết kế do người dùng quyết định là thẳng thừng: ** tận dụng triệt để tính năng phát lại tự nhiên của Kitaru — decode chỉ xây dựng những khả năng hỗ trợ và phát minh lại ở mức tối thiểu không có gì.** Không có công cụ tìm khác biệt phía decode, không có người chạy nhóm, không có máy ghi đè được triển khai lại.

Sự thật được xác nhận chống lại docs.zenml.io (dòng kitaru 0.18) + SDK đã cài đặt khi xác định phạm vi:

  • ** Luồng chuyển tiếp phát lại đối tượng luồng được lập luận dưới dạng kwargs:** flow.replay(exec_id, from_="cp", model="...", ghi đè={"checkpoint.x": …}). Vì vậy, phần ghi đè mô hình phải là tham số luồng để Kitaru hoán đổi nó được phát lại. client.executions.replay(...) và `` phát lại cuộc hành quyết kitaru --từ --args '{…}' --ghi đè '{…}' are the SDK/CLI mirrors (--args= flow inputs;--ghi đè điểm kiểm tra.X` = thay thế điểm kiểm tra-đầu ra).
  • Ghi đè chỉ cắn ở hạ lưu from_. Replay phục vụ mọi thứ ngược dòng từ neo từ cache và thực thi lại neo + con cháu thực sự (capstone: phát lại từ terminal điểm kiểm tra khiến cho bộ đếm chân của mô hình không bị di chuyển). Vì vậy, Ghi đè mô hình chỉ có hiệu lực ở các lượt được thực hiện lại ở hạ lưu --from; để hoán đổi mô hình cho toàn bộ lần chạy, neo tại/trước lần chạy đầu tiên cuộc gọi mẫu.
  • Điểm kiểm tra mỗi lượt quá thô để có thể neo phát lại trước lệnh gọi mô hình. Tính sẵn sàng phát lại yêu cầu checkpoint_strategy="calls". HITL đã có hiệu lực "calls"; mặc định chạy bypass là "turn" (settings.runtime_checkpoint_strategy).
  • "calls" có thể phá vỡ dòng bypass .wait() trích xuất trả về giống như cách đã làm với HITL (_MultipleTerminalStepsOutputError — ADR-0008 §3 sửa đổi 5). Bản sửa lỗi của luồng HITL là một terminal @checkpoint _capture_runtime_output + một trình đọc hiện vật được đặt tên.
  • Không thể điền trước thời gian chờ khi phát lại ("phải được giải quyết thông qua luồng đầu vào chờ thông thường"). Lần chạy HITL được phát lại sẽ hỏi lại mọi phê duyệt/câu hỏi trên ngăn xếp cục bộ (capstone test_replay_re_asks_a_wait_on_the_local_stack). Việc tái sử dụng câu trả lời thực sự cần một ngăn xếp được triển khai.
  • Mỗi lần gọi công cụ output=/raise_= mô phỏng là lộ trình của Kitaru, không được xuất xưởng. --overrides checkpoint.X là dự phòng hiện tại. Khác biệt và đoàn hệ cũng không phải là API được đóng gói trong 0,18 (đã được kiểm chứng bằng thực nghiệm khi xây dựng nhiệm vụ 070: không kitaru diff CLI, không forked.diff()/.diff() SDK, không kitaru_recipes mô-đun). Khác biệt hôm nay là sự so sánh thủ công của hai vụ hành quyết kitaru <id> outputs; a cohort is the run_cohort mẫu ví dụ từ repository ví dụ của Kitaru (được xây dựng trên executions.replay), rõ ràng là không có trong kitaru gói.

Các ràng buộc của dự án được tôn trọng: cơ sở hạ tầng được nhập/gọi trực tiếp (không có trình bao bọc); sự tương tác REPL và nhật ký JSONL của nó không bị ảnh hưởng (chỉ không có đầu); runtime/ vẫn là mô-đun bị cô lập. ADR này mở rộng ADR-0008 (không thay thế nó) và được sắp xếp thành các nhiệm vụ 067-070 (tính năng runtime-replay).

Quyết định

  1. Tái sử dụng bản phát lại gốc của Kitaru; decode chỉ hỗ trợ xây dựng. decode replay là một lớp bọc mỏng kết thúc run_agent_task.replay(...) có ngữ nghĩa neo phản chiếu Kitaru 1:1. Khác biệt (sách hướng dẫn hai-executions get so sánh ngày hôm nay), ghi đè điểm kiểm tra và thử nghiệm đoàn hệ ( run_cohort mẫu ví dụ) ở trên bề mặt toán tử Kitaru (ví dụ CLI + SDK +); decode không thực hiện lại chúng (nó ghi lại chúng - §6). Điều này giữ cho tính năng này nhỏ gọn và phù hợp với Kitaru lộ trình miễn phí.

  2. Mô hình dưới dạng tham số luồng có thể phát lại (nhiệm vụ 067). Chủ đề model: str | None = None thông qua _build_model → build_agent → _build_runtime_agent/_build_hitl_runtime_agent → run_agent_task/ run_agent_task_hitl. không có reads cài đặt.<provider>_model (không thay đổi byte); một giá trị ghi đè chỉ id mẫu của nhà cung cấp đang hoạt động. Nhà cung cấp vẫn được lựa chọn bởi LLM_PROVIDER - không trao đổi nhà cung cấp chéo (không phải mục tiêu vĩnh viễn). Trở thành đầu vào luồng chính xác là điều cho phép Kitaru hoán đổi nó qua flow.replay(..., model=…).

  3. Mặc định checkpoint_strategy="calls" (nhiệm vụ 068), được đảm bảo an toàn cho vòng lặp. "calls" ghi lại một điểm kiểm tra cho mỗi lệnh gọi mô hình/công cụ, vì vậy mọi decode run sẵn sàng phát lại - Bản phát lại có thể neo trước một nội dung cụ thể cuộc gọi mẫu; "turn" (một điểm kiểm tra thô cho mỗi lần chạy) là lựa chọn không tham gia rẻ hơn và chỉ có thể được thực hiện lại toàn bộ. "calls" an toàn vòng lặp trên gemini (nhà cung cấp có dây): Kitaru chạy từng điểm kiểm tra trong sở hữu asyncio.run vòng lặp sự kiện, vì vậy, decode sẽ xây dựng ứng dụng khách chế độ luồng của gemini với HTTP duy trì hoạt động bị vô hiệu hóa (_flow_mode_http_client) — không có kết nối gộp nào tồn tại sau một vòng lặp của điểm kiểm tra bị đứt chống lại nó vào lần tiếp theo (RuntimeError('Event loop is closed')) và thời gian chờ của nó sẽ xóa Gemini's Thời hạn tối thiểu 10s. (openrouter/modal chia sẻ vấn đề tiềm ẩn trong "calls" và sẽ cần điều tương tự khách hàng nối dây thông qua họ AsyncOpenAI — factory.py.) Nhiệm vụ 068 .wait() sửa chữa vẫn còn đất: bỏ qua .wait() nghỉ khai thác trở lại dưới "calls", do đó, luồng thông qua bản sửa lỗi HITL đã vận chuyển (terminal @checkpoint _capture_runtime_output

    • _load_runtime_output người đọc; CLI đọc tạo phẩm chứ không phải .wait().output) — mà HITL (luôn luôn "calls") và đường vòng "calls" con đường cả hai đều cần. (Lịch sử: 068 bị lật "turn" → "calls"; một sự thật nhiều lượt decode run sau đó xuất hiện sự cố vòng lặp sự kiện vòng lặp chéo; thay vì rút lui "turn", decode được thực hiện "calls" an toàn vòng lặp thông qua ứng dụng khách luồng không còn tồn tại, giữ nguyên giá trị mặc định chi tiết.)
  4. decode run --model X + hiển thị exec_id (tác vụ 069). Hiển thị tham số §2 dưới dạng cờ và ngừng loại bỏ FlowHandle (hôm nay cli.py:364): in câu trả lời ra stdout, sau đó exec_id: <id> + a paste-ready decode phát lại <id> --model … gợi ý về stderr, vì vậy điểm kiểm tra→vòng lặp phát lại có thể được phát hiện và thiết bị xuất chuẩn luôn sạch sẽ.

  5. decode replay <exec_id> [--from <cp>] [--model Y] — mỏng, chỉ bỏ qua, 1:1 Kitaru (nhiệm vụ 070). kết thúc tốt đẹp run_agent_task.replay(exec_id, from_=…, model=…). --from bản đồ thẳng tới Kitaru's from_ và phản ánh chính xác hành vi của Kitaru - decode không phát minh ra mỏ neo mặc định nào; nếu kitaru yêu cầu from_, decode replay thể hiện yêu cầu riêng của Kitaru như một đường dây thân thiện. --model mặc định = phát lại nguyên trạng. In exec_id mới + một gợi ý khác chỉ vào Kitaru đã được xác nhận bề mặt. Chỉ bỏ qua: một HITL exec_id không thân thiện (phát lại HITL yêu cầu lại mỗi lần chờ - §7) và chỉ vào kitaru executions replay. Gửi kèm thử nghiệm tích hợp NGOẠI TUYẾN chứng minh việc hoán đổi mô hình thực hiện lại các lượt rẽ xuôi dòng với mô hình mới.

  6. Bề mặt toán tử Kitaru vẫn nằm trên Kitaru; decode tài liệu đó (nhiệm vụ 070). AGENTS.md nhận được điểm kiểm tra→phát lại→khác biệt→quyết định vở kịch: quy tắc "ba lần chạy, không phải hai" (Đã quan sát → Đường cơ sở Chạy lại điều khiển → Fork), kitaru executions replay --args/--overrides, --ghi đè checkpoint.X làm bản mô phỏng đầu ra của công cụ (các mô hình trên mỗi công cụ là lộ trình), khác với hướng dẫn sử dụng hai-kitaru executions get so sánh (không kitaru diff CLI / forked.diff() trong 0,18), và run_cohort mẫu ví dụ (không có trong kitaru gói) cho đoàn hệ.

  7. Việc phát lại HITL với việc sử dụng lại câu trả lời bị hoãn lại. Trên ngăn xếp nội bộ đang xử lý, một lần chạy HITL được phát lại hỏi lại mỗi lần phê duyệt/ask_user (Kitaru không thể điền trước kết quả chờ đợi; đã được chứng minh bằng capstone). thực việc tái sử dụng câu trả lời cần một ngăn xếp được triển khai, vì vậy nó được đặt ở tasks/future/hitl-replay-answer-reuse.md và được chọn ở cột mốc triển khai. Đây là lý do tại sao §5 chỉ có tính năng bỏ qua.

Phi mục tiêu (NG, vĩnh viễn): phía decode diff/cohort lệnh; trao đổi mô hình giữa các nhà cung cấp phát lại; mỗi cuộc gọi công cụ output=/raise_= giả (sử dụng --overrides checkpoint.X); bất kỳ thay đổi nào đối với đường dẫn REPL trực tiếp (chỉ không có đầu).

Sơ đồ

flowchart TB
    subgraph obs["OBSERVED — the recorded run (task 069)"]
        run["decode run --model A 'task'"]
        flowA["@flow run_agent_task(task, model=A)"]
        cps[("Checkpoints (calls) — task 068<br/>cp1 · cp2 · … · cpN<br/>durable in the Kitaru store")]
        outA["answer + exec_id: kr-A (stderr hint)"]
        run --> flowA --> cps --> outA
    end

    subgraph enabler["ENABLER (task 067)"]
        param["model: str | None threaded<br/>_build_model → build_agent → seams → flows<br/>overrides only the active provider's model id"]
    end
    param -. makes model a swappable flow input .-> flowA

    subgraph replay["REPLAY — what-if (task 070)"]
        rcmd["decode replay kr-A --from cpK --model B"]
        cache[("cp1 … cp(K-1)<br/>served from CACHE (model A)")]
        reexec["cpK … cpN RE-EXECUTE for real<br/>with Model Override B"]
        fork["FORK: new exec kr-B<br/>original_exec_id → kr-A"]
        rcmd --> cache
        rcmd --> reexec --> fork
    end
    cps -. flow.replay(kr-A, from_=cpK, model=B) .-> rcmd

    subgraph ops["KITARU OPERATOR SURFACE — documented, not wrapped (task 070)"]
        baseline["Baseline Rerun (control)<br/>kitaru executions replay kr-A --from cpK"]
        diff["compare fork vs baseline (manual)<br/>kitaru executions get kr-B / kr-A → decision · cost · latency Δ"]
        over["--overrides 'checkpoint.X': … (tool-output stand-in)"]
        cohort["run_cohort example (examples repo,<br/>not in the kitaru package)"]
        fork --> diff
        baseline --> diff
        diff --> decide{{"ship the change? keep / reject"}}
        cohort --> decide
    end
    reexec -. tool-output mock .-> over

    subgraph deferred["DEFERRED (tasks/future/)"]
        hitl["HITL replay with answer-reuse<br/>needs a DEPLOYED stack — waits re-ask locally"]
    end
    fork -. bypass-only; HITL exec_id → friendly error .-> hitl

    classDef observed fill:#1565c0,stroke:#0d47a1,color:#ffffff;
    classDef store fill:#37474f,stroke:#102027,color:#ffffff;
    classDef enable fill:#00838f,stroke:#005662,color:#ffffff;
    classDef rep fill:#2e7d32,stroke:#1b5e20,color:#ffffff;
    classDef opsc fill:#e65100,stroke:#bf360c,color:#ffffff;
    classDef defer fill:#6a1b9a,stroke:#38006b,color:#ffffff;
    class run,flowA,outA observed;
    class cps,cache store;
    class param enable;
    class rcmd,reexec,fork rep;
    class baseline,diff,over,cohort,decide opsc;
    class hitl defer;

hậu quả

  • Tính năng nhỏ, khả năng lớn. Bốn công cụ hỗ trợ nhỏ (thông số luồng, sửa chữa ghi lại đầu ra bỏ qua, một lá cờ, một lớp bao bọc mỏng) mở khóa vòng lặp phát lại/điều gì xảy ra nếu của Kitaru và quy trình làm việc của người vận hành được xây dựng trên đó (khác biệt, ghi đè điểm kiểm tra, ví dụ về đoàn hệ). Mọi thứ khó khăn đều là của Kitaru, không phải của bộ decode.
  • Mặc định decode run có thể chơi lại một cách chi tiết. "calls" ghi lại một điểm kiểm tra cho mỗi mô hình/công cụ cuộc gọi, do đó, bản phát lại có thể neo trước một cuộc gọi mô hình cụ thể - an toàn vòng lặp trên gemini thông qua keep-alive-free flow client (Quyết định 3; openrouter/modal sẽ cần hệ thống dây điện tương tự). RUNTIME_CHECKPOINT_STRATEGY=turn là lựa chọn không tham gia rẻ hơn (một điểm kiểm tra mỗi lần chạy), nhưng "turn" run chỉ có thể được phát lại toàn bộ.
  • Việc hoán đổi mô hình có thể phân tách chuỗi cuộc gọi được ghi lại. Một mô hình khác có thể gọi công cụ khác nhau hạ lưu của --from; Kitaru có thể nâng cao KitaruDivergenceError. decode replay bề mặt nó như một dòng thân thiện (đó là kết quả giả định trung thực - sự thay đổi đã chuyển hướng cuộc chạy), không bao giờ truy tìm lại. KitaruStateError (mơ hồ --from) cũng được xử lý tương tự.
  • Cái .wait()-dưới-"calls" việc sửa chữa được xác minh trước, không được giả định. Nhiệm vụ 068 đo lường thực tế bỏ qua hành vi trước khi lựa chọn giữa việc giữ .wait().output và áp dụng đầu ra HITL tạo tác - mẫu sửa lỗi đã tồn tại, do đó rủi ro bị hạn chế.
  • Chỉ bỏ qua là giới hạn có chủ ý, được ghi lại. Tính năng phát lại HITL yêu cầu lại mỗi lần chờ trên cục bộ ngăn xếp (Kitaru không thể điền trước kết quả chờ); việc sử dụng lại câu trả lời được hoãn lại theo cột mốc triển khai (tasks/future/). decode replay từ chối HITL exec_id có hướng dẫn thay vì âm thầm nhắc lại.
  • CI vẫn ngoại tuyến. Bằng chứng phát lại mới dựa trên capstone isolated_kitaru_store + theo kịch bản FunctionModel đường nối — không có máy chủ, không có mạng, không có khóa — phản ánh mọi thử nghiệm runtime trước đó.
  • REPL không có kitaru. decode replay nhập khẩu runtime/ lười biếng, giống hệt như decode chạy; nhập decode.cli vẫn không bao giờ nhập kitaru.
  • Mở rộng, không thay thế, ADR-0008. Các quyết định Phát lại/Điểm kiểm tra/Chờ của ADR-0008 vẫn giữ nguyên; cái này ADR chỉ mở rộng tính năng Phát lại cho trường hợp sử dụng giả định và thêm bốn công cụ hỗ trợ. Bảng thuật ngữ Replay hàng được mở rộng và tăng Model Override, Fork, Baseline Rerun, Checkpoint Override.
Mục lục nguồn