- Khởi đầu: Khi các mảnh ghép tạo nên dây chuyền
- Nguyên lý kiến trúc: Hook quanh vòng lặp, không viết lại vòng lặp
- Bốn kỹ thuật lắp ráp dây chuyền harness
- Định lượng hóa output: Chuyển dữ liệu tự do thành tín hiệu đo lường
- Middleware chain: Thiết lập các chốt chặn kiểm soát tuần tự
- Quản lý context: Giữ bộ nhớ tinh gọn và tập trung
- Steering loop: Chuyển hóa thất bại thành quy tắc cải tiến
- Bốn bước xử lý vùng xám: Khi quy tắc không thể xác định hóa
- Bước 1: Bóc tách điều kiện tiên quyết thành chỉ số bán xác định
- Bước 2: Chuẩn hóa thang đo cho Inferential Sensor (Calibrated Rubrics)
- Bước 3: Đánh giá chéo và đo độ bất đồng (Dual-Judge Discrepancy)
- Bước 4: Thu hẹp vùng bất định qua phản hồi của con người
- Quản trị an toàn: Con người trong vòng lặp và điểm dừng an toàn
- Thử nghiệm: Dựng dây chuyền Code Review tự động
- Case study: Coding Agent review Pull Request
- Mở rộng tư duy harness sang Data, Ops và Tài chính
- Lộ trình tiến hóa và những câu hỏi mở
- Lời kết: Từ thử nghiệm đơn lẻ đến cỗ máy vận hành bền bỉ
Harness Engineering (Phần cuối): Kỹ thuật lắp ráp và vận hành
Sở hữu đủ guide và sensor chưa đủ để có một hệ thống trơn tru. Phần cuối hướng dẫn cách lắp ráp và vận hành dây chuyền harness cho coding agent, biến các mảnh ghép rời rạc thành một cỗ máy chạy bền bỉ.

Đọc thêm:
Harness Engineering (Phần 1): Tầm quan trọng của Harness Engineering trong kiến trúc Agentic
Harness Engineering (Phần 2): Cẩm nang hiện thực
Khởi đầu: Khi các mảnh ghép tạo nên dây chuyền
Ở phần 2, chúng ta đã cùng nhau bóc tách harness thành các thành phần cốt lõi từ guide đến sensor. Chúng ta cũng đã phân loại 3 tầng kiểm soát từ bảo trì, kiến trúc đến hành vi cùng nguyên tắc Keep Quality Left.
Thế nhưng, sở hữu đầy đủ các công cụ trên chưa đồng nghĩa với việc bạn đã có một hệ thống vận hành trơn tru. Trong thế giới Agent, Coding Agent là môi trường kiểm chứng lý tưởng và khắc nghiệt nhất cho harness engineering - nơi có compiler phán xét đúng sai rạch ròi, có linter đo đạc quy chuẩn, có test suite bảo vệ hành vi, và có git worktree để cô lập môi trường.
Nếu gom một đống linter, vài con bot review với tệp prompt dài ngoằng lại với nhau mà không biết cách kết nối, bạn sẽ nhanh chóng gặp rắc rối bởi vì:
- Sensor đứng một mình chỉ biết văng log báo lỗi rồi... để đấy
- Guide viết dài cả ngàn dòng nhưng Agent đọc xong rồi quên ngay sau vài lượt chat
- OPA hay Zod schema có chặt chẽ đến mấy cũng thành vô dụng nếu cắm sai chỗ trong luồng thực thi
Vì vậy, bài viết này tập trung đào sâu vào việc lắp ráp dây chuyền harness cho Coding Agent. Khi đã làm chủ được cỗ máy này trên môi trường lập trình, bạn sẽ dễ dàng mang cùng một tư duy kiến trúc đó sang bất kỳ domain nào khác.
Harness chỉ thực sự phát huy sức mạnh khi mọi thứ ráp nối thành một dây chuyền khép kín.

