Prompts & Instructions
The critical bridge between LLM text generation and file manipulation. How agents teach AI models to use their tools correctly.
Why Prompts Matter
An AI model doesn't inherently know how to edit files. It just generates text. The system prompt is how agents teach the model:
- What tools are available and their exact syntax
- When to use each tool (surgical edit vs. full rewrite)
- Critical rules (exact matching, escaping, ordering)
- How to handle errors and recover
- What format to output (XML, JSON, custom)
The Prompt Engineering Trap
Many developers underestimate how much detail the system prompt needs. A vague "you can edit files" instruction leads to hallucinated file paths, missing content, and syntax errors. Successful agents are extremely explicit.
Tool Definitions: The Contract
Every agent defines its tools with a precise schema. This tells the model exactly what parameters are required and what format to use.
Example: Cline's replace_in_file
From
src/core/prompts/system-prompt/tools/replace_in_file.ts:
## replace_in_file
Make targeted edits to specific parts of a file using SEARCH/REPLACE blocks.
### Parameters:
- **path** (required): File path relative to working directory
- **diff** (required): One or more SEARCH/REPLACE blocks
### SEARCH/REPLACE Block Format:
```
------- SEARCH
[exact content to find - must match EXACTLY including whitespace]
=======
[new content to replace with]
+++++++ REPLACE
```
### Critical Rules:
1. SEARCH content must match EXACTLY (character-for-character)
2. Only replaces the FIRST match occurrence
3. Multiple blocks must appear in file order
4. To delete code: Use empty REPLACE section
5. To move code: Delete from original + insert at new location
### Example:
```xml
<replace_in_file>
<path>src/app.ts</path>
<diff>
------- SEARCH
import React from 'react';
=======
import React, { useState } from 'react';
+++++++ REPLACE
</diff>
</replace_in_file>
```
Example: Codex's apply_patch
Codex uses a grammar-based parser with special markers:
## apply_patch
Apply changes to files using a patch format.
### Patch Format:
```
*** Begin Patch
*** Add File: <path> # Create new file
*** Update File: <path> # Modify existing file
*** Delete File: <path> # Remove file
*** Move to: <path> # Rename (with Update)
*** End Patch
```
### Context and Changes:
- `@@ <context>` - Context line for locating edit
- `+<text>` - Line to add
- `-<text>` - Line to remove
### Example:
```
*** Begin Patch
*** Update File: src/utils.py
@@ def calculate():
- return x + y
+ result = x + y
+ return result * factor
*** End Patch
```
System Prompt Strategies
Different agents take different approaches to instructing the AI. Here are the key patterns:
Strategy 1: Explicit Preference Order
Cline explicitly tells the model which tool to prefer:
### File Editing Approach
1. **Default to replace_in_file** for most changes (safer, more precise)
2. **Use write_to_file only when:**
- Creating new files
- Changes are so extensive that replace_in_file would be impractical
- File is small (< 50 lines) and changing most of it
- Generating boilerplate/scaffold
3. **Important:** After editing, the system may auto-format.
Re-read the file before making additional edits to get the
true content (quotes, indentation, semicolons may change).
Strategy 2: Explicit Anti-Patterns
Grok CLI lists what NOT to do:
IMPORTANT TOOL USAGE RULES:
- NEVER use create_file on files that already exist - this will
overwrite them completely
- ALWAYS use str_replace_editor to modify existing files, even
for small changes
- Before editing a file, use view_file to see its current contents
- Use create_file ONLY when creating entirely new files
When a user asks you to edit, update, modify, or change an
existing file:
1. First use view_file to see the current contents
2. Then use str_replace_editor to make the specific changes
3. Never use create_file for existing files
Strategy 3: Model-Specific Instructions
OpenCode maintains separate prompt files per model family:
| File | Model | Key Differences |
|---|---|---|
anthropic.txt |
Claude | "NEVER create files unless absolutely necessary" |
beast.txt |
GPT-4/5 | "Read 2000 lines at a time before editing" |
gemini.txt |
Gemini | Different escaping rules for code blocks |
qwen.txt |
Qwen | Simplified syntax, fewer fallbacks |
Example difference from OpenCode's anthropic.txt:
NEVER create files unless they're absolutely necessary for
achieving your goal. ALWAYS prefer editing an existing file
to creating a new one.
Use the Task tool for exploration when the request is ambiguous.
Break down complex edits into multiple smaller operations.
Error Handling & Recovery
What happens when an edit fails? Good prompts teach the model how to recover.
Aider's Error Template
When a SEARCH block fails to match, Aider returns this structured error:
# 1 SEARCH/REPLACE block failed to match!
## SearchReplaceNoExactMatch: This SEARCH block failed to
exactly match lines in src/app.py
<<<<<<< SEARCH
def calculate_total(items):
return sum(item.price for item in items)
=======
def calculate_total(items):
subtotal = sum(item.price for item in items)
return subtotal * 1.1
>>>>>>> REPLACE
Did you mean to match some of these actual lines from src/app.py?
```python
def calculate_total(items):
return sum(i.price for i in items) # Note: 'i' not 'item'
```
The SEARCH section must exactly match an existing block of lines
including all whitespace, comments, indentation, docstrings, etc.
OpenCode's LSP Feedback Loop
After every edit, OpenCode checks for syntax errors and appends them:
<tool_result status="success">
File edited successfully. Diff:
--- a/src/utils.py
+++ b/src/utils.py
@@ -10,3 +10,5 @@
def calculate():
- return x + y
+ subtotal = x + y
+ return subtotal * factor
<file_diagnostics>
Line 12: Name 'factor' is not defined
</file_diagnostics>
</tool_result>
The AI sees the error immediately and can self-correct without waiting for the user to run the code.
Cline's Failure Escalation
After 3 failed edit attempts, Cline suggests fallback:
The replace_in_file operation failed 3 times.
Consider using write_to_file instead to completely rewrite
the file. Make sure to include ALL existing content that
should be preserved, not just the changes.
Alternatively, use read_file to get the exact current content
and try again with a more precise SEARCH block.
Format Wars: XML vs JSON vs Custom
Why do agents use different output formats? Each has tradeoffs.
| Format | Used By | Pros | Cons |
|---|---|---|---|
| XML | Cline |
• No escaping for code content • Clear start/end boundaries • Familiar to LLMs |
• Verbose • Can confuse HTML/JSX |
| JSON | OpenCode, Crush, Neovate, Pochi, Qwen Code |
• Structured, parseable • Native to many APIs |
• Escaping hell for code • Newlines become \n |
| Custom Markers | Codex, Aider, Dirac (hash-anchor) |
• Optimized for code • Minimal token overhead • Familiar (git-style) |
• Custom parser needed • May conflict with code |
| Word Anchors | Dirac (exclusive) |
• Crypto-guaranteed match • No escaping needed • Survives partial edits |
• Requires hash state mgmt • LLM must learn anchor format |
| Markdown | Aider (whole) |
• Natural for LLMs • Code fences are common |
• Ambiguous boundaries • Easy to hallucinate |
The JSON Escaping Problem
If you pass code inside a JSON string, every quote becomes
\", every newline becomes \n, and every
backslash becomes \\. This is error-prone for LLMs
and wasteful on tokens. Cline and Codex avoid this by using XML or
custom formats.
Complete Examples: Creating a Function
Let's see how each agent would instruct the AI to add a new function to an existing file.
Cline's XML Format
<replace_in_file>
<path>src/utils.py</path>
<diff>
------- SEARCH
def existing_function():
return True
=======
def existing_function():
return True
def new_function(x, y):
"""Add two numbers with validation."""
if not isinstance(x, (int, float)):
raise TypeError("x must be numeric")
return x + y
+++++++ REPLACE
</diff>
</replace_in_file>
Note: Includes context (existing_function) to ensure unique match location.
Codex's Patch Format
*** Begin Patch
*** Update File: src/utils.py
@@ def existing_function():
@@ return True
+
+def new_function(x, y):
+ """Add two numbers with validation."""
+ if not isinstance(x, (int, float)):
+ raise TypeError("x must be numeric")
+ return x + y
*** End Patch
Note: Uses @@ context markers to locate insertion point.
Aider's SEARCH/REPLACE
src/utils.py
```python
<<<<<<< SEARCH
def existing_function():
return True
=======
def existing_function():
return True
def new_function(x, y):
"""Add two numbers with validation."""
if not isinstance(x, (int, float)):
raise TypeError("x must be numeric")
return x + y
>>>>>>> REPLACE
```
Note: Git-conflict-style markers. File path on line before fence.
Grok CLI's Tool Call
// First, view the file to get context
view_file("src/utils.py")
// Then, insert after the existing function
str_replace_editor({
filePath: "src/utils.py",
oldStr: `def existing_function():
return True`,
newStr: `def existing_function():
return True
def new_function(x, y):
"""Add two numbers with validation."""
if not isinstance(x, (int, float)):
raise TypeError("x must be numeric")
return x + y`,
replaceAll: false
})
Note: Two-step process—read then edit. JSON-style arguments.
Common Prompt Pitfalls
❌ Too Vague
"You can edit files using the
edit tool. Be careful."
Model doesn't know format, parameters, or edge cases.
✅ Explicit
"Use replace_in_file with exact
SEARCH blocks. Include 2-3
lines of context before and
after to ensure unique match."
Clear format, explicit uniqueness requirement.
❌ No Error Guidance
"Edit the file as needed."
When edit fails, model doesn't know how to recover.
✅ Recovery Path
"If SEARCH block fails, re-read
the file with read_file and
try again with exact content.
After 3 failures, fallback to
write_to_file."
Clear escalation path and recovery strategy.
Prompt Design Checklist
- Define exact tool syntax with examples
- Specify which tool to prefer (and when to switch)
- Explain the "exact match" requirement for search blocks
- Include context requirements (2-3 lines before/after)
- Provide error message templates with recovery instructions
- Mention auto-formatting risks (re-read after edit)
- List anti-patterns explicitly (never overwrite existing files)
- Consider model-specific adaptations
- Include examples for common operations (add, edit, delete, move)
- Define fallback escalation path