Advanced Autogpt 3 min read

AutoGPT Forge: Build Custom Agents from Scratch

#autogpt #forge #custom-agents #python #sdk #agent-protocol

What Is AutoGPT Forge?

AutoGPT Forge is the developer SDK within the AutoGPT project for building custom agents. While the main AutoGPT interface runs a pre-built agent, Forge lets you:

  • Build agents with custom capabilities and behaviors
  • Implement the Agent Protocol — a standardized REST API spec
  • Create specialized agents (coding, research, data analysis) from a clean template
  • Share and benchmark agents against others

Forge is for developers who want full control over agent logic rather than just running AutoGPT as a user.

Agent Protocol

AutoGPT agents implement the Agent Protocol — an open standard for AI agent communication:

POST /ap/v1/agent/tasks           → Create a new task
GET  /ap/v1/agent/tasks/{task_id} → Get task details
POST /ap/v1/agent/tasks/{task_id}/steps → Execute a step
GET  /ap/v1/agent/tasks/{task_id}/artifacts → List artifacts

Any Forge agent can be connected to any Agent Protocol-compatible frontend. This standardization means you can swap frontends and backends independently.

Setting Up Forge

# Clone AutoGPT repo
git clone https://github.com/Significant-Gravitas/AutoGPT.git
cd AutoGPT

# Navigate to Forge
cd autogpts/forge

# Install dependencies
poetry install

# Copy environment file
cp .env.template .env
# Edit .env — add OPENAI_API_KEY

Project Structure

