Chuyển đến nội dung chính

Lesson 8: The art of writing Prompt for Code — From vague to precise

Anatomy of a good code prompt: context, constraints, examples. Prompting patterns: zero-shot, few-shot, chain-of-thought for code. How to describe requirements clearly. Iterative prompting. Common mistakes and how to fix them.

💻 Programming — Lesson 8 Lesson 8: The art of writing Prompt for Code — From vague to precise

Vibe Coding with GitHub Copilot: From Basics to Advanced

Part 3: Prompt Engineering for Code

xdev.asia

1. Why is Prompt Engineering important for Vibe Coding?

In Vibe Coding, prompt is your code. Output quality depends directly on prompt quality. A good prompt can save hours of iterating, while a bad prompt leads to completely wrong code.

❌ Prompt tồi:  "Make a login page"
✅ Prompt tốt:  "Create a login page with email/password fields using React Hook Form,
                 Zod validation, error messages below each field, submit button
                 disabled until valid, loading spinner during API call,
                 redirect to /dashboard on success. Use our existing AuthContext
                 and api/auth endpoint. Follow the design system in styles/theme.ts"

2. Anatomy of a Good Code Prompt

An effective prompt code has 5 components:

┌─────────────────────────────────────────────────┐
│           PROMPT STRUCTURE                       │
├─────────────────────────────────────────────────┤
│                                                  │
│  1. CONTEXT     → Bối cảnh (tech stack, codebase)│
│  2. TASK        → Yêu cầu cụ thể                │
│  3. CONSTRAINTS → Ràng buộc (patterns, limits)   │
│  4. EXAMPLES    → Ví dụ input/output mong muốn  │
│  5. OUTPUT FORMAT → Định dạng kết quả           │
│                                                  │
└─────────────────────────────────────────────────┘

Application examples:

// CONTEXT
We have a Next.js 15 app with App Router, TypeScript, Prisma ORM,
and PostgreSQL. Authentication uses NextAuth v5 with JWT strategy.

// TASK Create an API route handler for creating blog posts.

// CONSTRAINTS

  • Use Zod for request body validation
  • Return proper HTTP status codes (201 created, 400 validation error, 401 unauthorized)
  • Only authenticated users with "author" role can create posts
  • Slug should be auto-generated from title (URL-safe, Vietnamese diacritics removed)
  • Include created_at timestamp

// EXAMPLES Request body: { "title": "Hướng dẫn Docker", "content": "Nội dung bài viết...", "tags": ["docker", "devops"] }

Expected response (201): { "id": "clx...", "title": "Hướng dẫn Docker", "slug": "huong-dan-docker", "content": "Nội dung bài viết...", "tags": ["docker", "devops"], "author_id": "user123", "created_at": "2026-03-31T12:00:00Z" }

// OUTPUT FORMAT Create the file at src/app/api/posts/route.ts following our existing API patterns.

3. Prompting Patterns for Code

3.1. Zero-shot — Zero e.g

// Đơn giản, nhanh. Phù hợp khi task rõ ràng:
Create a TypeScript utility function to deep merge two objects,
handling arrays by concatenation and nested objects recursively.

3.2. Few-shot — There are examples

// Cung cấp examples để AI hiểu pattern mong muốn:
Create a validation function following this pattern:

// Example 1: validateEmail("[email protected]") → { valid: true } validateEmail("invalid") → { valid: false, error: "Invalid email format" }

// Example 2: validatePhone("+84912345678") → { valid: true } validatePhone("abc") → { valid: false, error: "Invalid phone number" }

// Now create: validateUsername(username) with rules:

  • 3-20 characters
  • Only alphanumeric and underscore
  • Cannot start with number

3.3. Chain-of-Thought — Step-by-step reasoning

// Yêu cầu AI "think step by step":
Design a rate limiter middleware for Express.js.
Think step by step:
1. First, decide on the algorithm (token bucket vs sliding window)
2. Then, choose the storage (in-memory vs Redis)
3. Implement the middleware with configurable options
4. Add proper error responses and headers
5. Write unit tests for edge cases

3.4. Role-based — Set a role for the AI

// Cho AI một persona:
Act as a senior security engineer reviewing this authentication code.
Identify all security vulnerabilities and suggest fixes with code examples.
Focus on: injection attacks, token handling, password storage, rate limiting.

4. Iterative Prompting — Gradual improvement

Effective Vibe Coding is one conversation, not a single prompt:

// Round 1: Tạo cơ bản
Create a search component for our blog with debounced input.

// Round 2: Cải thiện
Good, but add these improvements:
- Show loading skeleton while fetching
- Handle empty results with a friendly message
- Add keyboard navigation (arrow keys to select, Enter to open)

// Round 3: Edge cases
Now handle these edge cases:
- Search query less than 3 characters → show "Type at least 3 characters"
- API error → show retry button
- Very long results → add pagination with "Load more"

// Round 4: Polish
Finally, add proper ARIA attributes for accessibility
and transition animations for smooth UX.

5. Common Mistakes and how to fix them

Mistake For example Fix
Too vague "Make a dashboard" Specify metrics, charts, data source, layout
Too long 500+ words in 1 prompt Divided into several iterations
No context "Add authentication" Specify framework, strategy, existing code
Contradictory "Use REST but real-time" Obvious: REST + WebSocket for real-time
No constraints "Create an API" Specify error handling, auth, validation
Vietnamese and English "Create a function to check validity" Consistency: full English or full Vietnamese

6. Prompt Templates are available

Template: New Features

Create [FEATURE_NAME] for our [FRAMEWORK] app.

Context:

  • Tech stack: [STACK]
  • Current architecture: [PATTERN]
  • Related files: [FILE_PATHS]

Requirements:

  1. [REQUIREMENT_1]
  2. [REQUIREMENT_2]
  3. [REQUIREMENT_3]

Constraints:

  • Follow [PATTERN_NAME] pattern
  • Use [LIBRARY] for [PURPOSE]
  • Handle errors with [STRATEGY]
  • Include [TEST_TYPE] tests

Template: Bug Fix

Fix this bug: [BUG_DESCRIPTION]

Error message: [ERROR_MESSAGE]

Steps to reproduce:

  1. [STEP_1]
  2. [STEP_2]

Expected behavior: [EXPECTED] Actual behavior: [ACTUAL]

Relevant files: [FILE_PATHS]

Template: Refactoring

Refactor [CODE_DESCRIPTION] to improve [QUALITY_ATTRIBUTE].

Current issues:

  • [ISSUE_1]
  • [ISSUE_2]

Target state:

  • [DESIRED_STATE_1]
  • [DESIRED_STATE_2]

Constraints:

  • Don't change the public API
  • Maintain backward compatibility
  • Keep test coverage above [X]%

7. English vs Vietnamese in Prompt

AI models (GPT, Claude) are trained mainly in English, so:

  • Prompt in English often gives better results for the code
  • Prompt Vietnamese OK for: explanation, documentation, comments
  • Mixed (Vietnamese + code terms English) also works well with Copilot
// OK - Mixed language:
Tạo một middleware xử lý rate limiting cho Express.js,
sử dụng sliding window algorithm với Redis.

// Better - Full English cho complex code tasks:
Create a rate limiting middleware for Express.js using
sliding window algorithm with Redis backend.

8. Summary

Pattern When to use
Zero-shot Task is simple and clear
Few-shot Need output according to specific pattern
Chain-of-Thoughts Complex logic, design decisions
Role-based Security review, code review, specific expertise
Iterative Every task (should always be used)

The next article will go deeper Context Management — how to provide the right context for AI to understand your codebase.