AI Series Interview 16: What Makes a Good Spec Coding?
A good Spec Coding (specification-driven programming) is about turning "vague ideas" into "precise, verifiable, and executable contracts." It's not just writing a document, but establishing a set of unambiguous communication languages between humans and AI (or between humans). Below, I will elaborate on what a good spec looks like from four dimensions: content structure of the specification, writing principles, collaboration process with AI, and quality verification.
1. Standard Structure of a Specification Document (Using a Feature Module as an Example)
| Section | Required Content | Example |
|---|---|---|
| 1. Goal and Scope | One sentence describing what to do, explicitly stating what not to do | "Implement user registration API, excluding email verification" |
| 2. Input/Output Contract | Data structure, types, required/optional fields, example values | POST /register request body {email: string, password: string}, response 201 or 400 with error code |
| 3. Behavior and Logic | Business rules, boundary conditions, state transitions | "Password length 8-20 characters, at least one digit; return 409 if email already exists" |
| 4. Error Handling | All possible exception scenarios and corresponding error codes/messages | "Database connection failure → return 503, do not expose stack trace" |
| 5. Non-functional Requirements | Performance (response time < 200ms), security (parameterized queries), logging, observability | "All SQL must use prepared statements; log email but not password" |
| 6. Test Cases (Critical) | At least 3 typical inputs + 2 boundary/abnormal inputs, with expected outputs | See table below |
| 7. Dependencies and Constraints | Libraries used, versions, environment variables | "Python 3.10+, FastAPI, environment variable DB_URL" |
Example Test Cases (Embedded in Spec)
| Scenario | Input | Expected Output |
|---|---|---|
| Normal registration | email: a@b.com, pwd: Pass1234 |
201, returns user_id |
| Password too short | pwd: Ab1 |
400, error code WEAK_PASSWORD |
| Email already exists | same email as above | 409, error code EMAIL_EXISTS |
A good spec should write test cases first, because AI can directly generate unit tests from them and automatically verify after completion.
2. Core Principles for Writing Specs (SMART Variant)
| Principle | Explanation | Counterexample |
|---|---|---|
| Precise | Use specific numbers, types, boolean conditions; avoid "as much as possible," "usually" | ❌ "Password must be secure enough" → ✅ "Password at least 8 characters, containing uppercase, lowercase, and digit" |
| Verifiable | Each requirement can be judged pass/fail through automated tests or manual inspection | ❌ "Code should be elegant" → ✅ "Function cyclomatic complexity ≤ 10, no duplicated code blocks" |
| Unambiguous | Same term has consistent meaning throughout the document; provide a glossary if necessary | ❌ "If user does not exist, return error" → ✅ "User does not exist → return 404 with {code: 'USER_NOT_FOUND'}" |
| Complete | Cover happy path, all exception paths, and non-functional requirements | ❌ Only writes success scenarios → ✅ Includes database timeout, insufficient permissions, etc. |
| Atomic | One spec describes only one independently deliverable feature point (so AI can finish it at once) | ❌ Write a single spec for "the entire payment system" → ✅ Split into "generate payment order," "callback signature verification," "refund" |
3. Spec Coding Workflow When Collaborating with AI
- Human writes the spec (the structure above, especially test cases and function signatures).
- Feed the entire spec to AI at once (do not add requirements through conversational interactions to avoid vibe contamination).
- AI outputs code + unit tests (AI must generate executable tests based on the test cases in the spec).
- Run tests: If all pass, proceed to next step; if not, modify the spec or directly fix the code (a small loop can be started, but changes must be recorded).
- Human review: Check for scope creep introduced beyond the spec, verify security/performance.
- Freeze: Commit the spec document and final code to the repository as permanent documentation.
Key practice: Code the spec — use
spec.md+test_spec.py, where the test file comes directly from the examples in the spec. This way, when code is modified later, simply running the tests can verify whether the spec is broken.
4. Effects of a Good Spec (Can Serve as Acceptance Criteria)
- Determinism: The same spec given to different AIs (or different people) yields similar implementations.
- Testability: Immediately after writing code, 90% correctness can be automatically verified.
- Maintainability: Six months later, anyone reading the spec can understand the original design intent.
- Low communication cost: Team discussions only talk about the spec, not specific lines of code.
- Built-in safety/quality: Security requirements (e.g., parameterized queries) and boundary conditions are written in the spec, and AI must comply.
5. Example of a Good Spec (Minimalist)
# Spec: User Registration API
## Scope
- Accept email, password
- Do not send verification email, do not check email authenticity
## Contract
POST /register
Content-Type: application/json
Request: { "email": string, "password": string }
Response 201: { "user_id": string }
Response 400: { "code": "INVALID_PASSWORD" | "INVALID_EMAIL" }
Response 409: { "code": "EMAIL_ALREADY_EXISTS" }
## Behavior
- Email must conform to basic RFC 5322 format (a@b.c)
- Password: length 8-20, at least one digit and one uppercase letter
- Use bcrypt with salt cost 10 for storage
- If email is found to exist before database insertion → 409
## Test Cases (Input -> Expected Status Code + Response Fields)
| Input email | password | Expected |
|-------------|----------|----------|
| test@x.com | Pass1234 | 201, user_id exists |
| test@x.com | pass | 400, INVALID_PASSWORD |
| bad | Pass1234 | 400, INVALID_EMAIL |
| (existing email) | Pass1234 | 409, EMAIL_ALREADY_EXISTS |
## Non-functional
- All SQL must use parameterized queries (prevent injection)
- Log registration source IP, do not log password
- Response time 95% of requests < 100ms (excluding bcrypt)
## Dependencies
- Python 3.10+, FastAPI, bcrypt, asyncpg
Good Spec Coding = turning human "design decisions" into machine "test cases + type signatures + behavior constraints", so that AI is only responsible for filling in the implementation, while humans always control quality and direction.
评论
暂无已展示的评论。
发表评论(匿名)