forge/
├── forge/
│   ├── agent.py          ← Your agent logic lives here
│   ├── prompts/          ← System prompts
│   ├── abilities/        ← Custom capabilities
│   │   ├── registry.py   ← Registers abilities
│   │   └── file_system/  ← Built-in file abilities
│   └── sdk/              ← Forge SDK (don't modify)
│       ├── agent.py      ← Base agent class
│       ├── memory/       ← Memory backends
│       └── workspace.py  ← Sandboxed file workspace
└── tests/

Your Agent Class

The core of a Forge agent is a class inheriting from Agent:

# forge/forge/agent.py
from forge.sdk import Agent, AgentDB, Step, StepRequestBody, Task, TaskRequestBody, Workspace

class ForgeAgent(Agent):

    async def create_task(self, task_request: TaskRequestBody) -> Task:
        """Called when a new task is created via POST /ap/v1/agent/tasks"""
        task = await self.db.create_task(
            input=task_request.input,
            additional_input=task_request.additional_input,
        )
        return task

    async def execute_step(self, task_id: str, step_request: StepRequestBody) -> Step:
        """Called on each step — this is where your agent logic runs"""

        # Get task context
        task = await self.db.get_task(task_id)
        steps = await self.db.list_steps(task_id)

        # Your agent logic here
        output = await self._run_agent_step(task, steps, step_request)

        # Create and return the step
        step = await self.db.create_step(
            task_id=task_id,
            input=step_request,
            is_last=output.get("is_done", False),
        )
        step.output = output.get("response", "")
        await self.db.update_step(task_id, step.step_id, "completed", step)
        return step

    async def _run_agent_step(self, task, steps, step_request) -> dict:
        """Implement your custom agent reasoning here."""
        # Use the Forge SDK's built-in chat model
        messages = [
            {"role": "system", "content": "You are a helpful agent. Complete tasks step by step."},
            {"role": "user", "content": task.input},
        ]

        # Add step history for context
        for step in steps[-5:]:  # last 5 steps
            if step.output:
                messages.append({"role": "assistant", "content": step.output})

        response = await self.openai_client.chat.completions.create(
            model="gpt-4o-mini",
            messages=messages,
        )

        answer = response.choices[0].message.content
        is_done = "TASK_COMPLETE" in answer

        return {"response": answer, "is_done": is_done}

Custom Abilities

Abilities are tools your agent can use. Forge has a built-in ability registry:

# forge/forge/abilities/web_search.py
from forge.sdk.abilities.registry import ability

@ability(
    name="web_search",
    description="Search the web for current information.",
    parameters=[
        {
            "name": "query",
            "description": "The search query",
            "type": "string",
            "required": True,
        }
    ],
    output_type="string",
)
async def web_search(agent, task_id: str, query: str) -> str:
    """Search the web and return results."""
    import httpx
    async with httpx.AsyncClient() as client:
        response = await client.get(
            "https://api.duckduckgo.com/",
            params={"q": query, "format": "json"},
        )
        data = response.json()
        results = data.get("RelatedTopics", [])[:5]
        return "\n".join([r.get("Text", "") for r in results if "Text" in r])

Register abilities in your agent:

# In ForgeAgent.__init__ or create_task
from forge.forge.abilities.web_search import web_search
from forge.sdk.abilities.registry import AbilityRegistry

self.abilities = AbilityRegistry()
self.abilities.register_ability(web_search)

Use abilities in execute_step:

async def _run_agent_step(self, task, steps, step_request) -> dict:
    # Get available abilities
    abilities_description = self.abilities.list_abilities_for_prompt()

    messages = [
        {
            "role": "system",
            "content": f"""You are an agent with these abilities:
{abilities_description}

To use an ability, respond with:
ABILITY: ability_name
PARAMS: {{"param": "value"}}

When done, respond with:
TASK_COMPLETE: <final answer>"""
        },
        {"role": "user", "content": task.input},
    ]

    response = await self.openai_client.chat.completions.create(
        model="gpt-4o-mini",
        messages=messages,
    )
    answer = response.choices[0].message.content

    # Parse and execute ability if requested
    if answer.startswith("ABILITY:"):
        lines = answer.split("\n")
        ability_name = lines[0].replace("ABILITY:", "").strip()
        params_line = lines[1].replace("PARAMS:", "").strip()
        import json
        params = json.loads(params_line)

        result = await self.abilities.run_ability(
            agent=self,
            task_id=task.task_id,
            ability_name=ability_name,
            **params,
        )
        return {"response": f"Ability result: {result}", "is_done": False}

    is_done = "TASK_COMPLETE" in answer
    return {"response": answer, "is_done": is_done}

Built-In Abilities

Forge ships with several pre-built abilities:

AbilityDescription
read_fileRead files from the workspace
write_fileWrite files to the workspace
list_filesList files in the workspace
query_language_modelAsk the LLM a sub-question

All file operations use a sandboxed workspace — agents cannot access files outside their designated directory.

Running Your Agent

# Start the Forge server
poetry run python -m forge.app

# Server runs at http://localhost:8000
# API docs at http://localhost:8000/docs

Test via CLI:

# Create a task
curl -X POST http://localhost:8000/ap/v1/agent/tasks \
  -H "Content-Type: application/json" \
  -d '{"input": "Write a Python script that prints the Fibonacci sequence"}'

# Execute a step
curl -X POST http://localhost:8000/ap/v1/agent/tasks/{task_id}/steps \
  -H "Content-Type: application/json" \
  -d '{}'

Test via AutoGPT frontend:

# From the AutoGPT root
cd frontend
npm install && npm run dev
# Frontend connects to your Forge agent at localhost:8000

Benchmarking with AgentEval

Forge includes integration with the AutoGPT Benchmark (agbenchmark):

# Install benchmark
pip install agbenchmark

# Run against your agent
agbenchmark run --url http://localhost:8000

# Results show pass/fail rates across task categories:
# - Coding
# - Data analysis
# - Web browsing
# - File operations

Use benchmarks to compare your custom agent against baseline implementations.

Frequently Asked Questions

Do I need to use OpenAI with Forge?

No. The openai_client is a convenience wrapper. You can use any LLM SDK — Anthropic, Mistral, Ollama — by calling the SDK directly in your _run_agent_step implementation.

How is Forge different from LangChain agents?

Forge provides the infrastructure (server, database, workspace, protocol) for hosting an agent as a service. LangChain provides reasoning and tool-use primitives. You can use LangChain’s agent reasoning inside a Forge agent — they are complementary.

Can multiple frontends connect to one Forge agent?

Yes — the Agent Protocol REST API is stateless and can handle multiple concurrent tasks. Each task has its own isolated context and workspace.

How do I persist agent memory across tasks?

Use the AgentDB instance (available as self.db) to store and retrieve custom data. For vector-based memory, integrate a vector store like Chroma or Pinecone and query it at the start of each step.

Is Forge production-ready?

Forge is mature enough for internal tools and prototypes. For customer-facing production use, add authentication, rate limiting, and proper error handling on top of the Agent Protocol server.

Next Steps

Related Articles