Để đưa sơ đồ trên vào thực tế, chúng ta sẽ bắt đầu từ nguyên lý kiến trúc nền tảng bằng cách cắm các điểm can thiệp quanh vòng lặp của model mà không triệt tiêu sự tự chủ của nó.
Nguyên lý kiến trúc: Hook quanh vòng lặp, không viết lại vòng lặp
Trước khi cắm thêm bất kỳ tầng kiểm soát nào, hãy ghi nhớ một nguyên tắc: đừng cố viết lại vòng lặp cốt lõi của Agent.
Khi xây dựng các coding agent, Anthropic, Google hay OpenAI đã đầu tư nguồn lực khổng lồ để tối ưu vòng lặp thực thi bên dưới: từ cơ chế gọi tool mượt mà, quản lý luồng dữ liệu, cho đến cách model tự sửa sai (self-correction). Việc cố nhồi nhét quá nhiều if-else, vẽ đồ thị node phức tạp hay ép model chạy theo chuỗi prompt gượng gạo sẽ chỉ làm hệ thống cồng kềnh, khó kiểm thử và rất dễ đứt gãy trước những trường hợp biên (edge cases). Thay vì đập đi xây lại bánh xe, việc của chúng ta là hiểu rõ cơ chế và cắm các điểm can thiệp (hooks) vào đúng vị trí quanh vòng lặp sẵn có.
.jpg)
Dự án learn-claude-code của shareAI-lab đúc kết nguyên tắc này trong một câu rất đắt:
"Agency comes from the Model. Harness is the Vehicle."
Trí thông minh và khả năng hành động (Agency) thuộc về model. Harness đóng vai trò là 'chiếc xe' đưa model đi đúng đường thông qua các ranh giới an toàn, công cụ cần thiết và tín hiệu phản hồi.
Vòng lặp cơ bản của một Agent thực ra rất tinh gọn:
async function agentLoop(messages: Message[], harness: Harness): Promise<void> {
while (true) {
const context = await harness.context.prepare(messages);
const response = await client.messages.create({ model, system, messages: context, tools });
messages.push({ role: "assistant", content: response.content });
if (response.stop_reason !== "tool_use") return;
const validation = await harness.middleware.validate(response.content);
if (!validation.ok) {
messages.push({ role: "user", content: validation.feedback });
continue;
}
const results = await harness.tools.execute(response.content);
messages.push({ role: "user", content: results });
}
}
Mọi cơ chế như phân quyền, ghi audit log, thử lại khi lỗi, nén ngữ cảnh hay chờ người phê duyệt đều được gắn vào vòng lặp dưới dạng các điểm can thiệp. Tuyệt đối không chèn logic nghiệp vụ vào nơi model đang suy luận. Đó là tinh thần của nguyên tắc: Hook around the loop, never rewrite the loop.
Ranh giới trách nhiệm lúc này rất rõ ràng: Model quyết định nên làm gì, còn harness kiểm soát xem hành động đó có hợp lệ, có an toàn và có cần sửa lại hay không.
Bốn kỹ thuật lắp ráp dây chuyền harness
Để kết nối các guide và sensor từ phần 2 thành một dây chuyền chạy trơn tru, chúng ta sẽ lần lượt triển khai 4 kỹ thuật lắp ráp nền tảng.

