Effective Prompting for Code
Advanced Prompting Techniques
Beyond basics, these advanced techniques help you get better results from AI coding assistants on complex tasks.
Few-Shot Prompting
Show examples of what you want:
Pattern Matching
Here's how we handle API responses in this project:
Example 1:
```typescript
// src/api/users.ts
export async function getUsers(): Promise<ApiResponse<User[]>> {
try {
const response = await api.get('/users');
return { data: response.data, error: null };
} catch (error) {
return { data: null, error: handleApiError(error) };
}
}
Example 2:
// src/api/products.ts
export async function getProducts(): Promise<ApiResponse<Product[]>> {
try {
const response = await api.get('/products');
return { data: response.data, error: null };
} catch (error) {
return { data: null, error: handleApiError(error) };
}
}
Now create similar functions for:
- getOrders()
- getOrderById(id: string)
- createOrder(data: CreateOrderInput)
### Code Style Examples
Our component tests follow this pattern:
describe('Button', () => {
it('renders with default props', () => {
render(<Button>Click me</Button>);
expect(screen.getByRole('button')).toHaveTextContent('Click me');
});
it('handles click events', async () => {
const handleClick = jest.fn();
render(<Button onClick={handleClick}>Click me</Button>);
await userEvent.click(screen.getByRole('button'));
expect(handleClick).toHaveBeenCalledTimes(1);
});
});
Write tests for the Modal component following this exact pattern.
## Chain-of-Thought Prompting
Ask the AI to think step by step:
### For Algorithm Design
Design a rate limiter. Think step by step:
- First, explain what data structure would be most efficient
- Then, describe the algorithm logic
- Consider edge cases (distributed systems, time zone issues)
- Finally, write the implementation
Show your reasoning at each step.
### For Debugging
This function has a bug. Debug it step by step:
- First, read the code and explain what it's supposed to do
- Trace through the execution with example input
- Identify where the logic fails
- Explain the fix
- Implement the corrected version
function findDuplicates(arr: number[]): number[] {
const seen = new Set();
return arr.filter(item => {
if (seen.has(item)) return true;
seen.add(item);
});
}
### For Architecture Decisions
I need to implement real-time notifications. Think through:
- What are the options? (WebSockets, SSE, polling)
- What are the trade-offs of each?
- Given we're using Next.js on Vercel, which makes most sense?
- What's the implementation plan?
Walk me through your reasoning before writing any code.
## Constraint Specification
Be explicit about constraints:
### Performance Constraints
Create a search function with these constraints:
- Must handle 100,000+ items
- Response time < 100ms
- Memory usage < 50MB
- Works on mobile browsers
Consider using:
- Binary search if sorted
- Index/cache for repeated searches
- Web Workers for heavy computation
### Compatibility Constraints
Create a date picker component:
- Must work with React 17 and 18
- No external dependencies except date-fns
- Support keyboard navigation (a11y)
- Work in all browsers including Safari 14+
- Support both controlled and uncontrolled usage
### Style Constraints
Generate code matching these style rules:
- 2 space indentation
- Single quotes for strings
- No semicolons
- Prefer const over let
- Use arrow functions for callbacks
- Named exports, no default exports
## Negative Prompting
Tell the AI what NOT to do:
Create a user authentication system.
DO NOT:
- Use deprecated crypto APIs
- Store passwords in plain text
- Use synchronous bcrypt functions
- Create custom JWT implementation (use jose library)
- Add console.logs in production code
- Use any as TypeScript type
DO:
- Use bcrypt with cost factor 12
- Implement proper CSRF protection
- Add rate limiting on auth endpoints
- Follow OWASP authentication guidelines
## Role-Based Prompting
Assign a specific role:
### Expert Role
You are a senior security engineer at a FAANG company.
Review this authentication code for security vulnerabilities. Think like an attacker trying to find exploits. Prioritize findings by severity (Critical/High/Medium/Low).
[code to review]
### Teacher Role
You are a patient coding mentor teaching a junior developer.
Explain how this React hook works, line by line. Use simple analogies when explaining complex concepts. After explaining, suggest improvements they could make.
[code to explain]
### Reviewer Role
You are a code reviewer at a company with strict quality standards.
Review this PR for:
- Logic errors
- Performance issues
- Security concerns
- Code style violations
- Missing tests
- Documentation gaps
Be constructive but thorough. Suggest specific fixes.
## Iterative Refinement Patterns
### The Funnel Pattern
Start broad, then narrow down:
Round 1: "Create a form handling utility" ↓ Round 2: "Add validation support with Zod schemas" ↓ Round 3: "Add support for async validation (API checks)" ↓ Round 4: "Add form state persistence to localStorage"
### The Layer Pattern
Build in layers:
Layer 1: Data Layer "Create TypeScript interfaces for the blog system"
Layer 2: API Layer "Create API routes for these interfaces"
Layer 3: Service Layer "Create service functions that call these APIs"
Layer 4: UI Layer "Create React components using these services"
### The Test-First Pattern
Step 1: "Write test cases for a URL validation utility" Step 2: "Now implement the utility to pass all tests" Step 3: "Add edge case tests for international URLs" Step 4: "Update implementation to pass new tests"
## Context Injection Techniques
### Using @-mentions Effectively
Looking at:
- @src/types/user.ts (for type definitions)
- @src/services/auth.ts (for existing patterns)
- @src/utils/validation.ts (for validation helpers)
Create a user profile update service that:
- Accepts partial user updates
- Validates email uniqueness
- Handles avatar upload
- Follows the same patterns as the referenced files
### Embedding Documentation
According to the Prisma documentation for transactions:
await prisma.$transaction([ prisma.user.create({ data: userData }), prisma.account.create({ data: accountData }), ])
Implement an atomic user registration that creates both a User and their initial Organization in a single transaction.
## Prompt Templates Library
### API Endpoint Template
Create a [METHOD] endpoint at /api/[path]:
Input: [describe input schema] Output: [describe output schema] Auth: [auth requirements] Validation: [validation rules]
Error cases:
- [case 1]: Return [status] with [message]
- [case 2]: Return [status] with [message]
Follow the pattern in @src/app/api/[existing-endpoint]/route.ts
### Component Template
Create a [ComponentName] component:
Props:
- [prop1]: [type] - [description]
- [prop2]: [type] - [description]
Behavior:
- [behavior 1]
- [behavior 2]
States:
- Loading: [how it looks]
- Error: [how it handles errors]
- Empty: [empty state display]
Style: Match @src/components/[SimilarComponent].tsx Tests: Include unit tests following our testing patterns
> **Advanced Insight:** The best prompts combine multiple techniques. Use few-shot for style, chain-of-thought for logic, constraints for quality, and negative prompting for safety.
In the next lesson, we'll build your personal prompt library for common scenarios.
:::