- Published on
Beyond Chat: A Structured Workflow for Predictable AI Development in Cursor
- Authors
- Name
- Xiaoyi Zhu
AI coding assistants like Cursor are revolutionizing how we write software. They promise faster development cycles, code generation, debugging help, and more. However, harnessing this power effectively, especially for complex tasks, often requires more than just conversational prompts. Relying solely on chat can lead to context loss, inconsistent results, and difficulty managing multi-step implementation processes. The AI might "forget" previous instructions, deviate from the plan, or require constant re-explanation.
What if we could impose more structure? What if we could guide the AI with a clear plan, maintain a persistent state, and ensure it focuses on one manageable step at a time? This post introduces a workflow designed to do just that, leveraging structured XML prompts and a simple two-file system within Cursor to create a more predictable, reliable, and autonomous development process.
The Headache: Wrangling Free-Form Agentic AI
While powerful, the typical chat-based interaction with agentic IDEs can present challenges:
- Context Drift & Ambiguity: Long conversations can lose vital context. Without clear structure, the AI might misinterpret instructions or confuse different pieces of information (like instructions vs. data).
- Lack of Planning: Diving straight into coding without a clear, agreed-upon plan increases the risk of rework or incorrect implementations.
- Inconsistent Execution: The AI might tackle steps out of order or hallucinate requirements not previously discussed, often due to missing or unclear context.
- Difficulty Tracking Progress: Understanding exactly what the AI has done and what's next can be difficult in a long chat history.
- Repetitive Setup: Starting new tasks often involves repeating similar context-setting instructions.
These issues can negate the productivity gains AI promises, especially on larger features or refactoring tasks. We need a way to provide clear instructions, maintain state, and enforce a logical execution flow.
The Fix: A Plan-Driven, State-Managed Workflow with Structured Prompts
This approach introduces discipline to the AI interaction using three core components:
- Structured XML Prompts: Instead of free-form text, we use predefined XML templates. Research and provider guidelines increasingly suggest that structure significantly improves LLM performance, especially for complex tasks. XML, with its explicit
<tag>...</tag>
structure, offers unambiguous delineation of prompt sections (like instructions, context, examples, state). This clarity helps the LLM parse the input accurately, minimizing misinterpretation risk, even though it might consume slightly more tokens than formats like Markdown. Major providers like Anthropic specifically fine-tune models like Claude for XML structure, making it highly effective. - Two-File System for Memory: This system addresses the inherent challenge of LLM statelessness by providing persistent context. This concept draws inspiration from community efforts like the workflow outlined in the kleosr/cursorkleosr repository, adapted here with XML prompts and a specific state structure.
implementation_plan.md
(Long-Term Memory - LTM): Generated upfront via a dedicated prompt, this Markdown file contains a detailed, step-by-step plan. Crucially, this file remains read-only during execution, serving as the immutable source of truth.implementation_state.md
(Short-Term Memory - STM): This dynamic Markdown file acts as the state tracker, recording the current task, progress, logs, and errors. This file is read before and updated after each step, providing essential short-term context and tracking the workflow's progression.
- Phased Workflow (Plan -> Execute -> Update):
- Planning Phase: Use an XML prompt to generate the
implementation_plan.md
. Review and refine this plan manually. - Execution Phase: Use a "kick-off" XML prompt, embedding references (
@
) to both theimplementation_plan.md
and theimplementation_state.md
. This prompt instructs the AI to execute tasks sequentially based on the plan (LTM) and current state (STM), updating the STM after each successful step. The AI operates autonomously, proceeding from one task to the next unless an error occurs.
- Planning Phase: Use an XML prompt to generate the
This system provides explicit control over the context provided to the AI, making the workflow transparent and potentially easier to debug. It represents a practical pattern emerging in the community to manage complex, multi-step AI interactions.
How It Works: The Workflow in Action
Let's break down the key phases and artifacts:
Phase 1: Generate the Implementation Plan
You start by using a dedicated XML prompt template to ask the AI to analyze the task and generate the implementation_plan.md
.
Example Plan Generation Prompt Template (generate_plan.xml
):
<PromptRequest>
<Goal>
Generate a detailed **implementation plan** in Markdown format for the task described in <TaskDescription/>. The plan should be based on an analysis of the current context and suitable for review before actual implementation begins.
</Goal>
<Context>
<TaskDescription>
{/* Use @symbol or paste task description here */}
{/* @symbol:path/to/your/task_description.md */}
</TaskDescription>
<RelevantCodebase>
{/* Use @symbol or list relevant files/dirs */}
{/* @symbol:path/to/relevant/code/file1.py */}
{/* @symbol:path/to/relevant/code/directory/ */}
</RelevantCodebase>
<RelevantDocumentation>
{/* @symbol:path/to/docs/api_spec.md */}
</RelevantDocumentation>
<CurrentState>
{/* Describe current project status or blockers */}
</CurrentState>
<RelevantTechnologies>
{/* e.g., Python 3.11, FastAPI, PostgreSQL, React */}
</RelevantTechnologies>
</Context>
<Request>
Please perform the following steps:
<AnalysisPhase>
1. **Analyze Current Context:**
* Conduct a comprehensive analysis of the <TaskDescription/> in relation to the <RelevantCodebase/>, <RelevantDocumentation/>, and <CurrentState/>.
* Evaluate potential impacts, dependencies, and prerequisites for the task.
* Identify potential challenges, risks, unknowns, or areas needing further investigation based on the provided context.
* **Summarize these findings clearly.**
</AnalysisPhase>
<PlanningPhase>
2. **Outline a Detailed Implementation Plan:**
Based on the analysis, **outline** a clear, actionable plan describing *how* the task will be implemented. This plan should detail the approach, broken down into **phases** with specific **tasks** and **steps** where applicable, covering the following aspects (adapt relevance based on the task):
* **<DesignAndArchitecturePlan title="Planned Design & Architecture">** {/* Outline design decisions */} </DesignAndArchitecturePlan>
* **<ImplementationDetailsPlan title="Planned Implementation Steps">** {/* Break down coding steps */} </ImplementationDetailsPlan>
* **<DataManagementPlan title="Planned Data Management (If Applicable)">** {/* Outline DB changes */} </DataManagementPlan>
* **<TestingStrategyPlan title="Planned Testing Strategy">** {/* Describe testing approach */} </TestingStrategyPlan>
* **<DeploymentPlan title="Planned Deployment/Rollout (If Applicable)">** {/* Outline deployment steps */} </DeploymentPlan>
* **<RollbackPlan title="Planned Rollback Strategy (If Applicable)">** {/* Describe rollback plan */} </RollbackPlan>
</PlanningPhase>
</Request>
<Deliverable>
The expected output is a **detailed implementation plan** in **Markdown format**. This document must contain:
1. A clear summary of the **Analysis Findings**.
2. A detailed **Implementation Plan Outline** covering the relevant planned aspects.
3. The plan must be structured with clear **Phases** and associated **Tasks/Steps**, making it suitable for review and tracking.
</Deliverable>
</PromptRequest>
You would fill in the <Context>
section, potentially using Cursor's @
symbol to reference relevant files or directories directly. The AI then generates implementation_plan.md
, which you review and approve before proceeding. Ensure tag names like <TaskDescription>
, <RelevantCodebase>
are descriptive.
Phase 2: Initialize the State
Create the implementation_state.md
file. It starts simply, pointing to the very first task from the plan.
implementation_state.md
Template:
# Implementation State (STM) - [Fill in Implementation name]
## Overall State
- **Current Phase:** [e.g., Planning, Development - Feature X, Testing]
- **Overall Progress:** Starting implementation. 0 tasks completed.
## Current Task / Next Action
- **Task ID/Description:** [Copy the **FIRST** step/task ID and description from implementation_plan.md here]
- **Status:** Pending
## Completed Items (Log for Context)
*(Append completed task summaries here as they finish)*
- **Task ID**: [Completed Task ID]
- **Action Taken:** [Summary of what AI did]
- **Outcome:** [Success/Failure + brief result]
- **Observations:** [Any relevant notes/details]
---
- (No items completed yet)
## Last Action Summary
- **Task ID:** N/A (Initial state)
- **Action Taken:** None
- **Outcome:** N/A
- **Observations:** N/A
## Errors / Blockers
- **Error Message (if any):** None
- **Blocker Description:** None
- **(If an error/blocker is recorded, await further user instruction)**
Phase 3: Kick Off Execution
Now, you start a new Cursor conversation dedicated to executing the plan. Use a kick-off prompt that embeds the plan and state files. This prompt instructs the AI on how to use the LTM/STM system and execute the plan autonomously.
Example Execution Kick-off Prompt (execute_plan.xml
):
<PromptRequest>
<Goal>
Implement the plan detailed in </Implementation_plan> using the two-file system. Execute tasks sequentially and **continuously** based on the state in </Implementation_state>, updating the state after each successful task. **Only stop if an error occurs or the plan is complete.** Use </Implementation_plan> as read-only Long-Term Memory (LTM) and </Implementation_state> as read/write Short-Term Memory (STM).
</Goal>
<Context>
<Implementation_plan>
{/* @symbol:path/to/implementation_plan.md */}
</Implementation_plan>
<Implementation_state>
{/* @symbol:path/to/implementation_state.md */}
</Implementation_state>
</Context>
<Request>
Please perform the following workflow **continuously until completion or error**:
<Workflow_Instructions>
**Execution Cycle:**
1. **Read STM:** Consult </Implementation_state> to identify the specific task in `## Current Task / Next Action`. If this section indicates completion, stop and report.
2. **Read LTM:** Consult </Implementation_plan> to understand the details for the identified task.
3. **Execute Task:** Perform the actions (create/modify files, run commands, etc.) as required by the task in the LTM.
4. **Handle Errors:** If an error occurs, **STOP** the workflow. Record the error in the STM (`## Errors / Blockers`), update `## Last Action Summary`, and report the halt state. **WAIT** for instructions.
5. **Update STM (on Success):** If successful, meticulously update </Implementation_state> following the `Interaction Protocol`.
6. **Report and Proceed (on Success):** Briefly report task completion (`[Completed Task ID]`) and the *new* current task (`[New Task ID]`). **Immediately proceed** to the next cycle without waiting for confirmation.
</Workflow_Instructions>
<Important_Files>
</Implementation_plan>:
**Role:** Long-Term Memory (Plan). READ-ONLY.
**Constraint:** Do NOT modify. Refer to understand task requirements.
</Implementation_state>:
**Role:** Short-Term Memory (State Tracker). Read/Write.
**Interaction Protocol:**
1. **ALWAYS READ** before acting to find `Current Task / Next Action`.
2. **ALWAYS UPDATE** after success and BEFORE reporting/proceeding. Updates MUST include:
* Update `## Overall State`.
* Log completion under `## Completed Items`.
* Detail action/outcome in `## Last Action Summary`.
* Clear `## Errors / Blockers`.
* Set the **NEXT** task from </Implementation_plan> under `## Current Task / Next Action`. Indicate completion if no tasks remain.
</Important_Files>
</Request>
<Initial_Action>
Carefully read </Implementation_state>. Identify the first task under `## Current Task / Next Action`. Briefly state the task you will perform. **Ask ONLY ONCE for confirmation to begin.** Once confirmed, start the continuous Execution Cycle.
</Initial_Action>
</PromptRequest>
When writing instructions within the XML, consider explicitly referring to context using the defined tags where appropriate (e.g., "Execute the task based on the steps outlined in <ImplementationDetailsPlan>
found in the <Implementation_plan>
file.").
Once you confirm the first step, Cursor will:
- Read
implementation_state.md
to find the current task. - Read
implementation_plan.md
for details on how to do that task. - Attempt the task (e.g., write code, modify a file).
- If successful:
- Update
implementation_state.md
(mark task done, log summary, set next task, clear errors). - Briefly report success and the next task it's starting.
- Repeat the cycle for the new task.
- Update
- If it fails:
- Update
implementation_state.md
(record the error, DO NOT advance the task). - Stop and report the error, waiting for your input.
- Update
Why This Approach Rocks (Benefits & Considerations)
This structured workflow offers significant advantages:
- Consistency & Reliability: Standardized XML prompts and explicit state tracking reduce AI variability and context drift. The explicit structure of XML minimizes ambiguity, especially helpful for complex prompts.
- Improved Context Management: The LTM/STM system provides persistent, relevant context, tackling the LLM statelessness problem. XML helps the model reliably parse different context types.
- Focus & Task Decomposition: AI handles one step at a time based on the plan and state, improving focus for potentially higher-quality output per step.
- Review & Control: Plan review allows human oversight. Explicit state tracking in files offers transparency and control.
- Structured Autonomy: Allows the AI to proceed but stops on errors, balancing automation with necessary human intervention points.
- Provider Alignment: Using XML for structure aligns well with recommendations from major LLM providers like Anthropic and Google for complex tasks.
Important Considerations:
- Manual Overhead: The main challenge is the manual effort required to maintain the
implementation_state.md
file accurately. - Token Cost: XML is more verbose than Markdown, leading to higher token consumption. This is a trade-off for its structural clarity.
- Heuristic Nature: Prompt engineering is empirical. This workflow, while based on sound principles, is a practical approach. Its effectiveness can depend on the specific LLM used (e.g., Claude vs. GPT vs. Gemini) and requires testing and refinement.
Getting Started & Potential Refinements
- Start Simple: Begin with smaller tasks to get comfortable with the flow.
- Refine Templates: Iterate on your XML templates and plan structure. Use meaningful, consistent tag names. Explicitly refer to tagged content in instructions where helpful. You can find the example XML prompt templates discussed in this post, ready to use or adapt, in the StructuredAgentFlowKit GitHub repository.
- Be Clear in Planning: A high-quality, detailed
implementation_plan.md
is crucial. - Leverage Cursor Features:
- @-Mentions: Instead of pasting large chunks of code or documentation into prompts or state files, use Cursor's
@
mentions (@file
,@symbol
). Cursor fetches the latest content dynamically. - Cursor Rules: Consider migrating static, project-wide context (tech stack, core standards) from your plan/XML into Cursor's Rules system (
.cursorrules
,.cursor/rules/*.mdc
). Cursor can then automatically inject this context. This might simplify your static context management within the prompt itself.
- @-Mentions: Instead of pasting large chunks of code or documentation into prompts or state files, use Cursor's
- Explore Alternatives for State: For very long tasks where the state file might grow too large, consider techniques like summarizing older log entries or using prompt chaining for distinct phases.
- Test and Iterate: Since LLM behavior varies, test your workflow with the models available in Cursor and refine based on results.
Wrapping Up
Agentic IDEs like Cursor are incredibly powerful, but maximizing their potential often requires moving beyond simple chat interactions. By implementing a structured workflow using well-defined XML prompts, a clear plan (LTM), and a dynamic state tracker (STM), you can guide the AI more effectively, improve consistency, maintain context, and tackle complex tasks with greater confidence and control. This approach transforms the interaction from a potentially chaotic conversation into a more predictable, traceable, and efficient engineering process, contributing to the practical exploration of effective human-AI collaboration patterns in software development.