- Python (Microsoft) — core language support, IntelliSense, debugging
- Pylance — fast type checking and autocompletion (powered by Pyright)
- Python Debugger (Debugpy) — breakpoints and variable inspection
- Even Better TOML — syntax support for
pyproject.toml - REST Client — test API endpoints without leaving VS Code
Workspace Settings for AI Projects
// .vscode/settings.json
{
"python.defaultInterpreterPath": "${workspaceFolder}/venv/bin/python",
"editor.formatOnSave": true,
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter"
},
"python.linting.enabled": true,
"python.linting.pylintEnabled": false,
"python.linting.flake8Enabled": false,
"python.analysis.typeCheckingMode": "basic"
}
Project Structure for AI Applications
A well-organized AI project makes it easy to swap models, add evaluation harnesses, and onboard new engineers. Here's the structure used in production AI engineering teams:
my-ai-app/
├── .python-version # pyenv version pin
├── .env # API keys (never commit!)
├── .env.example # template with placeholder values
├── .gitignore # includes venv/, .env, __pycache__/
├── requirements.in # your direct deps (loosely pinned)
├── requirements.txt # generated lockfile (pip-compile output)
├── requirements-dev.in # dev-only direct deps
├── requirements-dev.txt # generated dev lockfile
├── pyproject.toml # optional: tool config (black, mypy)
├── src/
│ ├── __init__.py
│ ├── client.py # AI client abstraction
│ ├── prompts.py # prompt templates
│ ├── models.py # Pydantic models for I/O
│ └── utils.py # shared utilities
├── tests/
│ ├── __init__.py
│ ├── test_client.py
│ └── test_prompts.py
└── scripts/
└── run_eval.py # evaluation harnesses
The .gitignore for AI Projects
# .gitignore
venv/
.env
*.pyc
__pycache__/
.pytest_cache/
.mypy_cache/
*.egg-info/
dist/
.DS_Store
# Never commit these
*.key
*_credentials.json
Environment Variables and API Keys
AI applications are key-heavy — OpenAI API key, Anthropic API key, vector DB credentials, etc. The pattern is identical to what you'd use in .NET with appsettings.json and User Secrets, but Python has its own conventions.
# .env file (never commit this)
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...
PINECONE_API_KEY=...
APP_ENV=development
LOG_LEVEL=DEBUG
# In your code — load with python-dotenv
from dotenv import load_dotenv
import os
load_dotenv() # reads .env into environment variables
api_key = os.environ["ANTHROPIC_API_KEY"] # raises KeyError if missing
# OR
api_key = os.getenv("ANTHROPIC_API_KEY", "") # returns "" if missing
In production code, prefer os.environ["KEY"] over os.getenv("KEY"). The former raises a KeyError immediately if the variable is missing, making configuration errors loud and early rather than silently passing an empty string to your AI API.
Reproducible Environments: The Full Workflow
Here's the complete setup workflow a new engineer would follow when cloning your AI project:
# 1. Clone the repo
git clone https://github.com/your-org/my-ai-app
cd my-ai-app
# 2. Activate the correct Python version
pyenv local # reads .python-version, activates automatically
# 3. Create and activate a fresh venv
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# 4. Install pip-tools, then sync all dependencies from the lockfile
pip install pip-tools
pip-sync requirements.txt requirements-dev.txt
# 5. Set up environment variables
cp .env.example .env
# Edit .env with real API keys
# 6. Verify everything works
python -c "import anthropic; print('Ready!')"
pytest tests/ -q
This five-step process is deterministic. Given the same .python-version and pip-tools-generated requirements.txt, every engineer gets byte-identical package versions. This is exactly what you need for AI applications where subtle version differences can change model behavior.
Key Takeaways
- Use pyenv to manage multiple Python versions and pin one per project via
.python-version - Always create a venv per project — never install AI packages globally
- Use pip-tools: list your direct deps in
requirements.in, runpip-compileto generate the pinned lockfile, andpip-syncto install it exactly — never usepip freeze - Store API keys in .env files and load with
python-dotenv; never commit secrets - Use
os.environ["KEY"](notgetenv) so missing config fails fast - Point VS Code's interpreter to
./venv/bin/pythonfor accurate IntelliSense