Spaces:
Sleeping
PoolCoach RL — hướng dẫn cho Claude Code
Luận văn thạc sĩ: huấn luyện tư duy điều bi 9-ball bằng RL.
Stack: pooltool (sim vật lý) → Gymnasium env → Stable-Baselines3 (PPO/SAC), cộng web app FastAPI + canvas gợi ý cú đánh.
Trả lời và giải thích bằng tiếng Việt. Commit message bằng tiếng Anh.
Môi trường
- Python 3.12, venv ở
D:\Khoa luan\poolcoach-env(NGOÀI repo). - Cài gói bằng uv, không dùng pip:
uv pip install -r requirements.txt --index-strategy unsafe-best-match(flag bắt buộc —panda3d==1.11.0.dev3702chỉ có trênarchive.panda3d.org). - 4 tầng requirements, cài tách để mạng chậm không kéo hỏng nhau:
requirements.txt(core: pooltool + gymnasium) ·-rl.txt(SB3 + torch) ·-app.txt(fastapi + uvicorn) ·-dev.txt(pytest + httpx). - Lần chạy pooltool đầu tiên mỗi process tốn ~40s Numba JIT. Đừng tưởng treo.
Quy ước repo — đọc trước khi viết code
Package KHÔNG được cài. Mọi file trong scripts/, tests/, examples/ phải tự đẩy src/ vào path trước khi import poolcoach_rl:
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "src"))
Quên dòng này là lỗi đã tái phạm (24/07). Trong tests/ việc này nằm ở conftest.py — đừng dựa vào app/main.py chèn hộ, vì khi đó kết quả test phụ thuộc thứ tự collect của pytest.
.bat có hai vai trò khác nhau — đừng lẫn:
- Launcher chạy tay đặt ở
D:\Khoa luan\(thư mục CHA, ngoài git). Script Python nằm trongscripts/;.batchỉ là lớp bọc activate venv +cd+ gọi script. Thêm script mới cần chạy thường xuyên → thêm.battương ứng ở thư mục cha, đừng tạo launcher trong repo. Hiện có:poolcoach.bat(mở shell đã activate) ·run_app.bat·run_tests_app.bat·run_eval_fullrack.bat·run_benchmark_fullrack.bat·run_recommend_smoke.bat+ cácrun_experiments_*.battheo ngày. - Bản lưu lịch sử của thí nghiệm ĐÃ CHẠY thì ngược lại: trong repo, ở
scripts/experiments/(29/07/2026). Đó là copy byte-for-byte của launcher đã thực sự sinh ra số liệu — bản ở thư mục cha vẫn còn nguyên để double-click. Lý do: comment đầu mỗi file ghi lý do chạy + ngưỡng nghiệm thu, thứgit logkhông tải nổi; vàrun_qfield_20260721.batlà lệnh tái lập chính model đang chạy trong app. Ngoài git thì mất là mất hẳn. Luật + bảng nội dung:scripts/experiments/README.md. Copy vào đó sau khi đã chạy xong, và không sửa bản đã lưu.
.gitattributes khai *.bat text eol=crlf — cmd Windows cần CRLF.
models/, logs/ bị gitignore. Model cần deploy phải ép: git add -f models/qfield_20260721/qfield.pt (đang track qua Git LFS).
Cấu trúc
src/poolcoach_rl/
envs/ SinkOneBallEnv (stage 1), PositionPlayEnv (stage 2a)
recommend/ simulate.py (chỉ trả FACTS vật lý) · rules.py (luật + EV)
geometry.py (đường bị chắn) · engines.py (oracle search + pool)
core.py (validate + orchestrate)
app/ main.py (FastAPI, 3 endpoint) · schemas.py · static/ (canvas FE)
scripts/ train_* · eval_* · benchmark_* · oracle_* · gen_bc_dataset
tests/ contract test (rules/fallback/api-v2/v1-compat) + conftest stub
Tách tầng cố ý: simulate.py chỉ nói chuyện gì đã xảy ra, rules.py mới phán hợp lệ hay không. Đừng nhét luật vào tầng sim.
Test & nghiệm thu
pytest(hoặcrun_tests_app.bat). Test kiểm contract — luật 9-ball, shape response, message lỗi — KHÔNG kiểm vật lý.conftest.pycố ý nhét stubpooltoolrỗng, thiếuSystem/simulate/EventTypeđể test nào lỡ chạm tầng vật lý sẽ némAttributeErrorngay.- Gate thật của engine là
scripts/eval_fullrack.py --tables 20: 0 cú phạm luật và search < 5s/cú. Mốc hiện tại: median 1.13s, max 2.48s. - Chỉ số RL đọc bằng eval mẫu lớn:
eval_position.py --episodes 1000. Eval 200 cú cho Q|pot nhiễu tới ±0.05 — đã bị lừa 2 lần (14/07, 16/07). Kết luận về Q phải kèm SE.
Bẫy đã trả giá — đừng lặp lại
os.cpu_count()không thấy cgroup quota. Trong container HF (2 vCPU) nó trả về số core host → pool 7-15 worker. Số worker khai báo tường minh qua envPOOLCOACH_WORKERS(Dockerfile set2= đúng số vCPU thật của Space;0= serial).sched_getaffinitycũng không cứu.- Quy ước spin của pooltool (nghiệm thu từ source wheel 0.6.0):
a=+1là mép TRÁI bi,b=+1là đỉnh bi. FE đã sửacx = 50 − side·46cho khớp. Đổi dấu ở đâu cũng phải đối chiếu lại docstringCue. - Tín hiệu "thắng" thô bị may mắn thổi phồng. Hai lần:
b2rớt lỗ may mắn (20/07) và "lucky 9" trong grid search (24/07). Cách sửa đúng là điều kiện hoá theo ngữ cảnh (WIN_EV chỉ khi target = 9), không phải hạ hệ số. .git/index.locksót lại → xoá tay file đó. Nguyên nhân đã truy ra (25/07):git statuschạy từ sandbox Linux của Cowork tạo lock rồi không unlink được qua mount Windows. Claude Code chạy native nên không dính; Cowork từ nay dùnggit --no-optional-locks status.
Mẫu block HANDOFF.md
Ghi thêm một block vào ..\HANDOFF.md sau MỖI lần chạy — xong hay dừng giữa chừng đều ghi. Chép từ ..\poolcoach-docs\Documents\PoolCoach_Workflow_Cowork_ClaudeCode.md §5.5; bản đó là bản gốc, sửa mẫu thì sửa ở đó trước.
Một block cho mỗi lần chạy, mới nhất ở dưới cùng:
## <ngày giờ> — <việc gì, một dòng>
**BRIEF**: <mốc chép từ BRIEF.md; "không có" nếu làm theo prompt miệng>
**Trạng thái**: XONG | XONG-CÓ-LỆCH | DỪNG-GIỮA-CHỪNG
**Commit**
- `<hash>` <subject> (rỗng nếu không commit gì — nói rõ vì sao)
**Gate**
| gate | ngưỡng | đo được | ĐẠT/ĐỎ |
**Lệch khỏi BRIEF** ← MỤC QUAN TRỌNG NHẤT
- <làm khác gì · vì sao · ảnh hưởng thế nào tới số liệu>
- ghi thẳng "không lệch gì" nếu đúng vậy — đừng bỏ trống
**Bất ngờ** (thứ tự nhận ra mà BRIEF không hỏi)
- <crash, hành vi lạ, phát hiện phụ, nghi ngờ chưa xác minh>
**File sinh ra**
| file | sinh bởi lệnh nào | commit hash lúc chạy |
**Câu hỏi cho Cowork** (quyết định cố ý KHÔNG tự đưa ra)
**Chưa làm**
Ba mục cứu được ca 27/07: Lệch khỏi BRIEF (khai script chữa cháy), Bất ngờ (khai crash), và cột commit hash lúc chạy trong bảng file (lộ ngay hai cấu hình chạy ở hai phiên bản code khác nhau).
Ghi
HANDOFF.mdkể cả khi thất bại — nhất là khi thất bại. Một lần chạy chết giữa chừng mang nhiều thông tin hơn một lần chạy trơn tru, mà nó lại chính là lần không để lại commit nào.
Ranh giới với Cowork
Claude Code sở hữu mọi thứ trong repo này. Không sửa ..\poolcoach-docs\research_log.md — nhật ký nghiên cứu do phiên Cowork ghi cuối ngày, dựa trên git log của repo này.
Design doc + implementation plan nằm ở ..\poolcoach-docs\Documents\ — đọc để lấy yêu cầu, nhưng không sửa; thiết kế được chốt ở Cowork.
Commit
Conventional Commits, tiếng Anh, cả subject lẫn body. Mỗi bước trong implementation plan = 1 commit, chỉ commit sau khi qua gate nghiệm thu của bước đó.
Scope đang dùng: rules recommend geometry engines api fe app envs eval deploy stage2a examples.
feat(rules): WIN_EV only for direct 9-ball target (anti lucky-9)
fix(app): flip spin-dot x-axis to match pooltool side-spin convention
chore(deploy): dockerignore tests, HF metadata for full-rack build