Harness Engineering

Nghệ thuật xây "bộ yên cương" quanh mô hình AI: vòng lặp, công cụ, ngữ cảnh, bộ nhớ, quyền hạn và kiểm chứng — thứ biến một LLM chỉ biết sinh chữ thành một agent làm được việc thật. Claude Code là ví dụ tiêu biểu nhất.

Agent = Model + Harness

Prompt Engineering

"Hỏi cái gì?" — tối ưu câu lệnh cho một lượt trả lời.

Context Engineering

"Cho xem cái gì?" — chọn lọc thông tin đưa vào cửa sổ ngữ cảnh mỗi bước.

Harness Engineering

"Cả hệ thống vận hành thế nào?" — vòng lặp, tools, quyền, hooks, sub-agent, kiểm thử, phục hồi lỗi.

Một con số hay được trích dẫn: trong thử nghiệm Terminal-Bench của LangChain, chỉ đổi harness, giữ nguyên model, độ chính xác tăng từ 52,8% lên 66,5%. Cùng một model, harness khác nhau cho ra trải nghiệm khác hẳn.

Các mô hình harness

Những kiến trúc phổ biến, từ đơn giản đến phức tạp.

1. Agent loop (ReAct / tool-use loop) — lõi của Claude Code

Người dùng Contextsystem+history+CLAUDE.md 🧠 Model Tool call → thực thi Trả lời cuối (stop) kết quả tool → nối vào context

Model gọi tool → harness thực thi → nối kết quả vào hội thoại → lặp lại tới khi model dừng. Mọi thứ khác (compaction, quyền, hooks) là lớp bọc quanh vòng lặp này.

2. Workflow cố định (Prompt chaining / Routing)

Code quyết định luồng, LLM chỉ làm từng bước. Dễ đoán, rẻ, nhưng kém linh hoạt. Phù hợp tác vụ lặp lại có cấu trúc.

Anthropic: Building effective agents

3. Orchestrator – Workers (Sub-agents)

Agent chính chia việc cho các sub-agent có context riêng, nhận về bản tóm tắt. Giữ context chính sạch; Claude Code dùng qua Task/Agent tool.

song songcô lập context

4. Evaluator – Optimizer

Một agent làm, một agent/bộ test chấm điểm và phản hồi, lặp tới khi đạt. Trong coding: test, lint, typecheck chính là evaluator.

feedback loop

5. Initializer + Coding agent (long-running)

Phiên đầu tạo feature_list.json, progress.txt, script init; các phiên sau đọc lại, làm từng tính năng, commit git, ghi tiến độ. Giải bài toán agent chạy nhiều giờ qua nhiều context window.

Anthropic, 11/2025

6. Harness làm "môi trường" (OpenAI Codex)

Repo được thiết kế cho agent đọc: tài liệu có cấu trúc làm nguồn sự thật, linter/kiến trúc ràng buộc cứng, agent tự review lẫn nhau. Con người thiết kế môi trường, agent viết code.

agent-first repo

7. Guides + Sensors (Martin Fowler / Birgitta Böckeler)

Guides (feedforward): CLAUDE.md, skills, quy ước — định hướng trước khi làm. Sensors (feedback): test, lint, type check, review — phát hiện sai sau khi làm. Harness tốt cần cả hai.

Thành phần của harness (theo Claude Code)

Mỗi lớp là một "đòn bẩy" kỹ sư có thể chỉnh.

