Build a Basic AI Agent from Scratch: Long Task Planning

ruxudev1 pts0 comments

Build A Basic AI Agent From Scratch: Long Task Planning

08 Jun 2026<br>Build A Basic AI Agent From Scratch: Long Task Planning

52 minute read<br>Artificial Intelligence

In the previous part of the Build A Basic AI Agent From Scratch series, we added the essential tools to our agent to allow it to work autonomously for us. We gave it the ability to find files, read and write files, run bash commands and get content from the web. We got a very capable agent with just these tools.

What happens when the agent runs long and complex tasks?

The current agent works very well, but we want our agent to get a lot of work done, and this requires staying on the task for long spans of time. Right now, if we try to give our agent long and complex tasks we will find that it does not think long term, and it stops working after the littlest progress.

This is to be expected because the LLM is trained to behave conversationally. It expects to go back and forth in a question-answer basis. This is fine for a simple chatbot, but our agent needs to be able to get a request and work for a long time on it before returning a result.

Long task planning

The next ability we will give to our agent is the ability to plan for long and complex tasks.

The abilities our agent needs are:

Understand the goal of the task

Plan how to tackle the task beforehand

Break the task into concrete steps

Keep track of pending, in progress and completed tasks

If something goes wrong with the current plan, rethink the approach

Check that everything planned is actually done before stopping

To give our agent these abilities, we will rely on the last part's addition: tools . We will also explain the model how to use long task planning in the model's system prompt .

New tool: Scratchpad

This is a very simple but powerful tool. We are just giving the model a place to write it's thoughts and read them again at a later time.

The main benefit of this tool is that it forces the model to think through the goal and plan the whole approach before starting working on it.

The tool saves the scratchpad content into memory instead of a file or database, which is fine because we don't want to share the scratchpad content between sessions.

Here's the python implementation:

class Scratchpad:<br>"""Read and write from a in-memory scratchpad"""

def __init__(self):<br>self._content = ""

def read(self) -> str:<br>if self._content == "":<br>return "(empty)"<br>return self._content

def write(self, content: str) -> str:<br>self._content = str(content).strip()<br>return self._content

scratchpad = Scratchpad()

def read_scratchpad():<br>"""Read the contents of the scratchpad"""<br>return scratchpad.read()

def write_scratchpad(content: str):<br>"""<br>Write into the scratchpad. The previous content<br>will be overwritten.<br>"""<br>scratchpad.write(content)<br>return "Successfully written content into scratchpad"

> You can find and clone this code in this blog series' a href="https://github.com/rogiia/basic-agent-harness" target="_blank">Github repo/a>.

New tool: To-do list

A to-do list allows the agent to decompose the work into tasks and keep track of them to know what's left to do (pending), what it's working on currently (in progress) and what is already done (done).

This tool also enforces some good practices: it doesn't allow multiple tasks to be in progress at the same time, it doesn't allow invalid task statuses and it doesn't allow repeated tasks.

Just like the scratchpad, this tool saves the to do list into memory instead of a file or database. This is also fine because we don't want to share the to-do list between agent sessions.

RETRY_LIMIT = 3

class ToDoList:<br>"""Helper class to hold a to-do list in memory"""

statuses = ["pending", "in_progress", "done", "cancelled", "failed"]

def __init__(self):<br>self._items = []

def read(self, include_completed=False):<br>"""Read the to-do list"""<br>if include_completed:<br>return [item.copy() for item in self._items]<br>else:<br>return [item.copy() for item in self._items<br>if item["status"] != "done" and item["status"] != "cancelled"]

def append(self, id, content, status):<br>if status not in ToDoList.statuses:<br>raise Exception(f"Invalid status {status}. "<br>"Valid to-do statuses: pending, in_progress, done, "<br>"cancelled, failed")<br>if self.contains(id):<br>raise Exception(f"To do item {id} already exists!")<br>new_item = {"id": id, "content": content,<br>"status": status, "retries": 0}<br>self._items.append(new_item)<br>return new_item.copy()

def contains(self, id) -> bool:<br>"""Check if the to do list contains an item with a specific id"""<br>for item in self._items:<br>if item["id"] == id:<br>return True<br>return False

def update(self, id, content, status):<br>if status is not None and status not in ToDoList.statuses:<br>raise Exception(f"Invalid status {status}. "<br>"Valid to-do statuses: pending, in_progress, done, "<br>"cancelled, failed")<br>idx = 0<br>while idx len(self._items):<br>if self._items[idx]["id"] == id:<br>if content is not None:<br>self._items[idx]["content"] = content<br>if status is not None:<br>prev_status...

self agent content status scratchpad long

Related Articles