Build an AGIMiddleLesson 648 min read

Hands on: the mini-AGI engine

One file, about a hundred lines. It plans, writes code, runs it, reads the error, and fixes itself. Everything above, made real.

Lesson in motion

In 60 seconds

Hands on: the mini-AGI engine

One file, about a hundred lines. It plans, writes code, runs it, reads the error, and fixes itself. Everything above, made real.

1/6
In simple words
We are going to build the loop now. The computer will write a little program, try it, see the mistake, and try again — all by itself.
Install one dependency:
Prerequisitesbash
pip install google-genai
export GEMINI_API_KEY="your-key-here"

Part 1 · the executor

This is the checker from Module 62 — the part that disposes of what the model proposes.
mini_agi.py — the executorpython
import os
import subprocess
import sys
from google import genai
from google.genai import types

client = genai.Client()   # reads GEMINI_API_KEY from the environment


def run_python_code(code_string):
    """Execute python code in a child process and return output or error."""
    filename = "temp_agent_sandbox.py"
    with open(filename, "w") as f:
        f.write(code_string)

    try:
        result = subprocess.run(
            [sys.executable, filename],
            capture_output=True,
            text=True,
            timeout=10,           # a runaway loop must not hang the agent
        )
        if result.returncode != 0:
            return f"EXECUTION ERROR:\n{result.stderr}"
        return f"SUCCESS OUTPUT:\n{result.stdout}"
    except Exception as e:
        return f"SYSTEM EXCEPTION: {str(e)}"
    finally:
        if os.path.exists(filename):
            os.remove(filename)
Watch out
Read the name of that function honestly. temp_agent_sandbox.py is not a sandbox. A subprocess protects the parent process from a crash; it does not protect your machine from the code. That child process has your filesystem, your network and your environment variables. It is fine for a tutorial on your own laptop with a goal you wrote. It is not fine for anything else — Module 66 replaces it properly.

Part 2 · the cognitive loop

mini_agi.py — the looppython
def agi_cognitive_loop(goal: str, max_iterations: int = 3):
    """Plan -> execute -> evaluate -> self-correct -> achieve goal."""
    print(f"\n[AGI Goal Initialized]: {goal}\n" + "=" * 40)

    system_prompt = (
        "You are an autonomous AGI reasoning agent. Your job is to achieve the "
        "user's goal by writing Python code blocks. Respond in two parts:\n"
        "1. THOUGHT: explain your step-by-step logic.\n"
        "2. CODE: enclosed in a python fenced block, containing executable code "
        "that solves or tests the step.\n"
        "If a previous step failed, analyse the error output and write "
        "corrected code."
    )

    # Working memory: the growing record of what has been tried.
    conversation_history = f"Goal: {goal}"

    for iteration in range(1, max_iterations + 1):
        print(f"\n--- [Iteration {iteration} of {max_iterations}] ---")

        # DECIDE
        response = client.models.generate_content(
            model="gemini-2.5-flash",
            contents=conversation_history,
            config=types.GenerateContentConfig(
                system_instruction=system_prompt,
                temperature=0.2,   # low temperature: strict logical adherence
            ),
        )
        model_output = response.text
        print(f"Agent thought and plan:\n{model_output}\n")

        fence = chr(96) * 3 + "python"      # the python code fence marker
        if fence not in model_output:
            print("No executable code block found this turn.")
            conversation_history += (
                f"\n\nIteration {iteration}: no code provided. "
                "Write code to test your logic."
            )
            continue

        # ACT
        code_block = model_output.split(fence)[1].split(chr(96) * 3)[0].strip()
        print("Executing agent-generated code...")
        execution_result = run_python_code(code_block)
        print(execution_result)

        # OBSERVE — the result becomes context for the next decision
        conversation_history += (
            f"\n\nIteration {iteration} code output:\n{execution_result}"
        )

        if "SUCCESS OUTPUT" in execution_result:
            print("\n[AGI Status]: goal reached and verified via execution.")
            return

    print("\n[AGI Status]: max iterations reached without closure.")


if __name__ == "__main__":
    goal = (
        "Write a python script that calculates the first 10 numbers of the "
        "Fibonacci sequence, verifies mathematically that each number is the "
        "sum of the two preceding ones, and prints 'VERIFICATION PASSED'."
    )
    agi_cognitive_loop(goal)

Two things to fix before you run it

  1. 1

    The comment marker

    Python comments start with #, not //. A line like temperature=0.2 // Low temperature is a syntax error — Python reads // as floor division and then chokes on the words. Fixed above.
  2. 2

    Extracting the code fence

    Writing the three-backtick marker inside a Python string is awkward and easy to get wrong. chr(96) * 3 builds it without any escaping trouble, which is why the version above does that.

Run it

What you should seetext
[AGI Goal Initialized]: Write a python script that calculates...
========================================

--- [Iteration 1 of 3] ---
Agent thought and plan:
THOUGHT: I will generate the sequence iteratively, then assert the
recurrence relation for every element from index 2 onward...

Executing agent-generated code...
SUCCESS OUTPUT:
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
VERIFICATION PASSED

[AGI Status]: goal reached and verified via execution.
Do this
Now do the thing that actually teaches you something: give it a goal it will get wrong on the first try. "Parse this malformed CSV and report the average of column three." Watch it fail, read the traceback, and fix itself in iteration two. That moment — the machine reading its own error and correcting — is the whole of this track in ten seconds.
Danger
And before you point it at anything real: this loop can write and run any Python. Keep the goal yours, keep the machine yours, and read Module 66 first. The gap between this tutorial and a production system is entirely in the executor.

Watch and read more

Lab

The mini-AGI engine, running and self-correcting.

~30 min

The problem

Build the engine from Module 64. Give it a goal it will fail on the first attempt and watch it read the traceback and fix itself. Then give it an impossible goal and watch it exhaust its iterations.
Starter codepython
goal = ("Parse this malformed CSV and print the mean of column 3. "
        "Some rows have missing fields and one has a stray quote.")

You are done when

Hard questions

Try to answer before you reveal. If you can answer these, you understood the lesson.

Q1Your agent fixed the error but the fix was to wrap everything in try/except and print nothing. It exited 0. What failed?Reveal
The verifier, not the model. Exit code 0 was your entire success condition, and suppressing the error satisfies it perfectly — the model did what you rewarded. This is Module 65 in one line: a goal check that inspects the output for the required numbers would have rejected it and produced a useful failure reason for the next iteration.

Please sign in to continue.

Questions people ask

Why temperature 0.2?

Low temperature makes the model pick high-probability tokens, which for code means conventional, syntactically safe constructions. Creativity is a liability here — you want the boring solution that runs.

Why does the whole history get resent every turn?

Because the model has no memory (Module 5). The growing conversation_history string is the working memory. It is also why this design eventually hits the context limit — Module 67 fixes that.

Can I use a different model?

Yes. Swap the client for any provider with a completion API. The architecture is provider-agnostic, which is the point: the intelligence is in the loop, not the vendor.

Three iterations seems low.

It is a sensible default. Success rates drop sharply after the third attempt — a model that has failed three times is usually committed to a wrong approach rather than closing in on a right one. Raise it if you like, but add a spend cap alongside.

Lesson test

5 questions. Get 3 right (60%) to pass and complete this lesson.

Sign in with your phone number to take the test and save your progress