Anatomy of System Prompts

Context Injection & Dynamic Prompts

4 min read

Static prompts are templates; dynamic prompts are living systems. Context injection transforms generic instructions into situation-aware assistants.

What is Context Injection?

Context injection is the practice of inserting runtime information into system prompts:

Static: "You are a coding assistant."

Dynamic: "You are a coding assistant working on {{project_name}},
         a {{framework}} project in {{language}}. The user is
         {{username}} with {{permission_level}} access."

Context Categories

1. Environment Context

Information about the execution environment:

<environment>
  <working_directory>/Users/dev/my-project</working_directory>
  <platform>darwin</platform>
  <os_version>Darwin 24.6.0</os_version>
  <shell>zsh</shell>
  <node_version>20.10.0</node_version>
  <python_version>3.12.1</python_version>
</environment>

2. User Context

Information about the current user:

<user>
  <id>user_12345</id>
  <name>Alice Developer</name>
  <role>senior_engineer</role>
  <preferences>
    <language>typescript</language>
    <style>functional</style>
    <verbosity>concise</verbosity>
  </preferences>
</user>

3. Project Context

Information about the codebase:

<project>
  <name>my-saas-app</name>
  <framework>Next.js 15</framework>
  <language>TypeScript</language>
  <package_manager>pnpm</package_manager>
  <structure>
    - src/app (App Router)
    - src/components
    - src/lib
    - prisma/schema.prisma
  </structure>
</project>

4. Conversation Context

Information about the current interaction:

<conversation>
  <message_count>12</message_count>
  <current_task>implementing user authentication</current_task>
  <files_modified>
    - src/lib/auth.ts
    - src/app/api/auth/route.ts
  </files_modified>
  <pending_actions>
    - Run tests
    - Update documentation
  </pending_actions>
</conversation>

Real-World Context Patterns

Cursor's Context Injection

Cursor injects rich codebase context:

<codebase_context>
Recently opened files:
- src/components/Button.tsx (modified 2 min ago)
- src/hooks/useAuth.ts (modified 5 min ago)

Symbols in scope:
- Button: React.FC<ButtonProps>
- useAuth: () => AuthContext
- api: AxiosInstance

Related files (by import graph):
- src/types/auth.ts
- src/lib/api-client.ts
</codebase_context>

Claude Code's Context Injection

Claude Code includes execution state:

<session_context>
  <git_status>
    branch: feature/auth
    staged: 2 files
    unstaged: 1 file
    untracked: 0 files
  </git_status>
  <recent_commands>
    - npm test (exit: 1, 3 failures)
    - npm run lint (exit: 0)
  </recent_commands>
  <active_todos>
    - Fix test failures in auth.test.ts
    - Update README with new API docs
  </active_todos>
</session_context>

Windsurf's Memory Context

Windsurf injects learned preferences:

<memories>
  <memory importance="high">
    User prefers Tailwind CSS for styling
  </memory>
  <memory importance="medium">
    Project uses PostgreSQL with Prisma ORM
  </memory>
  <memory importance="low">
    User likes detailed commit messages
  </memory>
</memories>

Context Injection Patterns

Pattern 1: Structured XML/JSON

<context type="environment">
  <key>value</key>
</context>

Pros: Easy to parse, clear boundaries Cons: Verbose, consumes tokens

Pattern 2: Natural Language

The user is working on a Next.js project called "my-app"
located at /Users/dev/my-app. They prefer TypeScript and
use pnpm as their package manager.

Pros: Model-friendly, flexible Cons: Harder to update programmatically

Pattern 3: Key-Value Pairs

PROJECT_NAME: my-app
FRAMEWORK: Next.js 15
LANGUAGE: TypeScript
PACKAGE_MANAGER: pnpm

Pros: Compact, scannable Cons: Limited structure

Dynamic Prompt Assembly

Production systems assemble prompts programmatically:

function buildSystemPrompt(context: Context): string {
  const sections = [
    buildIdentity(context.model),
    buildCapabilities(context.tools),
    buildEnvironment(context.env),
    buildProjectContext(context.project),
    buildUserContext(context.user),
    buildGuidelines(context.rules),
    buildConstraints(context.limits),
  ];

  return sections.join('\n\n');
}

Token Budget Management

Context injection requires careful token management:

Context Type Typical Tokens Priority
Core Identity 200-500 Critical
Tool Definitions 1,000-3,000 Critical
Environment 100-300 High
Project Structure 500-2,000 High
Recent Files 1,000-5,000 Medium
Conversation History Variable Medium
Memories 200-1,000 Low

Pro Tip: Use tiered context loading—inject essential context always, and add detailed context only when relevant to the task.

Context Freshness

Stale context causes errors. Production systems implement refresh strategies:

const contextRefreshRules = {
  environment: 'on_session_start',
  git_status: 'before_each_command',
  file_contents: 'on_file_change',
  memories: 'on_session_start',
  conversation: 'always_current',
};

Next module: We'll dive into specific patterns from AI coding assistants like Cursor, Windsurf, and Claude Code. :::

Quiz

Module 1: Anatomy of System Prompts

Take Quiz