Thành phầnVai tròTrong Claude Code
Agent loopVòng lặp model ↔ tool, xử lý lỗi, retryQuery loop dạng state machine, tự phục hồi khi tool lỗi
System promptĐịnh danh, quy tắc hành viPrompt hệ thống + output style
Memory / GuidesTri thức bền vững về dự ánCLAUDE.md (user/project/local), auto-memory
ToolsHành động lên thế giớiRead, Edit, Write, Bash, Grep, Glob, WebFetch, Agent…
SkillsNăng lực đóng gói, nạp khi cần.claude/skills/*/SKILL.md
MCPKết nối hệ thống ngoài theo chuẩn mở.mcp.json, claude mcp add
HooksCode tất định chạy tại các sự kiệnPreToolUse, PostToolUse, Stop, SessionStart, UserPromptSubmit…
Permissions / SandboxGiới hạn rủi roallow/deny rules, plan mode, sandbox bash
Sub-agentsChia việc, cô lập context.claude/agents/*.md
Context managementKhông tràn cửa sổ ngữ cảnhAuto-compact, /compact, /clear
Slash commands / PluginsĐóng gói & chia sẻ cả bộ harnessPlugin = skills + agents + hooks + MCP
Headless / SDKNhúng harness vào CI, sản phẩmclaude -p, Claude Agent SDK

Tools trong Claude Code — đào sâu

Tool là "tay chân" của agent. Model chỉ thấy tên, mô tả và JSON schema; harness lo thực thi và trả kết quả.

📂 Đọc & tìm

Read (đọc file, ảnh, PDF, notebook), Glob (tìm theo mẫu tên), Grep (ripgrep theo nội dung). Thiết kế để agent "agentic search" thay vì RAG vector.

✏️ Sửa

Edit thay chuỗi chính xác (bắt buộc đã Read trước — một guardrail của harness), Write ghi đè file, NotebookEdit.

💻 Thực thi

Bash: chạy lệnh, test, git, build. Có timeout, chạy nền, sandbox, và kiểm tra quyền theo pattern như Bash(npm test:*).

🌐 Web

WebSearch, WebFetch — kéo tài liệu mới hơn training cutoff.

🤖 Điều phối

Agent/Task khởi sub-agent; TodoWrite lập kế hoạch nhìn thấy được; Skill nạp skill; plan mode.

🔌 MCP tools

Tool từ server ngoài, tên dạng mcp__server__tool. Có thể "deferred" — chỉ nạp schema khi cần để tiết kiệm context.

Vòng đời một tool call

Model sinh tool_use {name:"Edit", input:{...}}
  → PreToolUse hooks (có thể chặn / sửa input)
  → Kiểm tra permission (allow / ask / deny)
  → Thực thi
  → PostToolUse hooks (vd: chạy prettier, lint)
  → tool_result nối vào hội thoại → model bước tiếp

Nguyên tắc viết tool tốt cho agent (Anthropic)

  • Ít tool nhưng đúng việc; gộp thao tác hay đi cùng nhau.
  • Tên & namespace rõ ràng, mô tả viết như hướng dẫn cho nhân viên mới.
  • Trả về thông tin có ý nghĩa, gọn (phân trang, cắt bớt) — tiết kiệm token.
  • Thông báo lỗi phải chỉ cách sửa.
  • Đánh giá bằng eval thực tế rồi để chính Claude đề xuất cải tiến tool.
// .claude/settings.json — giới hạn quyền tool
{ "permissions": {
    "allow": ["Bash(npm run test:*)", "Read", "Edit(src/**)"],
    "deny":  ["Bash(rm -rf:*)", "Read(.env)"] } }

Ví dụ tool call thực tế

Read   {"file_path":"/app/src/auth.ts","offset":40,"limit":60}
Grep   {"pattern":"useSession","glob":"**/*.tsx","output_mode":"files_with_matches"}
Glob   {"pattern":"src/**/*.test.ts"}
Edit   {"file_path":"/app/src/auth.ts","old_string":"expiresIn: 60","new_string":"expiresIn: 3600"}
Write  {"file_path":"/app/README.md","content":"# App\n..."}
Bash   {"command":"npm test -- auth","timeout":120000}
Bash   {"command":"git diff --stat && git commit -m 'fix token ttl'"}
WebFetch {"url":"https://docs.stripe.com/webhooks","prompt":"Cách verify chữ ký?"}
WebSearch {"query":"vite 7 breaking changes"}
Agent  {"subagent_type":"Explore","prompt":"Tìm mọi chỗ gọi API thanh toán"}
TodoWrite {"todos":[{"content":"Sửa TTL","status":"in_progress"}]}
Skill  {"skill":"pdf-report"}
mcp__youtube__search_videos {"query":"harness engineering","max_results":5}
mcp__github__create_pull_request {"repo":"me/app","title":"Fix TTL"}
mcp__postgres__query {"sql":"SELECT count(*) FROM orders"}

Kết quả trả về (tool_result) là text/JSON/ảnh — model đọc rồi quyết định bước tiếp.

❓ YouTube MCP có phải là tool không? Tool có gồm cả data không?

Ngắn gọn: YouTube MCP không phải là một tool — nó là một MCP server, tức một "ổ cắm" cung cấp nhiều tool (và có thể cả resource, prompt) cho agent. Mỗi chức năng nó phơi ra mới là một tool, ví dụ mcp__youtube__search_videos, mcp__youtube__get_transcript.

Claude Code (client) YouTube MCP server 🔧 tool: search_videos🔧 tool: get_transcript📄 resource: video://id💬 prompt: summarize YouTube Data API (data)

Tool có gồm data không? Không — tool là hành động / hàm (tên + mô tả + schema đầu vào). Data là thứ tool lấy về hoặc tác động lên, nằm ngoài tool (trên YouTube, trong database, trong file). Data chỉ vào context của model khi tool được gọi và trả tool_result. Ví dụ: tool get_transcript không "chứa" transcript; nó đi lấy transcript mỗi lần được gọi.

MCP chia rõ 3 loại khả năng:

LoạiAi điều khiểnBản chấtVí dụ YouTube
ToolsModel tự quyết gọiHàm thực thi (có thể đọc hoặc ghi)search_videos, get_transcript
ResourcesỨng dụng/người dùng chọn đính kèmDữ liệu chỉ đọc có URI (gần với "data" nhất)@youtube:video://abc123
PromptsNgười dùng gọiMẫu prompt dựng sẵn → slash command/mcp__youtube__summarize

Tóm lại: MCP server = gói kết nối · Tool = động từ (làm gì) · Resource/data = danh từ (cái được đọc). Trong harness, tool là cầu nối để data đi vào context đúng lúc cần — chứ không nạp sẵn hết.