Định lượng hóa output: Chuyển dữ liệu tự do thành tín hiệu đo lường
Chúng ta thường có thói quen giao tiếp với AI rất cảm tính: "Hình như chỗ này chưa ổn lắm" hoặc "Xem lại giùm tôi đoạn này".
Lời nhắc mơ hồ đó đẩy Agent vào một trò chơi đoán mò: nó phải đọc tới đọc lui codebase để suy diễn xem rốt cuộc bạn đang muốn gì. May mắn thì nó đoán trúng. Còn không, sau vài vòng cào source code làm phình context, Agent đành... đoán đại. Oái oăm ở chỗ, chính chúng ta vì "vibe coding" quá nhiều hoặc làm việc trên codebase quá lớn nên cũng chẳng nắm tường tận từng ngóc ngách, đành tặc lưỡi ừ đại và hy vọng AI làm đúng. Đến khi hệ thống vẫn lỗi, phản xạ quen thuộc là nâng cấp lên model to hơn, đắt tiền hơn. Kết quả là chúng ta dùng model xịn nhất, trả hàng đống tiền token, nhưng chất lượng code thì vẫn tệ như cũ.
Vấn đề không nằm ở việc model chưa đủ thông minh, mà vì bạn đang thiếu một sensor định lượng. Sensor không làm việc bằng cảm xúc hay trực giác, nó đòi hỏi các con số biết nói: dính bao nhiêu lỗi, vi phạm ở dòng nào, thiếu trường dữ liệu nào, và tỷ lệ đạt chuẩn là bao nhiêu phần trăm.
Do đó, bước đầu tiên của dây chuyền là ép toàn bộ output văn bản tự do về dạng dữ liệu có cấu trúc - bất kể Agent đang hoạt động trong lĩnh vực nào.
- Coding Agent: Thay vì bắt Agent tự đọc terminal log dài dằng dặc, test runner hoặc linter xuất thẳng ra file JSON gồm số lượng test pass, danh sách file và dòng code bị lỗi.
- Data/Extraction Agent: Dùng Zod schema validator bóc tách rõ trường nào hợp lệ, trường nào thiếu, độ tin cậy (confidence score) đạt bao nhiêu.
- Customer/Ops Agent: Policy engine trả về danh mục điều khoản vi phạm kèm điểm rủi ro cụ thể (risk score).
type ValidationReport = {
passed: number;
total: number;
failures: { target: string; code: string; message: string }[];
};
function parseReport(raw: string): ValidationReport {
const report = JSON.parse(raw);
return {
passed: report.passed,
total: report.total,
failures: report.failures,
};
}
Từ báo cáo JSON này, harness sinh ra tín hiệu phản hồi mang tính xây dựng (constructive prompt injection) vừa đủ gọn để Agent dễ sửa, vừa đủ dữ liệu số để hệ thống lưu vết:
const report = parseReport(result.content);
const failRate = 1 - report.passed / report.total;
const feedback = {
level: failRate > 0.05 ? "FAIL" : "PASS",
fix: report.failures
.map((f) => `fix ${f.target} [${f.code}]: ${f.message}`)
.join("\n"),
};
Đây chính là ranh giới giữa log thông thường và sensor: log chỉ kể lại chuyện đã rồi, còn sensor biến thông tin đó thành mệnh lệnh điều khiển hành động.
Khi mọi sensor đều nhả ra số liệu, bạn sẽ nhìn rõ biểu đồ sức khỏe của hệ thống: tỷ lệ lỗi tuần này tăng hay giảm, Agent mất bao lâu để sửa xong một bug, và tiết kiệm được bao nhiêu tiền token nhờ chặn lỗi sớm từ tầng máy móc.
Middleware chain: Thiết lập các chốt chặn kiểm soát tuần tự
Mỗi khi Agent muốn gọi một công cụ hay chạy một lệnh, đừng bao giờ để nó chạm thẳng vào hệ sinh thái chính. Hành động đó bắt buộc phải đi qua một chuỗi trạm kiểm định chất lượng: xác thực quyền hạn, quét chính sách an toàn, giới hạn tần suất và ghi audit log.
Mô hình lắp ráp chuẩn mực nhất là Interceptor/Onion Pipeline Pattern (tương tự middleware trong Express hay Koa):
type ActionContext = { action: string; params: Record<string, unknown>; userRole: string; securityLevel: "LOW" | "HIGH" };
type Middleware = (ctx: ActionContext, next: () => Promise<void>) => Promise<void>;
async function runPipeline(ctx: ActionContext, middlewares: Middleware[]): Promise<void> {
let index = -1;
async function dispatch(i: number): Promise<void> {
if (i <= index) throw new Error("next() called multiple times");
index = i;
const fn = middlewares[i];
if (fn) await fn(ctx, () => dispatch(i + 1));
}
await dispatch(0);
}
Dây chuyền này kết nối trực tiếp các chính sách và bộ kiểm tra từ Phần 2 vào từng tầng xử lý:
// Cắm trực tiếp Rego OPA Policy (từ Phần 2) vào Guardrail Middleware
const guardrailMiddleware: Middleware = async (ctx, next) => {
const isDestructive = /DROP|DELETE FROM|TRUNCATE/i.test(String(ctx.params.query || ""));
if (isDestructive && ctx.securityLevel !== "LOW") {
throw new Error(`[GUARDRAIL_VIOLATION] Query blocked by ARCH-001 policy`);
}
await next();
};
const auditMiddleware: Middleware = async (ctx, next) => {
await next();
// Ghi nhật ký bất biến sau khi hành động hoàn tất thành công
await db.query("INSERT INTO audit_logs (action, params) VALUES ($1, $2)", [ctx.action, JSON.stringify(ctx.params)]);
};
Tùy vào tính chất sự cố, middleware sẽ chọn cách xử lý phù hợp:
- Ngắt ngay (Fail-fast): Áp dụng cho lỗi phân quyền, vi phạm bảo mật hoặc sai lệch cấu trúc nặng. Dừng ngay lập tức để tránh đốt token vô ích vào một request đã sai từ gốc.
- Hạ cấp (Degrade): Áp dụng cho lỗi hiệu năng nhẹ hoặc sai quy chuẩn trình bày code. Hệ thống ghi nhận cảnh báo để xử lý sau chứ không chặn đứng luồng làm việc.
- Thử lại có giãn cách (Retry với backoff): Áp dụng cho lỗi timeout mạng hoặc chạm trần rate limit, vì đây chỉ là sự cố gián đoạn tạm thời của hạ tầng.
Mỗi middleware đều cần có unit test độc lập để khi bổ sung quy tắc guardrail mới, bạn không sợ làm gãy các chốt chặn cũ.
Quản lý context: Giữ bộ nhớ tinh gọn và tập trung
Một Agent có thể rất thông minh nhưng vẫn làm sai be bét chỉ vì context window đã phình quá to. Lịch sử hội thoại ngập ngụa log terminal, tài liệu nạp vô tội vạ và cào hàng chục kết quả dồn lại sẽ gây ra hai tổn thất chí mạng:
- Hiện tượng Lost in the middle: Khi context dài hàng chục ngàn token, cơ chế attention của LLM có xu hướng chỉ chú ý phần đầu (system prompt) và phần đuôi (tin nhắn gần nhất). Toàn bộ các ràng buộc nghiệp vụ, quy tắc kiến trúc hay chỉ thị then chốt nằm ở khúc giữa sẽ bị trôi tuột và bỏ quên hoàn toàn.
- Chi phí bùng nổ (Cost explosion): Ở mỗi lượt chat tiếp theo, bạn đều phải trả tiền để model đọc lại toàn bộ khối lượng dữ liệu khổng lồ trong quá khứ. Việc này vừa đốt tiền token theo cấp số nhân, vừa kéo dài độ trễ phản hồi, trong khi chất lượng suy luận lại suy giảm nghiêm trọng.
Do đó, giữ cho context luôn tinh gọn là yêu cầu sống còn của harness. Tuy nhiên, cách xử lý cụ thể phụ thuộc vào vị thế của bạn: bạn tự code Agent runtime hay bạn đang sử dụng một Coding Agent có sẵn (như Claude Code, OpenCode, Codex, Cursor...)?
Trường hợp 1: Tự xây dựng Agent Runtime (Custom Engine)
Tự nắm mảng messages: Message[], bạn có toàn quyền điều tiết bằng code:
snip: Tự động cắt tỉa output của công cụ khi vượt quá dung lượng cho phép.micro-compact: Tóm tắt lịch sử trao đổi cũ thành các ghi chú ngắn gọn, giữ lại quyết định và ràng buộc then chốt, gạt bỏ những đoạn trao đổi phụ trợ.toolResultBudget: Đặt trần dung lượng cho dữ liệu trả về từ công cụ, ép công cụ chỉ cung cấp đúng thông tin cần thiết.
Hàm snipToolResult thực chiến:
function snipToolResult(rawOutput: string, maxTokens: number = 2000): string {
const estimatedTokens = Math.ceil(rawOutput.length / 4);
if (estimatedTokens <= maxTokens) return rawOutput;
const lines = rawOutput.split("\n");
const head = lines.slice(0, 15).join("\n");
const tail = lines.slice(-10).join("\n");
const omitted = lines.length - 25;
return `${head}\n\n[...SNIPPED ${omitted} LINES (exceeded ${maxTokens} token budget)...]\n\n${tail}`;
}
Trường hợp 2: Dùng Coding Agent có sẵn
Ở vị thế người dùng, bạn không thể can thiệp vào vòng lặp ngầm bên dưới của hãng. Nếu Agent lỡ chạy một lệnh grep hay npm test xuất ra 5,000 dòng log, toàn bộ số đó sẽ lấp đầy context window. Lúc này, vũ khí duy nhất của bạn là thiết kế hệ thống Skills và Guides theo cơ chế nạp on-demand (Progressive Disclosure):
-
Biến
AGENTS.mdthành một bản đồ chỉ đường (Router siêu nhẹ): Đừng nhét toàn bộ tài liệu kiến trúc hàng ngàn dòng vàoAGENTS.mdhay file config. Hãy giữ file này dưới 150 dòng, đóng vai trò như một Router điều hướng trỏ tới các Skill chuyên biệt:- Khi sửa database/migration: Đọc .agents/skills/db-guidelines/SKILL.md - Khi viết API endpoint: Đọc .agents/skills/api-conventions/SKILL.md - Khi audit kiến trúc: Chạy script python3 .agents/scripts/verify.pyAgent chỉ dùng công cụ đọc file chi tiết khi bắt đầu nhận task liên quan, giúp context ban đầu luôn sạch tinh tươm.
-
Bắt Agent dùng 'kính hiển vi' để soi, cấm dùng 'máy hút bụi' chỉ để dọn: Trong Guide, cấm các lệnh đọc toàn bộ file dài; bắt buộc dùng lệnh có bộ lọc chính xác (
pytest -k test_login, chỉ xem lát cắt 50 dòng code liên quan thay vì load toàn bộ file 3,000 dòng). -
Cách ly rác bằng Subagent (Task Isolation): Khi cần đọc tài liệu dài hoặc debug một lỗi khó, hãy phân rã việc đó cho một Subagent. Subagent có thể tiêu tốn 50k token để thử-sai trong sandbox riêng, nhưng khi kết thúc chỉ trả về một bản tóm tắt 200 token cho Agent chính. Toàn bộ rác ngữ cảnh của quá trình thử-sai bị triệt tiêu hoàn toàn.
Steering loop: Chuyển hóa thất bại thành quy tắc cải tiến
Một harness chuẩn mực không xem thất bại là sự kết thúc, mà coi đó là nguồn dữ liệu quý giá để nâng cấp chính dây chuyền vận hành.
Khi Agent thất bại ở bước xác thực dữ liệu, chạy test fail, vi phạm chính sách bảo mật hay nhận điểm đánh giá thấp từ khâu kiểm duyệt, đừng vội can thiệp thủ công. Hãy bắt đầu bằng việc phân tích nguyên nhân gốc rễ:
- Đây là lỗi thật của Agent hay do sensor báo nhầm (false positive)?
- Nếu là lỗi thật, quy tắc nào còn thiếu trong guide khiến Agent đi lạc?
- Nếu là sensor báo nhầm, logic kiểm tra nào cần được tinh chỉnh?
Steering loop vận hành theo chu trình 4 bước khép kín:
- Detect (Phát hiện): Sensor kích hoạt và trích xuất lỗi thành dữ liệu có cấu trúc
- Triage (Phân loại): Phân biệt lỗi ngẫu nhiên (false positive) hay lỗi hệ thống lặp lại (true positive)
- Upgrade (Nâng cấp): Bổ sung chỉ thị vào guide (
AGENTS.md) hoặc thêm quy tắc kiểm tra vào sensor - Verify (Kiểm chứng): Chạy lại tác vụ để chứng minh quy tắc mới đã ngăn chặn triệt để lỗi cũ
Theo Luật đa dạng cần thiết (Law of Requisite Variety) của Ross Ashby, một bộ điều khiển muốn kiểm soát được một hệ thống thì phải có độ đa dạng phản hồi tương đương với độ đa dạng của hệ thống đó. Lỗi của Agent càng biến hóa, mạng lưới guide và sensor của harness càng phải bao phủ rộng. Khi một dạng lỗi mới xuất hiện, đó chính là tín hiệu cho thấy harness đang thiếu một quy tắc định hướng trong guide hoặc một kịch bản bắt lỗi trong sensor.
Nguyên lý này kết nối trực tiếp với chiến lược Keep Quality Left:
- Nếu Agent lặp lại cùng một lỗi 3 lần, hãy bổ sung ngay chỉ thị vào
AGENTS.mdhoặc cấu hình hệ thống. - Nếu Agent liên tục vi phạm ranh giới nghiệp vụ, hãy mã hóa quy tắc đó thành một policy xác định.
Một lỗi lặp lại không còn là sự cố riêng lẻ, mà chính là một yêu cầu thiết kế mới cho harness.
Để đánh giá tính hiệu quả của steering loop, hệ thống theo dõi 3 chỉ số chính:
- Fail rate trend: Xu hướng tỷ lệ thất bại tăng hay giảm theo thời gian.
- Time to fix: Thời gian trung bình để Agent sửa xong lỗi từ trạng thái FAIL sang PASS.
- Token saved: Chi phí tiết kiệm được nhờ các computational sensor chặn lỗi sớm trước khi cần gọi đến LLM.
Bốn bước xử lý vùng xám: Khi quy tắc không thể xác định hóa
Các ví dụ về linter, typecheck hay Rego policy đều dựa trên một giả định thuận lợi: quy tắc có thể viết thành code xác định (computational). Nhưng trong thực tế, nhiều yêu cầu nghiệp vụ phức tạp lại nằm ở vùng xám ngữ nghĩa:
- "Đoạn mã này có thiết kế sạch và đúng chuẩn domain architecture không?"
- "Báo cáo thị trường này có lập luận logic và đối soát đúng với tài liệu gốc không?"
- "Câu trả lời của Agent tư vấn có giữ đúng thái độ cảm thông và chuẩn mực thương hiệu không?"
Đây là những quy tắc không thể kiểm tra bằng Regex hay AST parser. Nếu cố ép chúng thành những quy tắc cứng nhắc, bạn sẽ bóp nghẹt tính sáng tạo của model. Ngược lại, nếu buông lỏng cho model tự quyết định, hệ thống sẽ đối mặt với rủi ro hallucination.
Khi đối mặt với vùng xám này, harness sẽ áp dụng chiến lược kiểm soát 4 bước.
Bước 1: Bóc tách điều kiện tiên quyết thành chỉ số bán xác định
Đừng cố đánh giá một khái niệm trừu tượng như 'code sạch' trong một lần kiểm tra duy nhất. Hãy bóc tách phần lớn khung kỹ thuật thành các điều kiện cứng có thể đo đạc bằng máy:
- Hàm không vượt quá 30 dòng
- Không mutate biến toàn cục
- Bắt buộc có ít nhất 2 unit test cho trường hợp biên
- Có docstring giải thích lý do (rationale) khi sử dụng design pattern
Khi phần khung kỹ thuật đã được các computational sensor bảo vệ, phạm vi ngữ nghĩa còn lại cần đánh giá sẽ thu hẹp đáng kể.
Bước 2: Chuẩn hóa thang đo cho Inferential Sensor (Calibrated Rubrics)
Với phần ngữ nghĩa còn lại, chúng ta sử dụng một LLM độc lập (LLM-as-a-Judge) làm sensor. Để tránh việc Judge đưa ra phán đoán thất thường, harness cung cấp một bộ Rubric chuẩn hóa kèm ví dụ mẫu (Few-shot Calibrated Examples):
- Không hỏi chung chung: "Bài viết này hay không?"
- Yêu cầu chấm điểm theo tiêu chí rõ ràng: "Đánh giá tính mạch lạc theo thang từ 1 đến 5. Điểm 5 phải đáp ứng: có dẫn chứng số liệu, không mâu thuẫn giữa các đoạn, kết luận rút ra từ dữ liệu đã nêu."
- Cung cấp ít nhất 2 mẫu PASS và 2 mẫu FAIL điển hình từ các sự cố trong quá khứ
Bước 3: Đánh giá chéo và đo độ bất đồng (Dual-Judge Discrepancy)
Đối với các tác vụ có rủi ro cao nhưng mang tính định tính, harness triển khai cơ chế chấm điểm kép (Dual-Judge):
- Hai mô hình (hoặc hai prompt với góc nhìn phản biện đối lập) cùng đánh giá độc lập một output
- Nếu cả hai thẩm định viên cùng đồng thuận PASS (hoặc FAIL), kết quả được chấp nhận tự động
- Nếu xuất hiện sự bất đồng (ví dụ: một bên chấm 4/5, một bên chấm 2/5) hoặc mức độ tự tin (confidence score) thấp hơn ngưỡng an toàn, harness lập tức kích hoạt cờ cảnh báo
type JudgeVerdict = {
score: number;
confidence: number;
rationale: string;
};
function evaluateGrayZone(primary: JudgeVerdict, shadow: JudgeVerdict): "PASS" | "FAIL" | "ESCALATE" {
const discrepancy = Math.abs(primary.score - shadow.score);
if (discrepancy >= 2 || primary.confidence < 0.8) {
return "ESCALATE";
}
return primary.score >= 4 ? "PASS" : "FAIL";
}
Bước 4: Thu hẹp vùng bất định qua phản hồi của con người
Khi cờ ESCALATE kích hoạt, approvalMiddleware đưa trường hợp bất đồng đến chuyên gia con người.
Điểm mấu chốt của harness đó là quyết định của con người không chỉ để giải quyết tác vụ hiện tại, mà còn trở thành dữ liệu hiệu chuẩn mới (calibration dataset). Mỗi lần chuyên gia phân xử và để lại lý do, lý do đó được nạp ngược lại vào bộ Rubric của Inferential Sensor hoặc mã hóa thành một rule xác định mới trong Guide. Qua thời gian, vùng xám ngữ nghĩa sẽ ngày càng thu hẹp lại.
Quản trị an toàn: Con người trong vòng lặp và điểm dừng an toàn
Không nên thả cho AI tự quyết mọi hành động chỉ vì chúng ta muốn tự động hóa tối đa. Thiệt hại sẽ ra sao nếu để AI tự do xóa một hàm dùng chung đang có hàng chục module phụ thuộc, chạy migration xóa bảng, git reset --hard cuốn phăng code chưa kịp commit? Hay bi kịch quen thuộc khi developer lỡ bật chế độ 'YOLO mode' - tự động duyệt mọi lệnh mà không hỏi lại khiến Agent thẳng tay xóa sạch cơ sở dữ liệu.
Trong lập trình, khi một thao tác có bán kính thiệt hại lớn (blast radius), harness bắt buộc phải chủ động dựng rào chắn để xin ý kiến con người.
Chốt chặn này cũng tự động kích hoạt khi các inferential sensor bất đồng quan điểm hoặc khi Agent chuẩn bị can thiệp vào các PR sửa đổi kiến trúc lõi. Cách triển khai trực quan nhất là thiết lập bước phê duyệt thành một middleware trong chuỗi:
const approvalMiddleware: Middleware = async (ctx, next) => {
const requiresApproval = ctx.securityLevel === "HIGH" || ctx.action === "MIGRATE_DB";
if (!requiresApproval) return next();
const verdict = await askHumanApproval({
action: ctx.action,
params: ctx.params,
reason: "High blast-radius operation requires confirmation",
});
if (verdict !== "APPROVED") throw new Error(`[APPROVAL_REJECTED] Rejected by human operator`);
await next();
};
Vị trí của middleware này mang tính quyết định: yêu cầu phê duyệt quá sớm sẽ biến con người thành 'nút bấm thủ công' cho mọi thao tác nhỏ; yêu cầu quá muộn thì tổn thất đã xảy ra. Computational sensor tự động xử lý các quy tắc cứng, còn con người chỉ xuất hiện tại những điểm mờ mà chính sách chưa bao quát hết, hoặc những nơi chi phí sai sót vượt xa thời gian chờ phê duyệt.
Khi mọi nhánh xử lý đều thất bại, Dead Letter Queue (DLQ) đóng vai trò chốt chặn cuối cùng. Tác vụ chuyển vào hàng đợi kèm theo bản chụp trạng thái đầy đủ:
type DLQRecord = {
sessionId: string;
failingAction: string;
retryCount: number;
contextSnapshot: string;
errorLog: string;
reproductionCommand: string;
};
Nhờ bản ghi này, kỹ sư vận hành chỉ cần gõ đúng một câu lệnh reproductionCommand là có thể tái hiện chính xác ngữ cảnh gặp sự cố của Agent mà không mất công rà soát log thô.
Thử nghiệm: Dựng dây chuyền Code Review tự động
Để thấy rõ cách toàn bộ hệ thống phối hợp nhịp nhàng, hãy cùng xem xét một bài toán thực tế: dựng dây chuyền Code Review cho Coding Agent, sau đó mở rộng mô hình này sang các bài toán khác.
Case study: Coding Agent review Pull Request
Vấn đề: Trước khi có harness, chúng ta hay ném file diff cho Agent và bảo: "Review giúp tôi PR này xem ổn không". Vì nhận một yêu cầu mơ hồ, Agent cũng 'vibe review' lại y hệt: liếc qua diff vài giây, thấy syntax không đỏ là hào phóng phán "Code trông rất sạch, LGTM!". Cả người lẫn AI đều thấy yên tâm cho đến khi lên production thì hệ thống toang vì những hàm gọi xung quanh (callers) bị gãy mà không ai hay biết.
Triển khai dây chuyền 4 bước:
-
Guide: File
AGENTS.mdquy định một lượt review hợp lệ bắt buộc đính kèm bằng chứng là danh sách các file đã đọc (bao gồm các hàm gọi đến đoạn mã bị sửa), câu lệnh test đã chạy, và mỗi nhận xét trỏ chính xác đến dòng code tương ứng. -
Sensor: Áp dụng kết hợp cả hai tầng:
- Computational Sensor: Chuyển đổi output của review thành số liệu (số file đã mở, số test đã chạy, số nhận xét có đính kèm dòng tham chiếu). Nếu chỉ số không đạt ngưỡng, review bị gắn cờ "shallow" và chuyển ngược lại cho Agent xử lý tiếp.
- Inferential Sensor: Sử dụng một LLM độc lập để đánh giá độ sâu và chất lượng của các nhận xét từ Agent.
-
Middleware chain: Lớp guardrail tự động ngắt (fail-fast) các review thiếu bằng chứng. Lớp audit lưu trữ đầy đủ nhật ký đánh giá. Các PR tác động đến kiến trúc lõi được định tuyến qua
approvalMiddlewaređể Tech Lead phê duyệt. -
Steering loop: Khi một bug lọt qua khâu rà soát, đội ngũ kỹ thuật phân tích nguyên nhân và bổ sung quy tắc mới vào guide: "Bắt buộc kiểm tra callers của mọi hàm có chữ ký (function signature) bị thay đổi".
Kết quả đo lường thực tế:
- Tỷ lệ phát hiện bug callers tăng từ 22% lên 91% nhờ sensor bắt buộc duyệt đồ thị phụ thuộc
- Thời gian review của Tech Lead giảm 45% do các lỗi hình thức và vi phạm quy chuẩn đã bị chặn từ sớm
- Zero security violation: Không có bất kỳ lệnh nguy hiểm hay thay đổi phân quyền trái phép nào lọt qua nhánh chính
Mở rộng tư duy harness sang Data, Ops và Tài chính
Khi đã dựng vững dây chuyền cho Coding Agent, bạn hoàn toàn có thể mang trọn vẹn bộ khung này sang các bài toán khác ngoài lập trình.
| Thành phần harness | Coding Agent (Trọng tâm) | Data/Research Agent | Customer Ops/Financial Agent |
|---|---|---|---|
| Guide | AGENTS.md: Cấm any, chuẩn layered, ErrorEnvelope | Quy định nguồn dữ liệu tin cậy, JSON schema bắt buộc | Quy tắc phản hồi khách hàng (SOP), hạn mức thanh toán |
| Sensor (Computational) | Linter, Typecheck, Unit test runner xuất báo cáo JSON | JSON Schema Validator, đối soát số liệu (chênh lệch = 0) | Regex kiểm tra rò rỉ PII, kiểm tra số tiền giao dịch hợp lệ |
| Sensor (Inferential) | LLM đánh giá kiến trúc, LLM-as-a-Judge chấm điểm review | LLM đối chiếu tính logic của báo cáo với tài liệu gốc | LLM đánh giá thái độ phản hồi (sentiment) và kịch bản tư vấn |
| Middleware Chain | Guardrail cấm DROP TABLE, cấm sửa file ngoài task | Rate-limit số truy vấn, Sandbox trích xuất dữ liệu | Phân quyền vai trò, mã hóa dữ liệu nhạy cảm trước khi lưu |
| Human-in-the-loop | Tech Lead duyệt PR sửa kiến trúc lõi | Chuyên gia dữ liệu duyệt báo cáo trước khi xuất bản | Kế toán trưởng duyệt các giao dịch hoàn tiền >$10,000 |
Nguyên lý bất biến: dù ở domain nào, hãyluôn bắt đầu từ các chốt chặn computational rẻ và xác định, dùng inferential để xử lý ngữ nghĩa, và giữ con người ở vị trí phán quyết tại các điểm rủi ro cao.
Lộ trình tiến hóa và những câu hỏi mở
Một hệ thống harness không nhất thiết phải đồ sộ ngay từ ngày đầu, mà nên lớn dần tương ứng với quy mô dự án qua 6 nấc thang tiến hóa.
.jpg)
- Act (Hành động cơ bản): Dựng vòng lặp cốt lõi, cấp quyền cơ bản và gắn các điểm can thiệp vào từng lượt gọi công cụ
- Handle (Xử lý nâng cao): Agent biết tự phân rã tác vụ cho subagent và chủ động thu gọn context khi lịch sử hội thoại phình to
- Remember (Quản lý tri thức): Bổ sung bộ nhớ dài hạn (Memory) và nạp tài liệu theo nhu cầu (On-demand skills), tránh nhồi nhét vào prompt ban đầu
- Long (Vận hành bền bỉ): Duy trì trạng thái qua nhiều phiên làm việc (session) nhờ tiến trình nền và cronjob, tự động thực thi nhiệm vụ định kỳ
- Coordinate (Phối hợp Multi-Agent): Nhiều Agent chạy song song trên các workspace/sandbox độc lập và đồng bộ trạng thái qua kênh điều phối trung tâm
- Extend (Tự thích ứng & Mở rộng): Tích hợp giao thức mở (như MCP) và meta-harness, nơi hệ thống có thể tự đề xuất quy tắc guide mới dựa trên nhật ký quan sát lỗi
Tuy nhiên, khi bước lên những nấc thang cao hơn, bạn sẽ đối mặt với 3 bài toán thực chiến chưa có lời giải hoàn hảo:
- Ngưỡng tự trị và bài toán chi phí: Khi nào nên để Agent tự sửa lỗi qua sensor, và khi nào bắt buộc phải ngắt luồng gọi người? Đặt trần retry quá cao thì cháy token và độ trễ tăng vọt; đặt quá thấp thì triệt tiêu tính tự chủ. Cùng với đó là độ trễ của Middleware Chain, khi số lượng guardrail tăng lên, làm sao phân loại rạch ròi chỗ nào cần chặn đồng bộ (blocking), chỗ nào có thể đẩy ra chạy ngầm bất đồng bộ?
- Xung đột quy tắc và điểm mù của Inferential Sensor: Khi chỉ dẫn trong guide mâu thuẫn với logic kiểm tra trong sensor, Agent sẽ rơi vào vòng lặp vô tận. Nguy hiểm hơn, bản thân LLM đóng vai trò giám khảo (Judge) cũng có thể chấm nhầm hoặc bỏ lọt lỗi logic tinh vi. Trong trường hợp đó, ranh giới trách nhiệm thuộc về ai: Agent viết code, harness, hay kỹ sư thiết kế rubric cho Judge?
- Thước đo hiệu quả thực chất: Các con số như Fail rate, Time to fix hay Token saved chỉ là chỉ số đại diện (proxy metrics). Thước đo tối thượng của một harness giỏi không phải là siết thật chặt để không bao giờ có lỗi, mà là tìm được điểm cân bằng: đủ an toàn để bảo vệ hệ thống, nhưng cũng đủ thoáng để Agent tự do phát huy tối đa sức mạnh của model.
Lời kết: Từ thử nghiệm đơn lẻ đến cỗ máy vận hành bền bỉ
Sự khác biệt lớn nhất giữa Vibe Coding và Harness Engineering nằm ở ranh giới giữa cầu may và kỷ luật.
Một bên đặt trọn niềm tin vào may rủi, trả tiền tấn cho model đời mới nhất để cầu nguyện nó đoán trúng ý mình. Một bên thiết lập hạ tầng kỹ nghệ vững chắc để ngay cả một model tầm trung cũng buộc phải tạo ra kết quả chính xác, an toàn và lặp lại được.
Harness Engineering không suy nghĩ thay cho model, mà đóng vai trò như bộ khung gầm vững chắc và hệ thống đường ray an toàn, cho phép model tự do phát huy trí thông minh trong ranh giới kiểm soát: mọi hành vi đều quan sát được, mọi rủi ro đều có chốt chặn, và con người luôn giữ vai trò cầm trịch tại những mắt xích phán đoán mang tính quyết định.
Đặt trong bức tranh tổng thể của kiến trúc Agent hiện đại, harness engineering là nền tảng cốt lõi. Khi kết hợp chặt chẽ cùng Loop Engineering (nghệ thuật tối ưu từng bước lặp tự chủ) và Graph Engineering (nghệ thuật thiết kế trạng thái, luồng dữ liệu và điều phối mạng lưới đa tác tử), harness giúp hệ thống Agent trở nên chính xác hơn, thông minh hơn và bền bỉ tự hoàn thiện theo thời gian.
Tham khảo
- shareAI-lab, "Learn Claude Code"
- Birgitta Böckeler & Nicola Gasparro, "Harness engineering for coding agent users"
- Open Policy Agent, "Policy-based control for cloud native environments"
- W. Ross Ashby, "Variety (cybernetics)", xem khái niệm Law of Requisite Variety
- Ned Letcher, "Harnessability", xem khái niệm Ambient Affordances