Agent Harness: lớp vỏ bọc biến LLM thành agent đáng tin cậy trong production
2025 là năm mọi người race nhau build AI agent. 2026 là năm nhận ra agent hay đến đâu cũng vô dụng nếu thiếu harness tốt. Agent Harness là lớp hạ tầng bọc quanh LLM — xử lý tool, quản lý context, kiểm soát permission, điều phối sub-agent — biến output ngẫu nhiên của model thành hành vi đáng tin cậy trong production. ---
Vấn đề: con agent ngoan ngoãn khi demo, điên loạn khi chạy thật
Chúng tôi từng deploy một coding agent lên môi trường staging. Trong demo nội bộ, nó chạy mượt — phân tích yêu cầu, viết code, chạy test, báo cáo kết quả. Impressive.
Ba ngày sau, team infra báo cáo: agent đã chạy liên tục 6 tiếng, tạo ra 847 file trong thư mục temp, gọi API bên ngoài 2.300 lần, và vẫn chưa hoàn thành task ban đầu.
Không phải lỗi model. Model vẫn "reasoning" bình thường. Vấn đề là không ai kiểm soát nó làm gì với những reasoning đó.
Đây là lúc team BKGlobal bắt đầu nghiêm túc với khái niệm Agent Harness.
Agent Harness là gì?
Hãy tưởng tượng một xe ô tô đua Formula 1. Model (LLM) là động cơ — mạnh, nhanh, tạo ra lực đẩy. Harness là toàn bộ phần còn lại — hệ thống lái, phanh, hộp số, telemetry, safety cage. Thiếu harness, động cơ mạnh nhất thế giới cũng chỉ là đống kim loại chạy lạc.
"The model generates text. The harness decides what that text can touch."
Về kỹ thuật, Agent Harness là lớp software nằm giữa LLM và thế giới thực, chịu trách nhiệm:
- Nhận output từ model (text, tool calls, reasoning)
- Validation và routing — tool call này có hợp lệ không? Permission level nào?
- Thực thi tool trong môi trường kiểm soát
- Quản lý state và context xuyên suốt session dài
- Phối hợp sub-agent khi task cần nhiều agent
- Xử lý lỗi và retry theo chiến lược định sẵn
Nếu bạn đã dùng Claude Code, LangChain, AutoGen, hay CrewAI — bạn đang dùng harness, dù có nhận ra hay không. Sự khác biệt giữa team ship được production và team mãi ở prototype chính là chất lượng của harness.
6 trụ cột của một Agent Harness
Dựa trên kinh nghiệm thực tế và phân tích kiến trúc của các hệ thống production, chúng tôi xác định 6 thành phần cốt lõi:
1. Human-in-the-Loop Controls
Không phải mọi hành động đều nên để agent tự quyết. Với các action có tính irreversible cao — xóa database, gửi email hàng loạt, deploy production — harness phải pause và yêu cầu human approval trước khi thực thi.
Đây không phải vấn đề tin tưởng model hay không. Đây là kiến trúc phòng ngừa rủi ro cho hệ thống production.
2. Filesystem và Resource Access Management
Định nghĩa rõ ràng: agent được đọc/ghi thư mục nào? Truy cập resource gì? Với Claude Code, harness kiểm soát chính xác từng filesystem operation — read, write, delete — với permission riêng cho từng loại.
Nguyên tắc: least privilege by default, mở rộng permission khi task thực sự cần.
3. Tool Call Orchestration
Harness là người điều phối tool, không phải model. Bao gồm:
- Sequencing: tool nào phải chạy trước tool nào
- Error handling: khi tool fail thì retry, fallback, hay escalate?
- Loop prevention: phát hiện và ngắt infinite loop
Ví dụ thực tế: agent của chúng tôi từng bị kẹt trong vòng lặp "read file → parse error → read file → parse error" 40 lần liên tiếp. Harness với circuit breaker đơn giản đã giải quyết.
4. Sub-agent Coordination
Agent phức tạp thường cần nhiều sub-agent chuyên biệt: một agent research, một agent viết code, một agent review. Harness chịu trách nhiệm:
- Spawn và terminate sub-agent
- Context isolation — mỗi sub-agent chỉ thấy context cần thiết, không phải toàn bộ history
- Merge output từ nhiều agent chạy song song
5. Prompt và State Management
Prompt không nên hard-code trong agent. Harness quản lý:
- Prompt library: các instruction template theo context (code review vs feature dev)
- State persistence: lưu và restore trạng thái giữa các session
- Context compaction: tóm tắt history cũ để tránh blown context window
6. Lifecycle Hooks
Các hành vi bất biến cần xảy ra tại điểm cụ thể trong vòng đời agent — không phải trong prompt, mà trong harness:
OnSessionStart: load project config, validate environmentPreToolUse: check permission, log intentPostToolUse: validate output, update stateOnError: trigger retry hoặc alert
Triển khai thực tế với C#/.NET
Dưới đây là skeleton của một Agent Harness đơn giản, phản ánh các pattern chúng tôi dùng trong dự án internal:
// Định nghĩa contract cho tool trong harness
public interface IAgentTool
{
string Name { get; }
ToolPermissionLevel RequiredPermission { get; }
Task<ToolResult> ExecuteAsync(ToolCallRequest request, CancellationToken ct);
}
public enum ToolPermissionLevel
{
ReadOnly, // Auto-approve: đọc file, search code
StateModifying, // Yêu cầu confirm: write file, chạy command
HighRisk // Yêu cầu explicit approval: xóa data, gọi API ngoài
}
// Harness core — điều phối tool dispatch với permission check
public class AgentHarness
{
private readonly IToolRegistry _toolRegistry;
private readonly IPermissionGate _permissionGate;
private readonly IHarnessLogger _logger;
private readonly CircuitBreaker _circuitBreaker;
public async Task<AgentResponse> ProcessAsync(
ModelOutput modelOutput,
AgentContext context,
CancellationToken ct)
{
// Chỉ xử lý tool call — text output trả thẳng về
if (!modelOutput.HasToolCall)
return AgentResponse.FromText(modelOutput.Text);
var toolCall = modelOutput.ToolCall;
// 1. Phát hiện loop trước khi làm gì
if (_circuitBreaker.IsTripped(toolCall.ToolName, context.SessionId))
return AgentResponse.Blocked($"Circuit breaker: {toolCall.ToolName} bị gọi quá nhiều lần");
// 2. Tìm tool trong registry
var tool = _toolRegistry.Find(toolCall.ToolName)
?? throw new UnknownToolException(toolCall.ToolName);
// 3. Kiểm tra permission — harness enforce, không phải model tự quyết
var approved = await _permissionGate.CheckAsync(
tool.RequiredPermission, toolCall, context, ct);
if (!approved)
return AgentResponse.PermissionDenied(toolCall.ToolName);
// 4. Lifecycle hook: PreToolUse
await RunHookAsync(HookType.PreToolUse, toolCall, context, ct);
try
{
_logger.LogToolInvocation(toolCall, context);
var result = await tool.ExecuteAsync(toolCall.Request, ct);
// 5. Lifecycle hook: PostToolUse
await RunHookAsync(HookType.PostToolUse, toolCall, context, ct);
_circuitBreaker.RecordSuccess(toolCall.ToolName, context.SessionId);
return AgentResponse.FromToolResult(result);
}
catch (Exception ex)
{
_circuitBreaker.RecordFailure(toolCall.ToolName, context.SessionId);
_logger.LogToolError(toolCall, ex, context);
// Harness quyết định retry hay escalate — không phải model
return context.RetryCount < 3
? AgentResponse.Retry(ex.Message)
: AgentResponse.Escalate($"Tool {toolCall.ToolName} failed sau 3 lần retry");
}
}
}
// Circuit breaker đơn giản — ngăn infinite loop
public class CircuitBreaker
{
private readonly Dictionary<string, int> _callCounts = new();
private const int MaxCallsPerTool = 10; // Ngưỡng trigger
public bool IsTripped(string toolName, string sessionId)
{
var key = $"{sessionId}:{toolName}";
return _callCounts.GetValueOrDefault(key, 0) >= MaxCallsPerTool;
}
public void RecordSuccess(string toolName, string sessionId)
{
var key = $"{sessionId}:{toolName}";
_callCounts[key] = _callCounts.GetValueOrDefault(key, 0) + 1;
}
public void RecordFailure(string toolName, string sessionId) =>
RecordSuccess(toolName, sessionId); // Failure cũng tính vào count
}
Đây là skeleton — production system cần thêm distributed state, observability, và audit logging. Nhưng pattern cốt lõi là đây: harness kiểm soát mọi interaction giữa model và thế giới ngoài.
Ba-agent harness: pattern của Anthropic
Anthropic gần đây công bố kiến trúc ba-agent harness cho long-running development tasks, và đây là pattern chúng tôi thấy scalable nhất:
┌─────────────────────────────────────────────────┐
│ HARNESS ORCHESTRATOR │
│ │
│ ┌──────────┐ ┌──────────┐ ┌────────────┐ │
│ │ PLANNER │───▶│ GENERATOR│───▶│ EVALUATOR │ │
│ │ Agent │ │ Agent │ │ Agent │ │
│ │ │◀───│ │◀───│ │ │
│ └──────────┘ └──────────┘ └────────────┘ │
│ │ │ │
│ (task breakdown) (adversarial QA) │
└─────────────────────────────────────────────────┘
Tại sao tách Planner và Generator? Bởi vì khi model vừa lên kế hoạch vừa thực thi, nó có xu hướng bảo vệ quyết định của mình — confirmation bias trong AI. Tách ra, Generator tập trung làm, Evaluator tập trung chỉ trích.
Tại sao Evaluator phải hoàn toàn độc lập? Anthropic nhấn mạnh: "Separating the agent doing the work from the agent judging it proves to be a strong lever." Evaluator không biết Generator đã làm gì trước đó — nó chỉ thấy output và grade theo criteria định sẵn.
Với frontend tasks, Evaluator của Anthropic dùng Playwright MCP để thực sự navigate trang web, chứ không chỉ đọc code. Đây là ví dụ harness quyết định chất lượng output — không phải model thông minh hơn.
So sánh: agent có harness vs không có harness
| Tiêu chí | Không có harness | Có harness tốt |
|---|---|---|
| Vòng lặp vô tận | Xảy ra thường xuyên | Circuit breaker ngăn |
| Permission kiểm soát | Model tự quyết | Harness enforce |
| Long-running session | Context bị blown | State machine + compaction |
| Debugging | "Model nói gì?" | Full audit log |
| Parallel agents | Conflict file, data race | Context isolation + worktree |
| Production safety | Không đảm bảo | Human-in-loop cho high-risk action |
Số liệu từ industry: 57% tổ chức đã có agent trong production, nhưng 32% cite quality là barrier số 1. Đây không phải vấn đề model — là vấn đề harness.
5 pattern quan trọng nhất từ Claude Code
Nghiên cứu kiến trúc Claude Code cho thấy 12 harness pattern — đây là 5 cái chúng tôi thấy impactful nhất khi áp dụng vào dự án:
1. Context-Isolated Subagents: Sub-agent chỉ thấy context mình cần. Research agent không thấy toàn bộ codebase. Planning agent không thấy implementation detail. Giúp response quality tốt hơn và tránh context window bloat.
2. Progressive Tool Expansion: Start với toolset nhỏ (< 20 tools), chỉ mở thêm khi task thực sự cần. Vercel đã remove 80% tool của agent và kết quả tốt hơn — quá nhiều tool gây "decision paralysis" cho model.
3. Tiered Memory Pattern: Memory phân tầng — index compact (luôn trong context), topic files (load khi cần), full history (trên disk). Tránh bị forced context compaction làm mất thông tin quan trọng.
4. Command Risk Classification: Pre-parse shell command trước khi model thấy kết quả. Regex đơn giản để phân loại rm -rf khác với ls -la, auto-approve cái an toàn, block cái nguy hiểm.
5. Deterministic Lifecycle Hooks: Hành vi bất biến — format code sau mỗi edit, validate env trước khi chạy, log mọi tool call — không để trong prompt (model có thể bỏ qua), để trong hooks (harness luôn chạy).
Best practices từ kinh nghiệm thực chiến
Từ quá trình build và vận hành agent system tại BKGlobal, chúng tôi rút ra:
Fail fast, recover gracefully. Phát hiện lỗi sớm tốt hơn để lỗi lan rộng. Nhưng recovery phải có chiến lược — retry với exponential backoff, sau đó fallback, sau đó escalate to human.
Minimal necessary intervention. Harness không nên can thiệp khi model đang tự xử lý được. Chỉ intercede khi model không thể self-correct, hoặc khi action là irreversible.
Observability trước optimization. Trước khi tune agent, phải thấy được nó đang làm gì. Full audit log của mọi tool call, latency, token count — không thể optimize cái không đo được.
Harness phức tạp hơn model là bình thường. Manus rewrote harness của họ 5 lần trong 6 tháng với cùng một model. Đây không phải thất bại — đây là iteration để tìm đúng kiến trúc.
Kết luận
Nếu 2025 là năm "xây agent", thì 2026 là năm "làm agent chạy được production". Và thứ quyết định là harness, không phải model.
Mô hình mạnh mà harness yếu → agent nhanh chóng trở thành gánh nặng vận hành. Harness tốt với mô hình vừa phải → hệ thống ổn định, debuggable, extensible.
Tại BKGlobal, chúng tôi đang áp dụng harness engineering vào các dự án AI nội bộ — từ coding assistant đến document processing pipeline. Pattern và code trong bài này là distillation từ kinh nghiệm thực tế đó.
Bước tiếp theo nếu bạn muốn bắt đầu:
- Audit agent hiện tại — nó có circuit breaker không? Permission gating không? Lifecycle hooks không?
- Chọn 1-2 pattern quan trọng nhất để implement trước
- Đo observability trước khi làm bất cứ thứ gì khác
Bài tiếp theo trong series: RAG pipeline kết hợp agent harness — khi document retrieval cần real-time validation và re-ranking trong vòng lặp agent.
Son Do — BKGlobal Tech Team
#BKGlobal #AIAgents #AgentHarness #dotnet #architecture #1percentbetter