如何编写 AI 智能体真正能够验证的验收标准
别再让每次 AI 编程会话都以“差不多,但还不够”收场——学会编写能在你审查 diff 之前就由 AI 智能体自行核对的验收标准。
Most AI coding sessions follow the same pattern. You describe what you want, the model produces something, you review it, and you say “close, but not quite” — then the loop repeats two, three, sometimes five times before the output matches what you imagined. The cost is measured in tokens, time, and frustration, but the root cause is nearly always the same: your acceptance criteria were not specific enough for the model to verify against its own output.
Acceptance criteria in human-led projects serve as the shared definition of “done” between the requester and the developer. In AI-assisted coding, they serve the same purpose, but the developer is a language model that reads every word literally. If your criterion says “make it look nice”, the model must guess what “nice” means. If it says “the form button should be blue, not disabled when all required fields are non-empty, and show a spinner on click for up to three seconds”, the model can check all three conditions before sending the code.
What makes a criterion verifiable?
A verifiable acceptance criterion has three properties: it is observable, unambiguous, and binary.
Observable means a human — or a model inspecting its own output — can determine whether the condition is met by looking at the result. “The button turns green when clicked” is observable. “The button looks good” is not.
Unambiguous means no room for interpretation. “The error message appears below the input field, left-aligned, in red 14px text” is unambiguous. “Handle errors gracefully” is not.
Binary means it passes or fails with no grey area. “The API returns a 200 response within 500ms” is binary. “The API performs well” is not.
When all three are present, the model can run a mental checklist against its own output before presenting it to you. If a criterion fails, the model knows it failed and can adjust. This is the difference between a model that guesses and a model that verifies.
Vague versus verifiable — side by side
| Vague criterion | Verifiable criterion | How the model checks it |
|---|---|---|
| ”Make it responsive" | "Layout collapses to a single column below 768px; navigation becomes a hamburger menu; font size scales down proportionally” | Inspect at breakpoint |
| ”Add validation" | "Email field rejects input without ’@’; submit disabled until all required fields are non-empty; inline error message in red below failing field” | Test each condition |
| ”Improve performance" | "Lighthouse Performance score ≥ 90 on mobile; LCP under 2.5s” | Run Lighthouse |
| ”Clean up the code" | "No unused imports; every function has a return type annotation; file is under 200 lines” | Static analysis |
| ”Make it secure" | "All user input sanitised with DOMPurify before rendering; API keys in environment variables, not source” | Inspect output |
Each verifiable criterion describes an outcome the model can check before it sends you the result. You are not writing unit tests — you are writing guardrails that steer the first attempt closer to what you actually want.
Writing criteria inside a prompt
The most effective place for acceptance criteria is at the end of the prompt, after you have described the task and the stack. This keeps the criteria separate from the instruction so the model treats them as a checklist rather than part of the specification.
Build a contact form component in React that collects name, email, and
message. Use React Hook Form for validation and Tailwind for styling.
Acceptance criteria:
- The email field rejects input without an '@' symbol and shows
"Please enter a valid email" below the field in red 14px text
- The submit button is disabled while the form is submitting and
displays a spinner
- On success, the form clears and a green banner says "Message sent!"
above the form
- On network failure, the form keeps the user's input and shows a red
"Could not send. Try again." banner
- The component exports as a default export from
`components/ContactForm.tsx`
The model can check each criterion against the component it writes. If the spinner is missing, it knows to add one. If the error banner uses the wrong colour, it fixes it. The first pass lands closer to shippable because the model was not guessing what “done” meant.
This approach maps directly to the patterns covered in Harness Engineering, which goes deeper into how to structure verifiable prompts at scale across large codebases.
Including edge cases
Models are optimised to produce plausible output, not to anticipate every edge case. If you do not mention empty states, error states, or loading states, the model will often skip them. A single additional group in your criteria fixes this:
Edge cases:
- Show an empty state with "No results found" when the data array is empty
- Handle a null or undefined user object without crashing
- Display a skeleton loader while data is fetching
Edge-case criteria have an outsized impact on quality because models default to the happy path. A prompt that explicitly asks for error handling, empty states, and loading indicators will produce a component that works in production — not just in a demo.
A reusable criteria template
Bookmark this format for your next session. It works across ChatGPT, Claude, Cursor, GitHub Copilot, and any other agent-based coding tool.
Task: [one-sentence description of what to build]
Stack: [language, framework, libraries, version constraints]
Acceptance criteria:
- [observable, unambiguous, binary condition 1]
- [observable, unambiguous, binary condition 2]
- [observable, unambiguous, binary condition 3]
Edge cases:
- [empty state]
- [error state]
- [loading state]
Out of scope:
- [features not to implement]
The “out of scope” line is surprisingly important. Without it, models sometimes add speculative features — authentication, pagination, dark mode — that you never asked for. Listing what not to build saves you from reviewing code you will delete.
For a deeper treatment of this template across an entire project lifecycle, see Agentic Coding Pro, which covers verification-driven development with AI agents from architecture through deployment.
Matching criteria to task size
For a single component, five criteria are enough. For a full-page layout, ten to twelve might be right. For an entire project brief, group criteria by feature area and keep each group under ten. The goal is not to write a test suite — it is to remove the ambiguity that causes rewrites.
The Google AI prompt engineering strategies guide recommends similar thinking: break complex tasks into smaller subtasks and define success for each one. Acceptance criteria are how you apply that strategy at the level of individual prompts.
Measure the difference
Next time you open a chat, try the criteria-first approach. Write your prompt, add a list of verifiable acceptance criteria, and compare the first output against what you would have received with a vague instruction. You will probably need one follow-up instead of five.
That saved time compounds across a project. Each session that lands closer to the target on the first pass means fewer hours reviewing, correcting, and re-prompting. Over the course of a week, verifiable acceptance criteria can halve the number of rounds between “build this” and “ship this.”
更多文章
全部文章Vibe Coding 新手必读:读懂 AI 所写 JavaScript 的最低要求
学会刚好够用的 JavaScript,去读懂 AI 生成的前端代码——包括变量、函数、DOM 基础,以及提示你应当重新提问的危险信号。
阅读全文