codex-harness-engineering 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +73 -0
- package/README.md +136 -0
- package/docs/harness-engineering/implementation-playbook.md +370 -0
- package/docs/harness-engineering/index.md +61 -0
- package/docs/harness-engineering/research-note.md +318 -0
- package/docs/harness-engineering/sources.md +126 -0
- package/package.json +38 -0
- package/scripts/install-skills.mjs +104 -0
- package/scripts/publish.sh +139 -0
- package/scripts/verify-harness.mjs +175 -0
- package/skills/acceptance-contract/SKILL.md +78 -0
- package/skills/acceptance-contract/agents/openai.yaml +4 -0
- package/skills/cleanup-harness/SKILL.md +90 -0
- package/skills/cleanup-harness/agents/openai.yaml +4 -0
- package/skills/creator-harness/SKILL.md +124 -0
- package/skills/creator-harness/agents/openai.yaml +4 -0
- package/skills/creator-harness/references/harness-artifacts.md +302 -0
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
# Harness Engineering cho AI Agent làm việc dài hạn
|
|
2
|
+
|
|
3
|
+
## Tóm tắt
|
|
4
|
+
|
|
5
|
+
Harness engineering là kỷ luật thiết kế môi trường quanh AI agent để agent có
|
|
6
|
+
thể tạo tiến triển dài hạn, kiểm chứng được, và duy trì được. Các nghiên cứu của
|
|
7
|
+
OpenAI, Anthropic và Google cho thấy cùng một luận điểm: năng lực mô hình chỉ trở
|
|
8
|
+
thành năng lực sản xuất khi môi trường cung cấp state bền vững, tool dễ dùng,
|
|
9
|
+
quan sát runtime, tiêu chí nghiệm thu, feedback loop, guardrail cơ học, dọn dẹp
|
|
10
|
+
hệ thống, và các cơ chế tự động hóa hay đánh giá vết chạy [S1], [S2], [S3], [S4], [S5].
|
|
11
|
+
|
|
12
|
+
Tài liệu này tổng hợp năm nguồn đó. Mọi nguồn mở rộng khác ngoài phạm vi đã bị
|
|
13
|
+
loại bỏ để giữ trọng tâm.
|
|
14
|
+
|
|
15
|
+
## 1. Vấn đề
|
|
16
|
+
|
|
17
|
+
Một agent có thể viết code tốt trong một lượt nhưng vẫn thất bại ở công việc dài
|
|
18
|
+
hạn. Các failure mode lặp lại là:
|
|
19
|
+
|
|
20
|
+
- session mới không biết session trước đã làm gì;
|
|
21
|
+
- agent cố hoàn thành toàn bộ app trong một lần và để lại trạng thái khó tiếp
|
|
22
|
+
tục;
|
|
23
|
+
- agent nhìn thấy vài feature đã xong rồi tuyên bố cả dự án hoàn thành;
|
|
24
|
+
- agent sửa code nhưng không kiểm thử đầu-cuối;
|
|
25
|
+
- agent không thấy UI, log, metric, trace, hoặc trạng thái runtime;
|
|
26
|
+
- throughput cao làm pattern xấu lan rộng nhanh hơn tốc độ con người review.
|
|
27
|
+
|
|
28
|
+
Anthropic mô tả vấn đề multi-session như một bài toán khôi phục trạng thái:
|
|
29
|
+
context window không đủ để bảo toàn toàn bộ tiến triển, nên harness phải đặt
|
|
30
|
+
state vào artifact bền vững như feature list, progress file, `init.sh`, và git
|
|
31
|
+
history [S2]. OpenAI mô tả cùng vấn đề ở quy mô repository: khi agent tạo code
|
|
32
|
+
nhanh hơn con người có thể QA thủ công, công việc kỹ sư chuyển sang thiết kế
|
|
33
|
+
môi trường, feedback loop, và control system quanh agent [S1].
|
|
34
|
+
|
|
35
|
+
Một ràng buộc quan trọng đến từ Anthropic: không phải mọi task đều cần agent hay
|
|
36
|
+
harness phức tạp. Nên bắt đầu bằng giải pháp đơn giản nhất, dùng workflow khi
|
|
37
|
+
đường đi đã rõ, và chỉ dùng agent tự chủ hoặc orchestration nhiều bước khi
|
|
38
|
+
tradeoff về cost, latency, và lỗi tích lũy được biện minh bằng outcome [S3].
|
|
39
|
+
|
|
40
|
+
## 2. Định nghĩa
|
|
41
|
+
|
|
42
|
+
Trong phạm vi năm nguồn này, **harness** là lớp scaffold ngoài mô hình giúp
|
|
43
|
+
agent làm việc đáng tin hơn. Nó có thể bao gồm:
|
|
44
|
+
|
|
45
|
+
- prompt và acceptance criteria;
|
|
46
|
+
- file state như feature list và progress log;
|
|
47
|
+
- script setup như `init.sh`;
|
|
48
|
+
- git history và commit discipline;
|
|
49
|
+
- tool để chạy app, browser automation, API check, log, metric, trace;
|
|
50
|
+
- planner, generator, evaluator khi task cần tách vai trò;
|
|
51
|
+
- linter, structural test, CI rule, và cleanup cadence;
|
|
52
|
+
- tự động tổng hợp lớp bọc thực thi (code harness/wrapper) để chặn hành động lỗi [S5];
|
|
53
|
+
- hệ thống đánh giá vết chạy (trajectory evaluation) và LLM-as-a-judge [S5].
|
|
54
|
+
|
|
55
|
+
Harness engineering là việc thiết kế, đo, và điều chỉnh lớp scaffold đó. Nó
|
|
56
|
+
khác với prompt engineering ở chỗ trọng tâm không chỉ là câu lệnh cho một lượt
|
|
57
|
+
model, mà là toàn bộ môi trường giúp nhiều lượt agent tiếp tục, quan sát, sửa,
|
|
58
|
+
và để lại bằng chứng.
|
|
59
|
+
|
|
60
|
+
## 3. Vai trò mới của kỹ sư
|
|
61
|
+
|
|
62
|
+
OpenAI tóm tắt mô hình vận hành bằng ý tưởng: con người định hướng, agent thực
|
|
63
|
+
thi. Trong case study của họ, Codex viết application logic, test, CI,
|
|
64
|
+
documentation, observability, và internal tooling; con người ưu tiên công việc,
|
|
65
|
+
dịch phản hồi thành acceptance criteria, xác minh outcome, và biến failure thành
|
|
66
|
+
cải tiến môi trường [S1].
|
|
67
|
+
|
|
68
|
+
Điểm quan trọng không phải là thay con người bằng agent, mà là chuyển tầng làm
|
|
69
|
+
việc của con người. Khi agent thất bại, câu hỏi tốt không phải "nhắc mạnh hơn
|
|
70
|
+
được không?", mà là "agent thiếu capability, context, tool, guardrail, hoặc
|
|
71
|
+
feedback loop nào?" [S1].
|
|
72
|
+
|
|
73
|
+
## 4. Nguyên lý vận hành
|
|
74
|
+
|
|
75
|
+
### 4.1 Bắt đầu đơn giản
|
|
76
|
+
|
|
77
|
+
Anthropic phân biệt workflow và agent. Workflow dùng đường đi định sẵn; agent
|
|
78
|
+
tự điều khiển process và tool usage. Vì agentic system đổi latency và cost lấy
|
|
79
|
+
performance, harness nên bắt đầu từ cấu trúc nhỏ nhất: một LLM call có retrieval,
|
|
80
|
+
tool, memory, hoặc một workflow đơn giản nếu task phân rã rõ [S3].
|
|
81
|
+
|
|
82
|
+
Chỉ thêm planner, evaluator, nhiều agent, hoặc vòng lặp dài khi failure mode cụ
|
|
83
|
+
thể xuất hiện: mất context, tự đánh giá yếu, runtime vô hình, scope drift, hoặc
|
|
84
|
+
QA không đủ [S2], [S4].
|
|
85
|
+
|
|
86
|
+
### 4.2 Ngoại hóa trạng thái
|
|
87
|
+
|
|
88
|
+
Harness cho agent dài hạn cần đưa bộ nhớ ra khỏi hội thoại. Anthropic dùng
|
|
89
|
+
initializer agent để tạo `init.sh`, progress file, feature list, và commit ban
|
|
90
|
+
đầu. Coding agent sau đó đọc các artifact này, chọn một feature chưa pass, làm
|
|
91
|
+
từng bước, cập nhật progress, và commit trạng thái sạch [S2].
|
|
92
|
+
|
|
93
|
+
Feature list có vai trò như contract bền vững. Mỗi feature nên có mô tả, bước
|
|
94
|
+
kiểm tra, và trạng thái pass/fail. Agent chỉ được đổi trạng thái sau khi xác
|
|
95
|
+
minh. Cách này giảm hai lỗi phổ biến: làm quá rộng và đánh dấu xong quá sớm
|
|
96
|
+
[S2].
|
|
97
|
+
|
|
98
|
+
Việc Anthropic dùng `feature_list.json` thay vì prose thuần cũng cho thấy một
|
|
99
|
+
điểm thiết kế quan trọng: trạng thái công việc nên đủ có cấu trúc để session
|
|
100
|
+
mới đọc, lọc, và cập nhật pass/fail nhất quán mà không phải suy diễn lại từ
|
|
101
|
+
văn bản tự do [S2].
|
|
102
|
+
|
|
103
|
+
Git history trong mẫu harness này cũng không chỉ là nhật ký. Anthropic nêu rõ
|
|
104
|
+
việc để agent kết thúc session bằng commit message mô tả rõ và progress update
|
|
105
|
+
giúp nó có recovery point để revert thay đổi xấu và quay về working state sạch
|
|
106
|
+
hơn trong vòng sau [S2].
|
|
107
|
+
|
|
108
|
+
OpenAI áp dụng cùng logic ở mức repository knowledge: `AGENTS.md` nên là bản đồ
|
|
109
|
+
ngắn trỏ tới tài liệu sâu hơn, còn source of truth nằm trong `docs/`, plan,
|
|
110
|
+
schema, test, lint, và artifact version hóa. Nếu quyết định chỉ nằm trong chat,
|
|
111
|
+
Google Docs riêng, hoặc trí nhớ con người, agent khó dùng nó trong lúc chạy
|
|
112
|
+
[S1].
|
|
113
|
+
|
|
114
|
+
Một diễn giải thực dụng từ [S1] và [S2] là nên tách hai loại trạng thái. Loại
|
|
115
|
+
ổn định của repository gồm rule, architecture, setup, và lệnh chuẩn; loại biến
|
|
116
|
+
động của công việc gồm feature đang làm, kết quả verify gần nhất, và bước kế
|
|
117
|
+
tiếp. Trộn cả hai vào một file dài làm session mới khó phục hồi nhanh và làm
|
|
118
|
+
instruction dễ drift theo tiến độ ngắn hạn [S1], [S2].
|
|
119
|
+
|
|
120
|
+
OpenAI còn đi xa hơn ở chỗ không chỉ lưu tri thức trong repo, mà còn tổ chức nó
|
|
121
|
+
theo progressive disclosure và kiểm tra freshness/cross-link bằng cơ chế cơ
|
|
122
|
+
học. Hệ quả là source of truth không nên chỉ "được viết xuống", mà còn nên có
|
|
123
|
+
cách để phát hiện doc cũ, liên kết hỏng, hoặc map điều hướng không còn phản ánh
|
|
124
|
+
thực tế của codebase [S1].
|
|
125
|
+
|
|
126
|
+
Anthropic còn cho thấy một điểm mạnh hơn: context reset không nhất thiết là
|
|
127
|
+
mất mát phải chịu đựng, mà có thể trở thành cơ chế chủ đích của harness. Khi
|
|
128
|
+
state handoff đủ tốt qua feature list, progress file, git log, và setup script,
|
|
129
|
+
session mới có thể khởi động lại với ngữ cảnh gọn hơn và ít bị context anxiety
|
|
130
|
+
hơn là cố kéo dài một chuỗi hội thoại suy giảm dần [S2], [S4].
|
|
131
|
+
|
|
132
|
+
### 4.3 Làm môi trường dễ đọc với agent
|
|
133
|
+
|
|
134
|
+
Agent chỉ sửa đáng tin những gì nó quan sát được. Anthropic cho thấy browser
|
|
135
|
+
automation giúp Claude kiểm thử feature web như người dùng thật và phát hiện lỗi
|
|
136
|
+
không thấy được từ code hoặc unit test đơn lẻ [S2]. OpenAI mở rộng ý tưởng này:
|
|
137
|
+
app, UI, log, metric, trace, và môi trường dev theo worktree phải trở thành tín
|
|
138
|
+
hiệu agent đọc được [S1].
|
|
139
|
+
|
|
140
|
+
Trong harness tốt, tool là giác quan của agent. Một web agent không có browser
|
|
141
|
+
automation không thật sự thấy app. Một backend agent không có log, metric, hoặc
|
|
142
|
+
trace khó suy luận về hành vi runtime. Một agent không biết setup app sẽ mất
|
|
143
|
+
thời gian đoán cách chạy trước khi làm việc thật [S1], [S2].
|
|
144
|
+
|
|
145
|
+
Anthropic cũng nhấn mạnh agent-computer interface. Tool nên có tên, tham số,
|
|
146
|
+
description, ví dụ, edge case, và ranh giới rõ. Tool khó dùng với con người mới
|
|
147
|
+
vào dự án thường cũng khó dùng với model [S3].
|
|
148
|
+
|
|
149
|
+
OpenAI bổ sung một hệ quả thiết kế ít hiển nhiên hơn: ngay cả lựa chọn
|
|
150
|
+
dependency và abstraction cũng là một phần của legibility. Công nghệ có API ổn
|
|
151
|
+
định, hành vi dễ mô hình hóa, và phần logic nằm trong repo thường dễ cho agent
|
|
152
|
+
reason hơn lớp upstream opaque. Vì vậy harness không chỉ thêm tool; nó còn có
|
|
153
|
+
thể ưu tiên stack và helper mà agent inspect, validate, và sửa trực tiếp được
|
|
154
|
+
[S1].
|
|
155
|
+
|
|
156
|
+
### 4.4 Tách sinh kết quả khỏi đánh giá
|
|
157
|
+
|
|
158
|
+
Một agent tự đánh giá output của chính nó thường quá tích cực, đặc biệt ở task
|
|
159
|
+
chủ quan như frontend design. Anthropic giải quyết bằng cách tách generator và
|
|
160
|
+
evaluator. Generator tạo sản phẩm; evaluator dùng tiêu chí chấm, Playwright, và
|
|
161
|
+
quan sát runtime để đưa phản hồi cụ thể; generator lặp lại dựa trên phản hồi đó
|
|
162
|
+
[S4].
|
|
163
|
+
|
|
164
|
+
Điểm cốt lõi là evaluator không cần hoàn hảo. Nó cần đủ hoài nghi và đủ cụ thể:
|
|
165
|
+
tiêu chí nào fail, bằng chứng quan sát là gì, user path nào lỗi, API hoặc state
|
|
166
|
+
nào chưa đúng, và sửa tiếp nên nhắm vào đâu [S4].
|
|
167
|
+
|
|
168
|
+
Google Cloud bổ sung khía cạnh **đánh giá vết thực thi (Trajectory Evaluation)**
|
|
169
|
+
và **LLM-as-a-judge** tự động. Việc đánh giá một agent dài hạn không chỉ đo lường
|
|
170
|
+
kết quả đầu ra tĩnh (static final evaluation) mà phải giám sát và chấm điểm toàn bộ
|
|
171
|
+
chuỗi hành động (gọi tool, suy luận) để phát hiện sai lệch hiệu năng sớm. Hơn nữa,
|
|
172
|
+
cơ chế **Meta-Evaluation (VeRO)** có thể được sử dụng để liên tục tối ưu hóa chính
|
|
173
|
+
cấu trúc của harness (prompt, tool) dựa trên vết chạy của session trước [S5].
|
|
174
|
+
|
|
175
|
+
### 4.5 Dùng sprint contract cho task dài
|
|
176
|
+
|
|
177
|
+
Với phát triển ứng dụng dài hạn, Anthropic dùng planner để mở rộng prompt ngắn
|
|
178
|
+
thành spec, generator để build, evaluator để QA, và sprint contract để hai bên
|
|
179
|
+
đồng thuận trước về scope và "done" [S4].
|
|
180
|
+
|
|
181
|
+
Sprint contract không phải thủ tục quản lý dự án. Nó là artifact điều khiển:
|
|
182
|
+
giới hạn phạm vi generator, làm rõ acceptance criteria, và cho evaluator tiêu
|
|
183
|
+
chuẩn chấm độc lập. Nếu task nhỏ, một acceptance contract hoặc test case là đủ.
|
|
184
|
+
Nếu task dài, contract nên nêu user path, API/data path, negative case, và cách
|
|
185
|
+
quan sát runtime [S3], [S4].
|
|
186
|
+
|
|
187
|
+
### 4.6 Cưỡng chế invariant bằng cơ chế kỹ thuật
|
|
188
|
+
|
|
189
|
+
OpenAI nhấn mạnh rằng documentation đơn thuần không giữ được coherence khi code
|
|
190
|
+
do agent sinh ra tăng nhanh. Họ mã hóa architecture rule, dependency direction,
|
|
191
|
+
data boundary parsing, structured logging, file size limit, naming convention,
|
|
192
|
+
và reliability rule bằng custom linter hoặc structural test [S1].
|
|
193
|
+
|
|
194
|
+
Nguyên tắc là: prompt nói điều nên làm; guardrail cơ học chặn điều không được
|
|
195
|
+
làm. Khi review comment hoặc bug lặp lại, harness tốt biến judgment đó thành
|
|
196
|
+
doc, lint, test, hoặc tool để agent tương lai không phải học lại từ đầu [S1].
|
|
197
|
+
|
|
198
|
+
Google DeepMind đóng góp giải pháp **AutoHarness** (tự động tổng hợp lớp bọc thực thi
|
|
199
|
+
bằng code). Thay vì con người phải tự viết thủ công tất cả luật linter hay guardrail,
|
|
200
|
+
mô hình có thể tự động phân tích và sinh ra lớp bọc (code harness/wrapper) để lọc/chặn
|
|
201
|
+
các hành động không hợp lệ trước khi chúng tác động tới môi trường [S5]. Cơ chế này
|
|
202
|
+
thậm chí có thể biên dịch toàn bộ chính sách quyết định thành code tĩnh
|
|
203
|
+
(**Harness-as-Policy**), giúp chạy trực tiếp mà không tốn chi phí và độ trễ gọi mô hình
|
|
204
|
+
ở runtime [S5].
|
|
205
|
+
|
|
206
|
+
### 4.7 Cleanup là một phần của harness
|
|
207
|
+
|
|
208
|
+
Throughput cao đổi failure mode từ "agent không viết được" sang "agent viết
|
|
209
|
+
nhiều và lan truyền pattern lệch". OpenAI mô tả recurring cleanup process,
|
|
210
|
+
quality grade, và targeted refactoring pull request như một dạng garbage
|
|
211
|
+
collection cho codebase agent-first [S1].
|
|
212
|
+
|
|
213
|
+
Cleanup không phải refactor tùy hứng. Nó nên là task có trigger, phạm vi, tiêu
|
|
214
|
+
chí nghiệm thu, và verification giống mọi thay đổi khác.
|
|
215
|
+
|
|
216
|
+
## 5. Lợi ích
|
|
217
|
+
|
|
218
|
+
### 5.1 Tiến triển dài hạn tốt hơn
|
|
219
|
+
|
|
220
|
+
Externalized state giúp session mới không phải đoán dự án đang ở đâu. Feature
|
|
221
|
+
list, progress file, git history, và `init.sh` giảm thời gian khởi động và giúp
|
|
222
|
+
agent chọn phần việc kế tiếp có phạm vi rõ [S2].
|
|
223
|
+
|
|
224
|
+
### 5.2 QA tốt hơn
|
|
225
|
+
|
|
226
|
+
Browser automation, test runtime, API check, log, metric, và trace giúp agent
|
|
227
|
+
kiểm chứng hành vi thay vì chỉ đọc code. Evaluator riêng có thể bắt gap mà
|
|
228
|
+
generator bỏ sót, như feature display-only, interaction thiếu chiều sâu, hoặc
|
|
229
|
+
stub chưa được thay bằng hành vi thật [S1], [S2], [S4].
|
|
230
|
+
|
|
231
|
+
Đánh giá vết thực thi (trajectory evaluation) và LLM-as-a-judge tự động giúp giám
|
|
232
|
+
sát độ an toàn và hiệu năng của agent liên tục, phát hiện lỗi suy luận hoặc lỗi
|
|
233
|
+
gọi công cụ một cách có hệ thống trước khi tích hợp [S5].
|
|
234
|
+
|
|
235
|
+
### 5.3 Judgment của con người tích lũy
|
|
236
|
+
|
|
237
|
+
Khi preference, review comment, architecture rule, và bug pattern được mã hóa
|
|
238
|
+
vào docs, lint, test, hoặc cleanup, chúng ảnh hưởng tới nhiều lần chạy agent sau
|
|
239
|
+
đó. Harness biến một lần can thiệp của con người thành ràng buộc lặp lại [S1].
|
|
240
|
+
|
|
241
|
+
### 5.4 Tốc độ cao hơn nếu môi trường đủ chín
|
|
242
|
+
|
|
243
|
+
OpenAI báo cáo case study nội bộ với throughput PR cao và codebase lớn do Codex
|
|
244
|
+
sinh ra, nhưng họ cũng cảnh báo mức tự chủ đó phụ thuộc mạnh vào cấu trúc và
|
|
245
|
+
tooling cụ thể của repository [S1]. Vì vậy lợi ích không nên được đọc như lời
|
|
246
|
+
hứa phổ quát; nó là kết quả của đầu tư vào harness.
|
|
247
|
+
|
|
248
|
+
## 6. Chi phí và giới hạn
|
|
249
|
+
|
|
250
|
+
### 6.1 Complexity có giá
|
|
251
|
+
|
|
252
|
+
Harness nhiều agent, nhiều vòng evaluator, và nhiều QA runtime có thể tốn nhiều
|
|
253
|
+
giờ và token. Anthropic nêu các run ứng dụng dài hạn kéo dài hàng giờ với chi
|
|
254
|
+
phí đáng kể. Vì vậy harness phức tạp phải được dùng như tradeoff có chủ đích,
|
|
255
|
+
không phải mặc định [S4].
|
|
256
|
+
|
|
257
|
+
### 6.2 Model capability thay đổi thiết kế harness
|
|
258
|
+
|
|
259
|
+
Một lớp orchestration hữu ích với model hiện tại có thể không còn cần thiết khi
|
|
260
|
+
model mới tốt hơn. Anthropic khuyến nghị re-examine harness khi model thay đổi:
|
|
261
|
+
loại bỏ phần không còn load-bearing và thêm phần mới nếu model mở ra khả năng
|
|
262
|
+
khác [S4].
|
|
263
|
+
|
|
264
|
+
### 6.3 Evaluator vẫn có giới hạn
|
|
265
|
+
|
|
266
|
+
Evaluator là LLM nên vẫn có thể bỏ sót bug hoặc đánh giá sai, nhất là ở domain
|
|
267
|
+
mà nó thiếu giác quan trực tiếp. Anthropic nêu ví dụ âm thanh: QA về musical
|
|
268
|
+
taste bị giới hạn nếu model không thực sự nghe được output [S4].
|
|
269
|
+
|
|
270
|
+
### 6.4 Kết quả không tự động tổng quát hóa
|
|
271
|
+
|
|
272
|
+
OpenAI nói rõ khả năng Codex drive feature end-to-end phụ thuộc mạnh vào cấu
|
|
273
|
+
trúc và tooling của repository. Đội khác không nên kỳ vọng outcome tương tự nếu
|
|
274
|
+
chưa có source of truth cục bộ, setup lặp lại, tool quan sát, test, lint, review
|
|
275
|
+
loop, và cleanup [S1].
|
|
276
|
+
|
|
277
|
+
## 7. Mô hình tổng hợp
|
|
278
|
+
|
|
279
|
+
Một harness trưởng thành có thể được đọc như hệ điều khiển gồm bốn lớp:
|
|
280
|
+
|
|
281
|
+
| Lớp | Câu hỏi | Artifact điển hình | Nguồn |
|
|
282
|
+
| --- | --- | --- | --- |
|
|
283
|
+
| State | Agent biết việc đã xảy ra chưa? | feature list, progress log, git history | [S2] |
|
|
284
|
+
| Senses | Agent thấy hành vi thật chưa? | browser, API check, log, metric, trace, trajectory evaluator | [S1], [S2], [S4], [S5] |
|
|
285
|
+
| Standards | Done nghĩa là gì? | acceptance criteria, sprint contract, evaluator rubric, LLM-as-a-judge | [S3], [S4], [S5] |
|
|
286
|
+
| Constraints | Điều gì không được drift? | lint, structural test, CI, cleanup, synthesized code harness | [S1], [S5] |
|
|
287
|
+
|
|
288
|
+
Thứ tự triển khai nên đi từ rẻ đến đắt: state trước, verification trước, tool
|
|
289
|
+
quan sát khi cần, evaluator khi self-review yếu, planner khi scope mơ hồ, và
|
|
290
|
+
guardrail khi invariant đã rõ.
|
|
291
|
+
|
|
292
|
+
## 8. Câu hỏi mở
|
|
293
|
+
|
|
294
|
+
Năm nguồn để lại một số câu hỏi nghiên cứu:
|
|
295
|
+
|
|
296
|
+
- Khi nào một agent tổng quát tốt hơn nhiều agent chuyên biệt? [S2], [S4]
|
|
297
|
+
- Khi nào evaluator đáng chi phí so với self-review hoặc test deterministic?
|
|
298
|
+
[S3], [S4]
|
|
299
|
+
- Làm sao đo được phần cải thiện đến từ model, prompt, tool, state, evaluator,
|
|
300
|
+
hay guardrail? [S3], [S4]
|
|
301
|
+
- Architecture coherence của codebase agent-generated sẽ tiến hóa thế nào qua
|
|
302
|
+
nhiều năm? [S1]
|
|
303
|
+
- Những phần harness nào nên bị loại bỏ khi model mới mạnh hơn? [S4]
|
|
304
|
+
- Khi nào nên dùng AutoHarness tự động sinh thay vì viết linter/guardrail thủ công? [S5]
|
|
305
|
+
- Làm thế nào để giảm thiểu sai số của LLM-as-a-judge trong trajectory evaluation? [S5]
|
|
306
|
+
|
|
307
|
+
## 9. Kết luận
|
|
308
|
+
|
|
309
|
+
Harness engineering làm autonomy trở thành thuộc tính của hệ thống, không chỉ
|
|
310
|
+
là thuộc tính của model. Một model mạnh trong môi trường thiếu state, thiếu
|
|
311
|
+
tool, thiếu tiêu chí done, và thiếu guardrail sẽ tạo tiến triển giòn. Cùng model
|
|
312
|
+
đó trong harness tốt có thể tiếp tục công việc, quan sát lỗi, nhận feedback,
|
|
313
|
+
sửa có bằng chứng, và giữ kiến trúc ổn định hơn.
|
|
314
|
+
|
|
315
|
+
Kết luận thực dụng từ các nghiên cứu là: đừng bắt đầu bằng harness phức tạp. Bắt
|
|
316
|
+
đầu bằng task rõ, state bền vững, setup lặp lại, và verify thật. Chỉ thêm evaluator,
|
|
317
|
+
planner, observability, hoặc cleanup automation khi failure mode cụ thể cho
|
|
318
|
+
thấy chúng đang mua thêm chất lượng đáng giá.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Nguồn
|
|
2
|
+
|
|
3
|
+
File này chỉ theo dõi bốn nguồn được phép dùng trong bản nghiên cứu hiện tại.
|
|
4
|
+
Không thêm claim vào tài liệu nếu claim đó không ánh xạ tới một trong bốn nguồn
|
|
5
|
+
này hoặc không được đánh dấu rõ là diễn giải.
|
|
6
|
+
|
|
7
|
+
## Danh mục nguồn
|
|
8
|
+
|
|
9
|
+
### [S1] OpenAI
|
|
10
|
+
|
|
11
|
+
- Tiêu đề: "Harness engineering: leveraging Codex in an agent-first world"
|
|
12
|
+
- Tác giả: Ryan Lopopolo
|
|
13
|
+
- Ngày xuất bản: 11 tháng 2, 2026
|
|
14
|
+
- URL: https://openai.com/index/harness-engineering/
|
|
15
|
+
- Dùng cho:
|
|
16
|
+
- framing "humans steer, agents execute";
|
|
17
|
+
- harness engineering như thiết kế environment, intent specification, và
|
|
18
|
+
feedback loop quanh Codex;
|
|
19
|
+
- repository knowledge base như system of record;
|
|
20
|
+
- `AGENTS.md` như bản đồ, không phải cẩm nang khổng lồ;
|
|
21
|
+
- ưu tiên dependency, abstraction, và thông tin mà agent có thể inspect,
|
|
22
|
+
validate, và modify trực tiếp trong repo;
|
|
23
|
+
- application, browser, log, metric, và trace như tín hiệu agent đọc được;
|
|
24
|
+
- progressive disclosure cho tri thức trong repo và kiểm tra cơ học về
|
|
25
|
+
freshness/cross-link để giảm drift của tài liệu;
|
|
26
|
+
- cưỡng chế architecture và taste bằng lint, structural test, và custom rule;
|
|
27
|
+
- throughput, merge philosophy, autonomy, entropy, và cleanup định kỳ;
|
|
28
|
+
- cảnh báo rằng mức tự chủ phụ thuộc vào cấu trúc và tooling cụ thể của repo.
|
|
29
|
+
|
|
30
|
+
### [S2] Anthropic
|
|
31
|
+
|
|
32
|
+
- Tiêu đề: "Effective harnesses for long-running agents"
|
|
33
|
+
- Tác giả: Justin Young
|
|
34
|
+
- Ngày xuất bản: 26 tháng 11, 2025
|
|
35
|
+
- URL: https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents
|
|
36
|
+
- Dùng cho:
|
|
37
|
+
- failure mode của agent qua nhiều context window;
|
|
38
|
+
- initializer agent và coding agent;
|
|
39
|
+
- feature list dạng JSON với trạng thái pass/fail;
|
|
40
|
+
- tiến triển từng feature thay vì làm quá rộng;
|
|
41
|
+
- progress file, git commit, và `init.sh`;
|
|
42
|
+
- kiểm thử đầu-cuối bằng browser automation;
|
|
43
|
+
- vòng bắt đầu session: đọc progress, feature list, git log, setup, smoke test.
|
|
44
|
+
|
|
45
|
+
### [S3] Anthropic
|
|
46
|
+
|
|
47
|
+
- Tiêu đề: "Building effective agents"
|
|
48
|
+
- Tác giả: Erik Schluntz và Barry Zhang
|
|
49
|
+
- Ngày xuất bản: 19 tháng 12, 2024
|
|
50
|
+
- URL: https://www.anthropic.com/engineering/building-effective-agents
|
|
51
|
+
- Dùng cho:
|
|
52
|
+
- phân biệt workflow định tuyến sẵn và agent tự điều khiển process/tool;
|
|
53
|
+
- nguyên tắc bắt đầu bằng giải pháp đơn giản nhất;
|
|
54
|
+
- tradeoff giữa performance, latency, cost, và complexity;
|
|
55
|
+
- building block "augmented LLM" với retrieval, tool, và memory;
|
|
56
|
+
- workflow pattern như prompt chaining, routing, parallelization,
|
|
57
|
+
orchestrator-workers, evaluator-optimizer;
|
|
58
|
+
- thiết kế agent-computer interface và tool definition dễ dùng.
|
|
59
|
+
|
|
60
|
+
### [S4] Anthropic
|
|
61
|
+
|
|
62
|
+
- Tiêu đề: "Harness design for long-running application development"
|
|
63
|
+
- Tác giả: Prithvi Rajasekaran
|
|
64
|
+
- Ngày xuất bản: 24 tháng 3, 2026
|
|
65
|
+
- URL: https://www.anthropic.com/engineering/harness-design-long-running-apps
|
|
66
|
+
- Dùng cho:
|
|
67
|
+
- vấn đề context anxiety và self-evaluation;
|
|
68
|
+
- tách generator khỏi evaluator;
|
|
69
|
+
- grading criteria để làm chất lượng chủ quan dễ chấm hơn;
|
|
70
|
+
- planner-generator-evaluator cho phát triển ứng dụng dài hạn;
|
|
71
|
+
- sprint contract giữa generator và evaluator;
|
|
72
|
+
- QA bằng Playwright qua UI, API, database state, và hành vi runtime;
|
|
73
|
+
- chi phí, độ trễ, và token cost của harness phức tạp;
|
|
74
|
+
- nguyên tắc xem lại harness khi model mới làm một số lớp orchestration không
|
|
75
|
+
còn load-bearing.
|
|
76
|
+
|
|
77
|
+
### [S5] Google
|
|
78
|
+
|
|
79
|
+
- Tiêu đề: "AutoHarness: Improving LLM Agents by Automatically Synthesizing a Code Harness" (Google DeepMind) và thực tiễn vận hành Agent/Evaluation Harness trên Google Cloud.
|
|
80
|
+
- Tác giả: Google DeepMind & Google Cloud
|
|
81
|
+
- Ngày xuất bản: 2024-2026
|
|
82
|
+
- URL: https://arxiv.org/abs/2406.11252
|
|
83
|
+
- Dùng cho:
|
|
84
|
+
- AutoHarness: Tự động tổng hợp lớp bọc thực thi (code harness/wrapper) bằng LLM để chặn hành động lỗi và cưỡng chế ràng buộc;
|
|
85
|
+
- Harness-as-Policy: Biên dịch chính sách quyết định thành code tĩnh để giảm chi phí/độ trễ runtime về 0;
|
|
86
|
+
- Trajectory Evaluation: Đánh giá vết chạy đầy đủ (gồm tool call, suy luận) thay vì chỉ chấm điểm kết quả tĩnh;
|
|
87
|
+
- LLM-as-a-Judge tự động & Meta-Evaluation (VeRO) để liên tục tối ưu cấu trúc của agent.
|
|
88
|
+
|
|
89
|
+
## Bản đồ bằng chứng
|
|
90
|
+
|
|
91
|
+
| Nhận định | Nguồn |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
| Harness engineering chuyển trọng tâm kỹ sư từ viết code tay sang thiết kế môi trường, intent, và feedback loop. | [S1] |
|
|
94
|
+
| Repository-local knowledge giúp agent truy cập quyết định, quy tắc, và trạng thái mà không phụ thuộc chat history. | [S1] |
|
|
95
|
+
| `AGENTS.md` nên là bản đồ ngắn trỏ tới nguồn sự thật sâu hơn, không phải một manual khổng lồ. | [S1] |
|
|
96
|
+
| Chọn dependency và abstraction nên tính đến việc agent có thể inspect, validate, và modify chúng trực tiếp; hành vi opaque ở upstream làm giảm leverage. | [S1] |
|
|
97
|
+
| Agent cần application legibility: UI, log, metric, trace, và môi trường dev có thể quan sát được. | [S1] |
|
|
98
|
+
| Repository knowledge nên theo progressive disclosure và có kiểm tra cơ học cho freshness/cross-link; doc-gardening định kỳ giúp giảm drift của source of truth. | [S1] |
|
|
99
|
+
| Documentation đơn thuần không đủ; architecture và taste nên được cưỡng chế bằng lint, structural test, và custom rule. | [S1] |
|
|
100
|
+
| Throughput cao làm entropy tích lũy nhanh, nên cleanup định kỳ là một phần của harness. | [S1] |
|
|
101
|
+
| Agent dài hạn dễ mất context giữa các session và cần externalized state. | [S2] |
|
|
102
|
+
| Feature list, progress file, git history, và `init.sh` giúp session mới phục hồi trạng thái. | [S2] |
|
|
103
|
+
| Feature list dạng JSON giúp agent giữ trạng thái feature có cấu trúc và cập nhật pass/fail nhất quán qua nhiều session. | [S2] |
|
|
104
|
+
| Git commit mô tả rõ và progress update không chỉ để audit; chúng còn tạo checkpoint để agent revert thay đổi xấu và khôi phục working state sạch hơn. | [S2] |
|
|
105
|
+
| Làm từng feature và chỉ đánh dấu pass sau kiểm thử giúp giảm tuyên bố hoàn thành sớm. | [S2] |
|
|
106
|
+
| Browser automation giúp agent phát hiện lỗi không thấy được từ code hoặc unit test đơn lẻ. | [S2] |
|
|
107
|
+
| Agentic system nên bắt đầu bằng giải pháp đơn giản nhất và chỉ tăng complexity khi cần. | [S3] |
|
|
108
|
+
| Workflow phù hợp với task có đường đi định sẵn; agent phù hợp khi cần model tự quyết định tool/process. | [S3] |
|
|
109
|
+
| Tool nên được thiết kế như agent-computer interface với mô tả, tham số, ranh giới, và ví dụ rõ. | [S3] |
|
|
110
|
+
| Generator tự đánh giá thường quá tích cực; evaluator riêng dễ được chỉnh thành hoài nghi hơn. | [S4] |
|
|
111
|
+
| Sprint contract giúp generator và evaluator đồng thuận về phạm vi, tiêu chí done, và phương thức QA. | [S4] |
|
|
112
|
+
| Context reset có thể là một phần chủ đích của harness; nếu state handoff đủ tốt, reset giúp giữ model bám task thay vì trượt theo context anxiety. | [S4] |
|
|
113
|
+
| Harness phức tạp có thể tốn nhiều giờ và token, nên phải được xem là tradeoff thay vì mặc định. | [S4] |
|
|
114
|
+
| Khi model mới xuất hiện, nên xem lại và loại bỏ các phần harness không còn tạo giá trị. | [S4] |
|
|
115
|
+
| Thay vì tự viết thủ công mọi ràng buộc, mô hình (như Gemini Flash) có thể tự động tổng hợp lớp bọc thực thi (AutoHarness) bằng code để lọc các hành động lỗi. | [S5] |
|
|
116
|
+
| Biên dịch chính sách quyết định thành code tĩnh (Harness-as-Policy) giúp loại bỏ việc gọi mô hình ở runtime, tối ưu hóa chi phí và độ trễ. | [S5] |
|
|
117
|
+
| Đánh giá agent dài hạn cần dựa trên vết chạy đầy đủ (Trajectory Evaluation) bao gồm cả chuỗi gọi tool và suy luận, thay vì chỉ so sánh kết quả đầu ra tĩnh. | [S5] |
|
|
118
|
+
| LLM-as-a-Judge tự động giúp đo lường độ an toàn và hiệu năng của agent liên tục, và Meta-Evaluation (VeRO) tối ưu hóa cấu trúc của harness dựa trên phản hồi. | [S5] |
|
|
119
|
+
|
|
120
|
+
## Chính sách citation
|
|
121
|
+
|
|
122
|
+
- Chỉ dùng mã `[S1]`, `[S2]`, `[S3]`, `[S4]`, `[S5]`.
|
|
123
|
+
- Không thêm citation, paper, DOI, benchmark, hoặc blog ngoài phạm vi nếu chưa
|
|
124
|
+
được yêu cầu.
|
|
125
|
+
- Nếu mở rộng phạm vi sau này, phải cập nhật file này trước rồi mới cập nhật
|
|
126
|
+
`research-note.md` hoặc `implementation-playbook.md`.
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codex-harness-engineering",
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "Codex harness engineering docs and installable agent skills.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"codex",
|
|
7
|
+
"harness-engineering",
|
|
8
|
+
"agent-skills",
|
|
9
|
+
"ai-agents",
|
|
10
|
+
"long-running-agents"
|
|
11
|
+
],
|
|
12
|
+
"type": "module",
|
|
13
|
+
"bin": {
|
|
14
|
+
"codex-harness-engineering": "scripts/install-skills.mjs",
|
|
15
|
+
"codex-harness-install-skills": "scripts/install-skills.mjs"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"AGENTS.md",
|
|
19
|
+
"README.md",
|
|
20
|
+
"docs",
|
|
21
|
+
"scripts",
|
|
22
|
+
"skills"
|
|
23
|
+
],
|
|
24
|
+
"scripts": {
|
|
25
|
+
"test": "node --test tests/*.test.mjs",
|
|
26
|
+
"verify": "node scripts/verify-harness.mjs && npm test",
|
|
27
|
+
"pack:dry": "npm pack --dry-run",
|
|
28
|
+
"release": "./scripts/publish.sh",
|
|
29
|
+
"prepublishOnly": "npm test"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18.17"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"license": "UNLICENSED"
|
|
38
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { realpathSync } from "node:fs";
|
|
4
|
+
import { access, cp, mkdir, rm } from "node:fs/promises";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const PACKAGE_ROOT = path.resolve(__dirname, "..");
|
|
10
|
+
|
|
11
|
+
export const SKILL_NAMES = [
|
|
12
|
+
"acceptance-contract",
|
|
13
|
+
"cleanup-harness",
|
|
14
|
+
"creator-harness",
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
async function exists(filePath) {
|
|
18
|
+
try {
|
|
19
|
+
await access(filePath);
|
|
20
|
+
return true;
|
|
21
|
+
} catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function assertCanWrite(target, force) {
|
|
27
|
+
if (!force && await exists(target)) {
|
|
28
|
+
throw new Error(`${target} already exists. Re-run with --force to overwrite it.`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function installSkills({
|
|
33
|
+
packageRoot = PACKAGE_ROOT,
|
|
34
|
+
projectRoot = process.cwd(),
|
|
35
|
+
force = false,
|
|
36
|
+
} = {}) {
|
|
37
|
+
const sourceRoot = path.join(packageRoot, "skills");
|
|
38
|
+
const targetRoot = path.join(projectRoot, ".agents", "skills");
|
|
39
|
+
const docsSource = path.join(packageRoot, "docs", "harness-engineering");
|
|
40
|
+
const docsTarget = path.join(projectRoot, "docs", "harness-engineering");
|
|
41
|
+
const installed = [];
|
|
42
|
+
|
|
43
|
+
await mkdir(targetRoot, { recursive: true });
|
|
44
|
+
|
|
45
|
+
for (const skillName of SKILL_NAMES) {
|
|
46
|
+
const source = path.join(sourceRoot, skillName);
|
|
47
|
+
const target = path.join(targetRoot, skillName);
|
|
48
|
+
|
|
49
|
+
if (path.resolve(source) !== path.resolve(target)) {
|
|
50
|
+
await assertCanWrite(target, force);
|
|
51
|
+
await rm(target, { recursive: true, force: true });
|
|
52
|
+
await cp(source, target, { recursive: true, force: true });
|
|
53
|
+
}
|
|
54
|
+
installed.push(skillName);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (path.resolve(docsSource) !== path.resolve(docsTarget)) {
|
|
58
|
+
await assertCanWrite(docsTarget, force);
|
|
59
|
+
await rm(docsTarget, { recursive: true, force: true });
|
|
60
|
+
await cp(docsSource, docsTarget, { recursive: true, force: true });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return { targetRoot, docsTarget, installed };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function parseArgs(args) {
|
|
67
|
+
const [command, ...flags] = args;
|
|
68
|
+
|
|
69
|
+
if (command !== "init") {
|
|
70
|
+
throw new Error("Usage: codex-harness-engineering init [--force]");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const unknownFlag = flags.find((flag) => flag !== "--force");
|
|
74
|
+
if (unknownFlag) {
|
|
75
|
+
throw new Error(`Unknown option: ${unknownFlag}`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return { command, force: flags.includes("--force") };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function isDirectRun() {
|
|
82
|
+
if (!process.argv[1]) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return pathToFileURL(realpathSync(process.argv[1])).href ===
|
|
87
|
+
pathToFileURL(realpathSync(fileURLToPath(import.meta.url))).href;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (isDirectRun()) {
|
|
91
|
+
try {
|
|
92
|
+
const { force } = parseArgs(process.argv.slice(2));
|
|
93
|
+
const { targetRoot, docsTarget, installed } = await installSkills({ force });
|
|
94
|
+
|
|
95
|
+
console.log(`Installed ${installed.length} skills to ${targetRoot}`);
|
|
96
|
+
for (const skillName of installed) {
|
|
97
|
+
console.log(`- ${skillName}`);
|
|
98
|
+
}
|
|
99
|
+
console.log(`Copied docs to ${docsTarget}`);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error(error instanceof Error ? error.message : error);
|
|
102
|
+
process.exitCode = 1;
|
|
103
|
+
}
|
|
104
|
+
}
|