# Architecture of the Code Generation Pipeline in GPT-Engineer's Steps Module

> Explore the GPT-Engineer steps module architecture. Discover its linear pipeline for prompt preparation, code generation, execution, and iteration, transforming prompts into code with FilesDict.

- Repository: [Anton Osika/gpt-engineer](https://github.com/AntonOsika/gpt-engineer)
- Tags: architecture
- Published: 2026-03-06

---

**The GPT-Engineer steps module implements a linear pipeline of discrete, composable functions—prompt preparation, code generation, entrypoint creation, sandboxed execution, and iterative improvement—that transform user prompts into executable codebases through a shared `FilesDict` abstraction.**

The `gpt_engineer.core.default.steps` module serves as the central orchestration layer for AI-driven software generation in the GPT-Engineer repository. Understanding the architecture of the code generation pipeline in the steps module reveals how raw natural language prompts evolve into structured, runnable projects through deterministic transformations that leverage shared abstractions like `FilesDict` and `BaseMemory`.

## Core Pipeline Stages

The architecture follows a functional, stateless design where each step accepts an AI interface, memory store, and `FilesDict`, then returns a modified `FilesDict`. This pattern enables easy testing, debugging, and reordering of individual stages without side effects.

### Prompt Preparation with setup_sys_prompt

Before generation begins, the pipeline constructs specialized system prompts using `setup_sys_prompt` and `setup_sys_prompt_existing_code` (lines 75-118 in [`gpt_engineer/core/default/steps.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/default/steps.py)). These functions retrieve roadmap, philosophy, and template preprompts from a `PrepromptsHolder`, assembling the contextual foundation that guides the LLM's behavior.

- **Generation mode**: `setup_sys_prompt` (lines 75-95) assembles prompts for greenfield projects.
- **Improvement mode**: `setup_sys_prompt_existing_code` (lines 97-118) incorporates existing codebase context for refinement tasks.

### Code Generation via gen_code

The `gen_code` function (lines 121-151) executes the primary synthesis phase. This step retrieves the system prompt via `setup_sys_prompt`, invokes `ai.start` with the system prompt and user content from `Prompt.to_langchain_content()`, and parses the LLM response through `chat_to_files_dict` to extract a `FilesDict` containing all generated files. The complete conversation logs to `CODE_GEN_LOG_FILE` for auditability.

### Entrypoint Generation with gen_entrypoint

After code generation, `gen_entrypoint` (lines 153-203) creates execution scaffolding. This function generates a bash script stored as `ENTRYPOINT_FILE` that handles dependency installation and project execution. The implementation uses a fallback script description if the user provides no custom prompt, calls `ai.start` with the entrypoint preprompt and current codebase serialized via `files_dict.to_chat()`, and extracts code blocks using regex `r"```\S*\n(.+?)```"`. The exchange logs to `ENTRYPOINT_LOG_FILE`.

### Sandbox Execution via execute_entrypoint

The `execute_entrypoint` function (lines 205-269) handles safe execution of generated projects. This step validates the presence of `ENTRYPOINT_FILE`, requests user confirmation, then delegates to a `BaseExecutionEnv` implementation (such as Docker) to run `bash entrypoint.sh`. Notably, this step returns the unmodified `FilesDict`, maintaining the pipeline's stateless nature while isolating execution side effects from the generation state.

### Iterative Improvement Loop

The improvement architecture implements a robust validation and retry mechanism through three coordinated functions in [`gpt_engineer/core/default/steps.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/default/steps.py):

**improve_fn** (lines 271-313) initializes the refinement context using `setup_sys_prompt_existing_code`, packages the current codebase via `files_dict.to_chat()`, and initiates the improvement conversation with the LLM.

**_improve_loop** (lines 315-339) implements the retry logic, repeatedly invoking `ai.next` and `salvage_correct_hunks` until all diffs validate successfully or the process reaches `MAX_EDIT_REFINEMENT_STEPS` (defined in [`gpt_engineer/core/default/constants.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/default/constants.py)).

**salvage_correct_hunks** (lines 341-361) parses diff output via `parse_diffs` from [`gpt_engineer/core/chat_to_files.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/chat_to_files.py), validates each hunk against current file state using `diff.validate_and_correct`, applies valid changes, and logs errors for invalid hunks to feed back into the correction loop.

## Shared Abstractions and Data Flow

The pipeline relies on several critical abstractions that decouple the architecture from specific LLM implementations:

- **FilesDict**: A dictionary-like container (defined in [`gpt_engineer/core/files_dict.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/files_dict.py)) that flows through every step, mapping filenames to source content and enabling stateless function composition.
- **BaseMemory**: The logging interface (from [`gpt_engineer/core/base_memory.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/base_memory.py)) that persists conversations and intermediate states for traceability.
- **PrepromptsHolder**: Manages static system prompt templates located in [`gpt_engineer/core/preprompts_holder.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/preprompts_holder.py).
- **chat_to_files_dict**: Parses LLM markdown responses into structured files, implemented in [`gpt_engineer/core/chat_to_files.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/chat_to_files.py).

## Practical Pipeline Implementation

Below is a complete example demonstrating how to compose these steps into a working generation pipeline:

```python
from gpt_engineer.core.default.steps import (
    gen_code,
    gen_entrypoint,
    execute_entrypoint,
    improve_fn
)
from gpt_engineer.core.ai import AI
from gpt_engineer.core.files_dict import FilesDict
from gpt_engineer.core.default.base_memory import BaseMemory
from gpt_engineer.core.preprompts_holder import PrepromptsHolder

# Initialize core components

ai = AI()
memory = BaseMemory()
preprompts = PrepromptsHolder()

# Step 1: Generate initial codebase from description

files = gen_code(ai, user_prompt, memory, preprompts)

# Step 2: Create execution entrypoint

entrypoint_files = gen_entrypoint(ai, user_prompt, files, memory, preprompts)
files.update(entrypoint_files)

# Step 3: Execute in sandboxed environment (optional)

execute_entrypoint(ai, docker_env, files)

# Step 4: Iterative refinement based on new requirements

final_files = improve_fn(ai, improvement_prompt, files, memory, preprompts)

```

## Summary

- The **architecture of the code generation pipeline in the steps module** follows a functional, composable design where discrete steps transform a `FilesDict` through generation, entrypoint creation, execution, and improvement phases.
- Each function in [`gpt_engineer/core/default/steps.py`](https://github.com/AntonOsika/gpt-engineer/blob/main/gpt_engineer/core/default/steps.py) maintains statelessness by accepting and returning `FilesDict` instances, enabling flexible pipeline construction and unit testing.
- The **improvement loop** implements robust validation through `salvage_correct_hunks` and `_improve_loop`, using `MAX_EDIT_REFINEMENT_STEPS` to ensure code modifications are syntactically correct before application.
- Shared abstractions including `FilesDict`, `BaseMemory`, and `PrepromptsHolder` decouple the pipeline from specific LLM providers, allowing the architecture to support multiple AI backends and execution environments.

## Frequently Asked Questions

### What is the primary function of the steps module in GPT-Engineer?

The steps module serves as the central orchestration layer that coordinates the entire AI-driven code generation workflow. It transforms natural language prompts into executable codebases through a linear pipeline of discrete functions handling prompt preparation, code synthesis, entrypoint generation, sandboxed execution, and iterative refinement.

### How does the improve_fn function handle invalid code modifications?

The `improve_fn` function implements a validation and retry mechanism through its helper functions `_improve_loop` and `salvage_correct_hunks`. When the LLM returns diffs, each hunk is validated against the current file state using `diff.validate_and_correct`; invalid hunks are logged and fed back to the model for correction. This loop continues until all changes are valid or the process reaches `MAX_EDIT_REFINEMENT_STEPS`.

### What is the role of FilesDict in the code generation pipeline?

`FilesDict` is the central data structure that enables stateless function composition throughout the pipeline. Acting as a dictionary-like container mapping filenames to source content, it flows through every step from `gen_code` to `improve_fn`, allowing each function to receive the complete codebase, apply transformations, and return the modified state without side effects.

### Can individual pipeline steps be executed independently?

Yes, the architecture explicitly supports independent execution and custom sequencing of individual steps. Because each function is stateless and accepts standardized inputs (AI interface, memory, preprompts, and `FilesDict`), developers can skip entrypoint generation, insert custom processing between stages, or run only the improvement loop on existing codebases without executing the full generation pipeline.