mirror of
https://github.com/coleam00/context-engineering-intro.git
synced 2025-12-29 16:14:56 +00:00
Context engineering intro
This commit is contained in:
395
PRPs/EXAMPLE_multi_agent_prp.md
Normal file
395
PRPs/EXAMPLE_multi_agent_prp.md
Normal file
@@ -0,0 +1,395 @@
|
||||
name: "Multi-Agent System: Research Agent with Email Draft Sub-Agent"
|
||||
description: |
|
||||
|
||||
## Purpose
|
||||
Build a Pydantic AI multi-agent system where a primary Research Agent uses Brave Search API and has an Email Draft Agent (using Gmail API) as a tool. This demonstrates agent-as-tool pattern with external API integrations.
|
||||
|
||||
## Core Principles
|
||||
1. **Context is King**: Include ALL necessary documentation, examples, and caveats
|
||||
2. **Validation Loops**: Provide executable tests/lints the AI can run and fix
|
||||
3. **Information Dense**: Use keywords and patterns from the codebase
|
||||
4. **Progressive Success**: Start simple, validate, then enhance
|
||||
|
||||
---
|
||||
|
||||
## Goal
|
||||
Create a production-ready multi-agent system where users can research topics via CLI, and the Research Agent can delegate email drafting tasks to an Email Draft Agent. The system should support multiple LLM providers and handle API authentication securely.
|
||||
|
||||
## Why
|
||||
- **Business value**: Automates research and email drafting workflows
|
||||
- **Integration**: Demonstrates advanced Pydantic AI multi-agent patterns
|
||||
- **Problems solved**: Reduces manual work for research-based email communications
|
||||
|
||||
## What
|
||||
A CLI-based application where:
|
||||
- Users input research queries
|
||||
- Research Agent searches using Brave API
|
||||
- Research Agent can invoke Email Draft Agent to create Gmail drafts
|
||||
- Results stream back to the user in real-time
|
||||
|
||||
### Success Criteria
|
||||
- [ ] Research Agent successfully searches via Brave API
|
||||
- [ ] Email Agent creates Gmail drafts with proper authentication
|
||||
- [ ] Research Agent can invoke Email Agent as a tool
|
||||
- [ ] CLI provides streaming responses with tool visibility
|
||||
- [ ] All tests pass and code meets quality standards
|
||||
|
||||
## All Needed Context
|
||||
|
||||
### Documentation & References
|
||||
```yaml
|
||||
# MUST READ - Include these in your context window
|
||||
- url: https://ai.pydantic.dev/agents/
|
||||
why: Core agent creation patterns
|
||||
|
||||
- url: https://ai.pydantic.dev/multi-agent-applications/
|
||||
why: Multi-agent system patterns, especially agent-as-tool
|
||||
|
||||
- url: https://developers.google.com/gmail/api/guides/sending
|
||||
why: Gmail API authentication and draft creation
|
||||
|
||||
- url: https://api-dashboard.search.brave.com/app/documentation
|
||||
why: Brave Search API REST endpoints
|
||||
|
||||
- file: examples/agent/agent.py
|
||||
why: Pattern for agent creation, tool registration, dependencies
|
||||
|
||||
- file: examples/agent/providers.py
|
||||
why: Multi-provider LLM configuration pattern
|
||||
|
||||
- file: examples/cli.py
|
||||
why: CLI structure with streaming responses and tool visibility
|
||||
|
||||
- url: https://github.com/googleworkspace/python-samples/blob/main/gmail/snippet/send%20mail/create_draft.py
|
||||
why: Official Gmail draft creation example
|
||||
```
|
||||
|
||||
### Current Codebase tree
|
||||
```bash
|
||||
.
|
||||
├── examples/
|
||||
│ ├── agent/
|
||||
│ │ ├── agent.py
|
||||
│ │ ├── providers.py
|
||||
│ │ └── ...
|
||||
│ └── cli.py
|
||||
├── PRPs/
|
||||
│ └── templates/
|
||||
│ └── prp_base.md
|
||||
├── INITIAL.md
|
||||
├── CLAUDE.md
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
### Desired Codebase tree with files to be added
|
||||
```bash
|
||||
.
|
||||
├── agents/
|
||||
│ ├── __init__.py # Package init
|
||||
│ ├── research_agent.py # Primary agent with Brave Search
|
||||
│ ├── email_agent.py # Sub-agent with Gmail capabilities
|
||||
│ ├── providers.py # LLM provider configuration
|
||||
│ └── models.py # Pydantic models for data validation
|
||||
├── tools/
|
||||
│ ├── __init__.py # Package init
|
||||
│ ├── brave_search.py # Brave Search API integration
|
||||
│ └── gmail_tool.py # Gmail API integration
|
||||
├── config/
|
||||
│ ├── __init__.py # Package init
|
||||
│ └── settings.py # Environment and config management
|
||||
├── tests/
|
||||
│ ├── __init__.py # Package init
|
||||
│ ├── test_research_agent.py # Research agent tests
|
||||
│ ├── test_email_agent.py # Email agent tests
|
||||
│ ├── test_brave_search.py # Brave search tool tests
|
||||
│ ├── test_gmail_tool.py # Gmail tool tests
|
||||
│ └── test_cli.py # CLI tests
|
||||
├── cli.py # CLI interface
|
||||
├── .env.example # Environment variables template
|
||||
├── requirements.txt # Updated dependencies
|
||||
├── README.md # Comprehensive documentation
|
||||
└── credentials/.gitkeep # Directory for Gmail credentials
|
||||
```
|
||||
|
||||
### Known Gotchas & Library Quirks
|
||||
```python
|
||||
# CRITICAL: Pydantic AI requires async throughout - no sync functions in async context
|
||||
# CRITICAL: Gmail API requires OAuth2 flow on first run - credentials.json needed
|
||||
# CRITICAL: Brave API has rate limits - 2000 req/month on free tier
|
||||
# CRITICAL: Agent-as-tool pattern requires passing ctx.usage for token tracking
|
||||
# CRITICAL: Gmail drafts need base64 encoding with proper MIME formatting
|
||||
# CRITICAL: Always use absolute imports for cleaner code
|
||||
# CRITICAL: Store sensitive credentials in .env, never commit them
|
||||
```
|
||||
|
||||
## Implementation Blueprint
|
||||
|
||||
### Data models and structure
|
||||
|
||||
```python
|
||||
# models.py - Core data structures
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import List, Optional
|
||||
from datetime import datetime
|
||||
|
||||
class ResearchQuery(BaseModel):
|
||||
query: str = Field(..., description="Research topic to investigate")
|
||||
max_results: int = Field(10, ge=1, le=50)
|
||||
include_summary: bool = Field(True)
|
||||
|
||||
class BraveSearchResult(BaseModel):
|
||||
title: str
|
||||
url: str
|
||||
description: str
|
||||
score: float = Field(0.0, ge=0.0, le=1.0)
|
||||
|
||||
class EmailDraft(BaseModel):
|
||||
to: List[str] = Field(..., min_items=1)
|
||||
subject: str = Field(..., min_length=1)
|
||||
body: str = Field(..., min_length=1)
|
||||
cc: Optional[List[str]] = None
|
||||
bcc: Optional[List[str]] = None
|
||||
|
||||
class ResearchEmailRequest(BaseModel):
|
||||
research_query: str
|
||||
email_context: str = Field(..., description="Context for email generation")
|
||||
recipient_email: str
|
||||
```
|
||||
|
||||
### List of tasks to be completed
|
||||
|
||||
```yaml
|
||||
Task 1: Setup Configuration and Environment
|
||||
CREATE config/settings.py:
|
||||
- PATTERN: Use pydantic-settings like examples use os.getenv
|
||||
- Load environment variables with defaults
|
||||
- Validate required API keys present
|
||||
|
||||
CREATE .env.example:
|
||||
- Include all required environment variables with descriptions
|
||||
- Follow pattern from examples/README.md
|
||||
|
||||
Task 2: Implement Brave Search Tool
|
||||
CREATE tools/brave_search.py:
|
||||
- PATTERN: Async functions like examples/agent/tools.py
|
||||
- Simple REST client using httpx (already in requirements)
|
||||
- Handle rate limits and errors gracefully
|
||||
- Return structured BraveSearchResult models
|
||||
|
||||
Task 3: Implement Gmail Tool
|
||||
CREATE tools/gmail_tool.py:
|
||||
- PATTERN: Follow OAuth2 flow from Gmail quickstart
|
||||
- Store token.json in credentials/ directory
|
||||
- Create draft with proper MIME encoding
|
||||
- Handle authentication refresh automatically
|
||||
|
||||
Task 4: Create Email Draft Agent
|
||||
CREATE agents/email_agent.py:
|
||||
- PATTERN: Follow examples/agent/agent.py structure
|
||||
- Use Agent with deps_type pattern
|
||||
- Register gmail_tool as @agent.tool
|
||||
- Return EmailDraft model
|
||||
|
||||
Task 5: Create Research Agent
|
||||
CREATE agents/research_agent.py:
|
||||
- PATTERN: Multi-agent pattern from Pydantic AI docs
|
||||
- Register brave_search as tool
|
||||
- Register email_agent.run() as tool
|
||||
- Use RunContext for dependency injection
|
||||
|
||||
Task 6: Implement CLI Interface
|
||||
CREATE cli.py:
|
||||
- PATTERN: Follow examples/cli.py streaming pattern
|
||||
- Color-coded output with tool visibility
|
||||
- Handle async properly with asyncio.run()
|
||||
- Session management for conversation context
|
||||
|
||||
Task 7: Add Comprehensive Tests
|
||||
CREATE tests/:
|
||||
- PATTERN: Mirror examples test structure
|
||||
- Mock external API calls
|
||||
- Test happy path, edge cases, errors
|
||||
- Ensure 80%+ coverage
|
||||
|
||||
Task 8: Create Documentation
|
||||
CREATE README.md:
|
||||
- PATTERN: Follow examples/README.md structure
|
||||
- Include setup, installation, usage
|
||||
- API key configuration steps
|
||||
- Architecture diagram
|
||||
```
|
||||
|
||||
### Per task pseudocode
|
||||
|
||||
```python
|
||||
# Task 2: Brave Search Tool
|
||||
async def search_brave(query: str, api_key: str, count: int = 10) -> List[BraveSearchResult]:
|
||||
# PATTERN: Use httpx like examples use aiohttp
|
||||
async with httpx.AsyncClient() as client:
|
||||
headers = {"X-Subscription-Token": api_key}
|
||||
params = {"q": query, "count": count}
|
||||
|
||||
# GOTCHA: Brave API returns 401 if API key invalid
|
||||
response = await client.get(
|
||||
"https://api.search.brave.com/res/v1/web/search",
|
||||
headers=headers,
|
||||
params=params,
|
||||
timeout=30.0 # CRITICAL: Set timeout to avoid hanging
|
||||
)
|
||||
|
||||
# PATTERN: Structured error handling
|
||||
if response.status_code != 200:
|
||||
raise BraveAPIError(f"API returned {response.status_code}")
|
||||
|
||||
# Parse and validate with Pydantic
|
||||
data = response.json()
|
||||
return [BraveSearchResult(**result) for result in data.get("web", {}).get("results", [])]
|
||||
|
||||
# Task 5: Research Agent with Email Agent as Tool
|
||||
@research_agent.tool
|
||||
async def create_email_draft(
|
||||
ctx: RunContext[AgentDependencies],
|
||||
recipient: str,
|
||||
subject: str,
|
||||
context: str
|
||||
) -> str:
|
||||
"""Create email draft based on research context."""
|
||||
# CRITICAL: Pass usage for token tracking
|
||||
result = await email_agent.run(
|
||||
f"Create an email to {recipient} about: {context}",
|
||||
deps=EmailAgentDeps(subject=subject),
|
||||
usage=ctx.usage # PATTERN from multi-agent docs
|
||||
)
|
||||
|
||||
return f"Draft created with ID: {result.data}"
|
||||
```
|
||||
|
||||
### Integration Points
|
||||
```yaml
|
||||
ENVIRONMENT:
|
||||
- add to: .env
|
||||
- vars: |
|
||||
# LLM Configuration
|
||||
LLM_PROVIDER=openai
|
||||
LLM_API_KEY=sk-...
|
||||
LLM_MODEL=gpt-4
|
||||
|
||||
# Brave Search
|
||||
BRAVE_API_KEY=BSA...
|
||||
|
||||
# Gmail (path to credentials.json)
|
||||
GMAIL_CREDENTIALS_PATH=./credentials/credentials.json
|
||||
|
||||
CONFIG:
|
||||
- Gmail OAuth: First run opens browser for authorization
|
||||
- Token storage: ./credentials/token.json (auto-created)
|
||||
|
||||
DEPENDENCIES:
|
||||
- Update requirements.txt with:
|
||||
- google-api-python-client
|
||||
- google-auth-httplib2
|
||||
- google-auth-oauthlib
|
||||
```
|
||||
|
||||
## Validation Loop
|
||||
|
||||
### Level 1: Syntax & Style
|
||||
```bash
|
||||
# Run these FIRST - fix any errors before proceeding
|
||||
ruff check . --fix # Auto-fix style issues
|
||||
mypy . # Type checking
|
||||
|
||||
# Expected: No errors. If errors, READ and fix.
|
||||
```
|
||||
|
||||
### Level 2: Unit Tests
|
||||
```python
|
||||
# test_research_agent.py
|
||||
async def test_research_with_brave():
|
||||
"""Test research agent searches correctly"""
|
||||
agent = create_research_agent()
|
||||
result = await agent.run("AI safety research")
|
||||
assert result.data
|
||||
assert len(result.data) > 0
|
||||
|
||||
async def test_research_creates_email():
|
||||
"""Test research agent can invoke email agent"""
|
||||
agent = create_research_agent()
|
||||
result = await agent.run(
|
||||
"Research AI safety and draft email to john@example.com"
|
||||
)
|
||||
assert "draft_id" in result.data
|
||||
|
||||
# test_email_agent.py
|
||||
def test_gmail_authentication(monkeypatch):
|
||||
"""Test Gmail OAuth flow handling"""
|
||||
monkeypatch.setenv("GMAIL_CREDENTIALS_PATH", "test_creds.json")
|
||||
tool = GmailTool()
|
||||
assert tool.service is not None
|
||||
|
||||
async def test_create_draft():
|
||||
"""Test draft creation with proper encoding"""
|
||||
agent = create_email_agent()
|
||||
result = await agent.run(
|
||||
"Create email to test@example.com about AI research"
|
||||
)
|
||||
assert result.data.get("draft_id")
|
||||
```
|
||||
|
||||
```bash
|
||||
# Run tests iteratively until passing:
|
||||
pytest tests/ -v --cov=agents --cov=tools --cov-report=term-missing
|
||||
|
||||
# If failing: Debug specific test, fix code, re-run
|
||||
```
|
||||
|
||||
### Level 3: Integration Test
|
||||
```bash
|
||||
# Test CLI interaction
|
||||
python cli.py
|
||||
|
||||
# Expected interaction:
|
||||
# You: Research latest AI safety developments
|
||||
# 🤖 Assistant: [Streams research results]
|
||||
# 🛠 Tools Used:
|
||||
# 1. brave_search (query='AI safety developments', limit=10)
|
||||
#
|
||||
# You: Create an email draft about this to john@example.com
|
||||
# 🤖 Assistant: [Creates draft]
|
||||
# 🛠 Tools Used:
|
||||
# 1. create_email_draft (recipient='john@example.com', ...)
|
||||
|
||||
# Check Gmail drafts folder for created draft
|
||||
```
|
||||
|
||||
## Final Validation Checklist
|
||||
- [ ] All tests pass: `pytest tests/ -v`
|
||||
- [ ] No linting errors: `ruff check .`
|
||||
- [ ] No type errors: `mypy .`
|
||||
- [ ] Gmail OAuth flow works (browser opens, token saved)
|
||||
- [ ] Brave Search returns results
|
||||
- [ ] Research Agent invokes Email Agent successfully
|
||||
- [ ] CLI streams responses with tool visibility
|
||||
- [ ] Error cases handled gracefully
|
||||
- [ ] README includes clear setup instructions
|
||||
- [ ] .env.example has all required variables
|
||||
|
||||
---
|
||||
|
||||
## Anti-Patterns to Avoid
|
||||
- ❌ Don't hardcode API keys - use environment variables
|
||||
- ❌ Don't use sync functions in async agent context
|
||||
- ❌ Don't skip OAuth flow setup for Gmail
|
||||
- ❌ Don't ignore rate limits for APIs
|
||||
- ❌ Don't forget to pass ctx.usage in multi-agent calls
|
||||
- ❌ Don't commit credentials.json or token.json files
|
||||
|
||||
## Confidence Score: 9/10
|
||||
|
||||
High confidence due to:
|
||||
- Clear examples to follow from the codebase
|
||||
- Well-documented external APIs
|
||||
- Established patterns for multi-agent systems
|
||||
- Comprehensive validation gates
|
||||
|
||||
Minor uncertainty on Gmail OAuth first-time setup UX, but documentation provides clear guidance.
|
||||
212
PRPs/templates/prp_base.md
Normal file
212
PRPs/templates/prp_base.md
Normal file
@@ -0,0 +1,212 @@
|
||||
name: "Base PRP Template v2 - Context-Rich with Validation Loops"
|
||||
description: |
|
||||
|
||||
## Purpose
|
||||
Template optimized for AI agents to implement features with sufficient context and self-validation capabilities to achieve working code through iterative refinement.
|
||||
|
||||
## Core Principles
|
||||
1. **Context is King**: Include ALL necessary documentation, examples, and caveats
|
||||
2. **Validation Loops**: Provide executable tests/lints the AI can run and fix
|
||||
3. **Information Dense**: Use keywords and patterns from the codebase
|
||||
4. **Progressive Success**: Start simple, validate, then enhance
|
||||
5. **Global rules**: Be sure to follow all rules in CLAUDE.md
|
||||
|
||||
---
|
||||
|
||||
## Goal
|
||||
[What needs to be built - be specific about the end state and desires]
|
||||
|
||||
## Why
|
||||
- [Business value and user impact]
|
||||
- [Integration with existing features]
|
||||
- [Problems this solves and for whom]
|
||||
|
||||
## What
|
||||
[User-visible behavior and technical requirements]
|
||||
|
||||
### Success Criteria
|
||||
- [ ] [Specific measurable outcomes]
|
||||
|
||||
## All Needed Context
|
||||
|
||||
### Documentation & References (list all context needed to implement the feature)
|
||||
```yaml
|
||||
# MUST READ - Include these in your context window
|
||||
- url: [Official API docs URL]
|
||||
why: [Specific sections/methods you'll need]
|
||||
|
||||
- file: [path/to/example.py]
|
||||
why: [Pattern to follow, gotchas to avoid]
|
||||
|
||||
- doc: [Library documentation URL]
|
||||
section: [Specific section about common pitfalls]
|
||||
critical: [Key insight that prevents common errors]
|
||||
|
||||
- docfile: [PRPs/ai_docs/file.md]
|
||||
why: [docs that the user has pasted in to the project]
|
||||
|
||||
```
|
||||
|
||||
### Current Codebase tree (run `tree` in the root of the project) to get an overview of the codebase
|
||||
```bash
|
||||
|
||||
```
|
||||
|
||||
### Desired Codebase tree with files to be added and responsibility of file
|
||||
```bash
|
||||
|
||||
```
|
||||
|
||||
### Known Gotchas of our codebase & Library Quirks
|
||||
```python
|
||||
# CRITICAL: [Library name] requires [specific setup]
|
||||
# Example: FastAPI requires async functions for endpoints
|
||||
# Example: This ORM doesn't support batch inserts over 1000 records
|
||||
# Example: We use pydantic v2 and
|
||||
```
|
||||
|
||||
## Implementation Blueprint
|
||||
|
||||
### Data models and structure
|
||||
|
||||
Create the core data models, we ensure type safety and consistency.
|
||||
```python
|
||||
Examples:
|
||||
- orm models
|
||||
- pydantic models
|
||||
- pydantic schemas
|
||||
- pydantic validators
|
||||
|
||||
```
|
||||
|
||||
### list of tasks to be completed to fullfill the PRP in the order they should be completed
|
||||
|
||||
```yaml
|
||||
Task 1:
|
||||
MODIFY src/existing_module.py:
|
||||
- FIND pattern: "class OldImplementation"
|
||||
- INJECT after line containing "def __init__"
|
||||
- PRESERVE existing method signatures
|
||||
|
||||
CREATE src/new_feature.py:
|
||||
- MIRROR pattern from: src/similar_feature.py
|
||||
- MODIFY class name and core logic
|
||||
- KEEP error handling pattern identical
|
||||
|
||||
...(...)
|
||||
|
||||
Task N:
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Per task pseudocode as needed added to each task
|
||||
```python
|
||||
|
||||
# Task 1
|
||||
# Pseudocode with CRITICAL details dont write entire code
|
||||
async def new_feature(param: str) -> Result:
|
||||
# PATTERN: Always validate input first (see src/validators.py)
|
||||
validated = validate_input(param) # raises ValidationError
|
||||
|
||||
# GOTCHA: This library requires connection pooling
|
||||
async with get_connection() as conn: # see src/db/pool.py
|
||||
# PATTERN: Use existing retry decorator
|
||||
@retry(attempts=3, backoff=exponential)
|
||||
async def _inner():
|
||||
# CRITICAL: API returns 429 if >10 req/sec
|
||||
await rate_limiter.acquire()
|
||||
return await external_api.call(validated)
|
||||
|
||||
result = await _inner()
|
||||
|
||||
# PATTERN: Standardized response format
|
||||
return format_response(result) # see src/utils/responses.py
|
||||
```
|
||||
|
||||
### Integration Points
|
||||
```yaml
|
||||
DATABASE:
|
||||
- migration: "Add column 'feature_enabled' to users table"
|
||||
- index: "CREATE INDEX idx_feature_lookup ON users(feature_id)"
|
||||
|
||||
CONFIG:
|
||||
- add to: config/settings.py
|
||||
- pattern: "FEATURE_TIMEOUT = int(os.getenv('FEATURE_TIMEOUT', '30'))"
|
||||
|
||||
ROUTES:
|
||||
- add to: src/api/routes.py
|
||||
- pattern: "router.include_router(feature_router, prefix='/feature')"
|
||||
```
|
||||
|
||||
## Validation Loop
|
||||
|
||||
### Level 1: Syntax & Style
|
||||
```bash
|
||||
# Run these FIRST - fix any errors before proceeding
|
||||
ruff check src/new_feature.py --fix # Auto-fix what's possible
|
||||
mypy src/new_feature.py # Type checking
|
||||
|
||||
# Expected: No errors. If errors, READ the error and fix.
|
||||
```
|
||||
|
||||
### Level 2: Unit Tests each new feature/file/function use existing test patterns
|
||||
```python
|
||||
# CREATE test_new_feature.py with these test cases:
|
||||
def test_happy_path():
|
||||
"""Basic functionality works"""
|
||||
result = new_feature("valid_input")
|
||||
assert result.status == "success"
|
||||
|
||||
def test_validation_error():
|
||||
"""Invalid input raises ValidationError"""
|
||||
with pytest.raises(ValidationError):
|
||||
new_feature("")
|
||||
|
||||
def test_external_api_timeout():
|
||||
"""Handles timeouts gracefully"""
|
||||
with mock.patch('external_api.call', side_effect=TimeoutError):
|
||||
result = new_feature("valid")
|
||||
assert result.status == "error"
|
||||
assert "timeout" in result.message
|
||||
```
|
||||
|
||||
```bash
|
||||
# Run and iterate until passing:
|
||||
uv run pytest test_new_feature.py -v
|
||||
# If failing: Read error, understand root cause, fix code, re-run (never mock to pass)
|
||||
```
|
||||
|
||||
### Level 3: Integration Test
|
||||
```bash
|
||||
# Start the service
|
||||
uv run python -m src.main --dev
|
||||
|
||||
# Test the endpoint
|
||||
curl -X POST http://localhost:8000/feature \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"param": "test_value"}'
|
||||
|
||||
# Expected: {"status": "success", "data": {...}}
|
||||
# If error: Check logs at logs/app.log for stack trace
|
||||
```
|
||||
|
||||
## Final validation Checklist
|
||||
- [ ] All tests pass: `uv run pytest tests/ -v`
|
||||
- [ ] No linting errors: `uv run ruff check src/`
|
||||
- [ ] No type errors: `uv run mypy src/`
|
||||
- [ ] Manual test successful: [specific curl/command]
|
||||
- [ ] Error cases handled gracefully
|
||||
- [ ] Logs are informative but not verbose
|
||||
- [ ] Documentation updated if needed
|
||||
|
||||
---
|
||||
|
||||
## Anti-Patterns to Avoid
|
||||
- ❌ Don't create new patterns when existing ones work
|
||||
- ❌ Don't skip validation because "it should work"
|
||||
- ❌ Don't ignore failing tests - fix them
|
||||
- ❌ Don't use sync functions in async context
|
||||
- ❌ Don't hardcode values that should be config
|
||||
- ❌ Don't catch all exceptions - be specific
|
||||
Reference in New Issue
Block a user