Skills trong Claude Code — đào sâu

Skill = một thư mục chứa SKILL.md + script + tài liệu, giúp agent "học nghề" mà không nhồi hết vào context.

Agent Skills

Progressive disclosure — 3 tầng

  1. Metadata (name + description) luôn nằm trong system prompt — chỉ vài chục token mỗi skill.
  2. Thân SKILL.md chỉ được nạp khi Claude thấy skill liên quan.
  3. File phụ / script chỉ đọc hoặc chạy khi thật sự cần.

Nhờ vậy có thể cài hàng trăm skill mà không tốn context.

Cấu trúc

.claude/skills/pdf-report/
├── SKILL.md
├── reference.md
└── scripts/
    └── fill_form.py
---
name: pdf-report
description: Tạo báo cáo PDF theo mẫu công ty.
  Dùng khi người dùng xin báo cáo, PDF, xuất file.
allowed-tools: Read, Bash(python:*)
---
# Cách làm
1. Đọc reference.md để lấy mẫu
2. Chạy scripts/fill_form.py ...

Vị trí

~/.claude/skills/ (cá nhân), .claude/skills/ (dự án, commit vào git), hoặc trong plugin. Gọi tự động khi khớp description, hoặc thủ công bằng /ten-skill.

Skill vs các thứ khác

CLAUDE.md: luôn nạp, nên ngắn. Skill: nạp theo nhu cầu. Sub-agent: context riêng. MCP: cung cấp tool/dữ liệu. Hook: tất định, không phụ thuộc model.

Mẹo viết skill

  • Description quyết định skill có được kích hoạt — ghi rõ "dùng khi…".
  • Giữ SKILL.md ngắn, đẩy chi tiết sang file phụ.
  • Thao tác tất định → viết script, đừng bắt model tự làm.
  • Dùng skill-creator để tạo và eval skill.

Case study

Anthropic: agent chạy dài hạn

Dựng clone claude.ai qua hàng chục phiên. Thất bại ban đầu: agent cố làm hết một lần, hoặc tuyên bố xong sớm. Sửa bằng harness: initializer agent, danh sách 200+ feature dạng JSON, git commit mỗi bước, test end-to-end bằng Puppeteer.

Đọc bài →

Addy Osmani: Agent Harness Engineering

Luận điểm: hành vi bạn cảm nhận bị chi phối bởi harness, không chỉ model. Mỗi lỗi agent mắc là tín hiệu để thêm một rule, test hay hook — harness "tích lũy" theo thời gian.

Đọc bài →

OpenAI: 1 triệu dòng code không viết tay

Đội nhỏ xây sản phẩm nội bộ trong ~5 tháng mà code do Codex viết. Công việc của kỹ sư chuyển sang thiết kế môi trường: tài liệu có cấu trúc, ràng buộc kiến trúc bằng linter, vòng review agent–agent, dọn "rác" định kỳ.

Đọc bài →

LangChain: Terminal-Bench

Giữ nguyên model, chỉ cải tiến harness (tự kiểm chứng, prompt, middleware theo dõi vòng lặp) → từ ~52,8% lên 66,5%, nhảy từ ngoài top 30 vào top 5.

Learn Claude Code (mã nguồn mở)

Dựng lại harness kiểu Claude Code từ con số 0 qua từng bước: loop → tools → todo → sub-agent → skills → compaction. "Model là tài xế, harness là chiếc xe."

GitHub →

Vụ lộ mã nguồn Claude Code (3/2026)

Phân tích cộng đồng cho thấy Claude Code không phải "wrapper mỏng": query loop dạng state machine, auto-compaction, nhiều tầng phục hồi lỗi tool, hệ thống quyền chi tiết. (Thông tin từ bài phân tích thứ cấp.)

Đọc bài →

Video

Claude Code best practices — Anthropic
Mastering Claude Code in 30 minutes — Anthropic
Claude Code & the evolution of agentic coding — Boris Cherny
Claude Agent Skills Explained — Anthropic
How does Claude Code actually work? — Theo
Introducing Claude Code — Anthropic
Claude Code: Anthropic's CLI Agent — Latent Space
How to Use Claude Code Better Than 98% of People — Nate Herk

Tài liệu nên đọc

Building effective agents

Workflow vs agent, các mẫu kiến trúc nền tảng.

Effective context engineering

Context là tài nguyên hữu hạn — compaction, note-taking, sub-agent.

Writing effective tools for agents

Thiết kế và eval tool cho agent.

Thêm liên kết
Checklist harness cho dự án của bạn
  1. CLAUDE.md ngắn: lệnh build/test, quy ước, cạm bẫy.
  2. Lệnh test chạy nhanh để agent tự kiểm chứng.
  3. Hook PostToolUse format/lint tự động.
  4. Permission allow-list cho lệnh an toàn, deny cho thứ nguy hiểm.
  5. Skill cho quy trình lặp lại (deploy, release, review).
  6. Sub-agent cho tìm kiếm rộng / review độc lập.
  7. Mỗi lỗi agent mắc → thêm một guide hoặc sensor.