Skip to content

Eigene AI Coding Agents bauen

Eigene AI Coding Agents bauen: Von einfachen Scripts bis zu autonomen Multi-Step Agents. MCP, Tool Use, LangChain, Vercel AI SDK und Custom Agents für Entwickler.

Einleitung

AI Coding Agents sind die nächste Evolutionsstufe: Statt einzelne Prompts zu schreiben, baust du Systeme, die autonom Code schreiben, testen und deployen. In diesem Artikel zeige ich dir, wie du eigene AI Coding Agents baust – von einfachen Scripts bis zu Multi-Step Agents mit Tool Use.


Inhaltsverzeichnis

  1. Was sind AI Coding Agents?
  2. Agent-Architektur verstehen
  3. Einen einfachen Agent bauen
  4. Tool Use: Agents mit Werkzeugen
  5. MCP (Model Context Protocol)
  6. Multi-Step Agent mit Planung
  7. Code-Generierungs-Agent
  8. Test-Agent: Automatisch Tests schreiben
  9. Code Review Agent
  10. Frameworks & SDKs
  11. Agents in Production
  12. FAQ

Was sind AI Coding Agents?

Allerdings gibt es einige wichtige Unterschiede zu beachten.

Ein AI Agent ist ein System, das:

  1. Wahrnimmt: Liest Code, Fehlermeldungen, Spezifikationen
  2. Plant: Zerlegt eine Aufgabe in Schritte
  3. Handelt: Schreibt Code, führt Tests aus, erstellt Dateien
  4. Reflektiert: Prüft Ergebnisse und korrigiert sich selbst

Der Unterschied zu einem einfachen Prompt: Agents arbeiten in einer Schleife (Observe → Plan → Act → Reflect) und können Tools nutzen (Dateisystem, Terminal, APIs).

Bekannte Beispiele: Cline, Cursor Composer, Devin, OpenHands, SWE-Agent, GitHub Copilot Agent Mode.


Agent-Architektur verstehen

Ebenso wichtig ist es, die Best Practices zu kennen.

Jeder AI Agent besteht aus diesen Komponenten:

┌─────────────────────────────────────────┐
│              AI Agent                    │
│                                         │
│  ┌──────────┐    ┌──────────────────┐  │
│  │  LLM     │    │  System Prompt   │  │
│  │ (Claude, │    │  (Rolle, Regeln, │  │
│  │  GPT-4)  │    │   Kontext)       │  │
│  └────┬─────┘    └──────────────────┘  │
│       │                                 │
│  ┌────▼─────────────────────────────┐  │
│  │         Agent Loop               │  │
│  │  1. Observe (Input lesen)        │  │
│  │  2. Think  (Nächsten Schritt)    │  │
│  │  3. Act    (Tool aufrufen)       │  │
│  │  4. Reflect (Ergebnis prüfen)    │  │
│  └────┬─────────────────────────────┘  │
│       │                                 │
│  ┌────▼─────────────────────────────┐  │
│  │         Tools                     │  │
│  │  • Dateien lesen/schreiben       │  │
│  │  • Terminal-Befehle ausführen    │  │
│  │  • Web-Suche                     │  │
│  │  • API-Aufrufe                   │  │
│  │  • Datenbank-Queries             │  │
│  └──────────────────────────────────┘  │
└─────────────────────────────────────────┘

Deshalb empfiehlt es sich, den Prompt schrittweise zu verfeinern.


Einen einfachen Agent bauen

Zusammenfassend lässt sich sagen, dass dies ein zentraler Aspekt ist.

Starten wir mit dem einfachsten Agent: Ein Script das iterativ Code verbessert.

// simple-agent.ts - Minimaler AI Agent mit Vercel AI SDK
import { generateText } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
import { readFileSync, writeFileSync } from 'fs';

async function improveCode(filePath: string, instruction: string) {
  const code = readFileSync(filePath, 'utf-8');
  
  const { text } = await generateText({
    model: anthropic('claude-sonnet-4-20250514'),
    system: `Du bist ein Senior TypeScript Developer.
             Gib NUR den verbesserten Code zurück, keine Erklärungen.`,
    prompt: `Verbessere diesen Code:
    
Anweisung: ${instruction}

Code:
\`\`\`typescript
${code}
\`\`\``,
  });

  // Extrahiere Code aus der Antwort
  const codeMatch = text.match(/```typescript\n([\s\S]*?)```/);
  if (codeMatch) {
    writeFileSync(filePath, codeMatch[1].trim());
    console.log(`✅ ${filePath} wurde verbessert.`);
  }
}

// Verwendung
improveCode('./src/utils.ts', 'Füge TypeScript Typen und Error Handling hinzu');

Weiterhin ist es ratsam, die Ergebnisse immer kritisch zu prüfen.


Tool Use: Agents mit Werkzeugen

Natürlich gibt es dabei verschiedene Herangehensweisen.

Echte Agents brauchen Tools. Das LLM entscheidet dynamisch welches Tool es aufruft:

// agent-with-tools.ts - Agent mit Tool Use
import { generateText, tool } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
import { z } from 'zod';
import { execSync } from 'child_process';
import { readFileSync, writeFileSync, existsSync } from 'fs';

const codingAgent = async (task: string) => {
  const { text, toolCalls } = await generateText({
    model: anthropic('claude-sonnet-4-20250514'),
    system: `Du bist ein AI Coding Agent. Du hast Zugriff auf Tools 
             um Dateien zu lesen, zu schreiben und Befehle auszuführen.
             Löse die Aufgabe Schritt für Schritt.`,
    prompt: task,
    maxSteps: 10, // Max 10 Tool-Aufrufe
    tools: {
      readFile: tool({
        description: 'Liest den Inhalt einer Datei',
        parameters: z.object({
          path: z.string().describe('Dateipfad'),
        }),
        execute: async ({ path }) => {
          if (!existsSync(path)) return `Datei ${path} nicht gefunden`;
          return readFileSync(path, 'utf-8');
        },
      }),
      writeFile: tool({
        description: 'Schreibt Inhalt in eine Datei',
        parameters: z.object({
          path: z.string().describe('Dateipfad'),
          content: z.string().describe('Dateiinhalt'),
        }),
        execute: async ({ path, content }) => {
          writeFileSync(path, content);
          return `Datei ${path} geschrieben.`;
        },
      }),
      runCommand: tool({
        description: 'Führt einen Terminal-Befehl aus',
        parameters: z.object({
          command: z.string().describe('Shell-Befehl'),
        }),
        execute: async ({ command }) => {
          try {
            return execSync(command, { encoding: 'utf-8' });
          } catch (e: any) {
            return `Fehler: ${e.stderr || e.message}`;
          }
        },
      }),
    },
  });

  console.log('Agent Ergebnis:', text);
};

// Verwendung
codingAgent('Erstelle eine TypeScript Utility-Funktion für E-Mail-Validierung in src/utils/validate-email.ts mit Unit Tests in src/__tests__/validate-email.test.ts. Führe die Tests aus und fixe Fehler.');

Dabei zeigt dieses Beispiel den grundlegenden Ansatz.


MCP (Model Context Protocol)

Tatsächlich ist dieser Bereich besonders wichtig für Entwickler.

MCP ist der Standard von Anthropic für Tool-Integration. Statt Tools im Code zu definieren, verbindest du externe MCP-Server:

// MCP Server-Beispiel: Dein eigener Code-Analyse Server
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';

const server = new McpServer({
  name: 'code-analyzer',
  version: '1.0.0',
});

// Tool 1: Code-Komplexität analysieren
server.tool(
  'analyzeComplexity',
  'Analysiert die zyklomatische Komplexität einer Datei',
  { filePath: z.string() },
  async ({ filePath }) => {
    // Complexity-Analyse implementieren
    const complexity = await calculateComplexity(filePath);
    return {
      content: [{
        type: 'text',
        text: JSON.stringify(complexity, null, 2)
      }]
    };
  }
);

// Tool 2: Projekt-Struktur analysieren
server.tool(
  'getProjectStructure',
  'Gibt die Projektstruktur als Baum zurück',
  { rootDir: z.string() },
  async ({ rootDir }) => {
    const tree = await generateTreeStructure(rootDir);
    return {
      content: [{ type: 'text', text: tree }]
    };
  }
);

// Server starten
const transport = new StdioServerTransport();
await server.connect(transport);

MCP-Server sind wiederverwendbar: Einmal bauen, in Cursor, Cline, Claude Desktop und eigenen Agents nutzen.


Multi-Step Agent mit Planung

Dennoch solltest du einige Besonderheiten beachten.

// Fortgeschrittener Agent: Plant vor dem Handeln
import { generateObject, generateText, tool } from 'ai';
import { anthropic } from '@ai-sdk/anthropic';
import { z } from 'zod';

// Schritt 1: Plan erstellen
async function createPlan(task: string) {
  const { object: plan } = await generateObject({
    model: anthropic('claude-sonnet-4-20250514'),
    schema: z.object({
      steps: z.array(z.object({
        id: z.number(),
        description: z.string(),
        type: z.enum(['read', 'write', 'execute', 'analyze']),
        dependencies: z.array(z.number()),
      })),
    }),
    prompt: `Erstelle einen Schritt-für-Schritt Plan für: ${task}`,
  });
  return plan;
}

// Schritt 2: Plan ausführen
async function executePlan(plan: any) {
  const results = new Map();
  
  for (const step of plan.steps) {
    console.log(`\n📋 Schritt ${step.id}: ${step.description}`);
    
    // Sammle Ergebnisse abhängiger Schritte
    const context = step.dependencies
      .map((dep: number) => results.get(dep))
      .filter(Boolean)
      .join('\n---\n');
    
    const result = await generateText({
      model: anthropic('claude-sonnet-4-20250514'),
      prompt: `Führe diesen Schritt aus: ${step.description}
               Kontext aus vorherigen Schritten: ${context}`,
      tools: { /* ... Tools wie oben ... */ },
      maxSteps: 5,
    });
    
    results.set(step.id, result.text);
    console.log(`✅ Schritt ${step.id} abgeschlossen`);
  }
  
  return results;
}

// Verwendung
const plan = await createPlan(
  'Erstelle eine REST API für ein Todo-App Backend mit Express, TypeScript, Prisma und Tests'
);
console.log('Plan:', JSON.stringify(plan, null, 2));
await executePlan(plan);

Grundsätzlich kannst du diesen Prompt an deine Bedürfnisse anpassen.


Code-Generierungs-Agent

Weiterhin ist es wichtig, die Grundlagen zu verstehen.

// Spezialisierter Agent: Generiert Code aus Spezifikationen

Prompt für den Agent (System Prompt):

Du bist ein Code-Generierungs-Agent. Du erhältst eine Feature-Spezifikation 
und erstellst den kompletten Code.

Workflow:
1. ANALYSE: Lies die Spezifikation und bestimme welche Dateien erstellt werden
2. PLAN: Erstelle die Datei-Liste mit Abhängigkeiten
3. TYPES: Erstelle zuerst die TypeScript Types/Interfaces
4. IMPLEMENTATION: Implementiere die Business Logic
5. TESTS: Schreibe Tests für jeden Teil
6. VALIDATE: Führe die Tests aus und fixe Fehler

Regeln:
- Immer TypeScript strict
- Jede Datei max. 200 Zeilen
- Jede Funktion max. 20 Zeilen
- Tests decken Happy Path + Edge Cases ab
- Imports relativ mit @/ Alias

Wenn ein Test fehlschlägt:
1. Analysiere den Fehler
2. Fixe den Code (nicht den Test!)
3. Führe den Test erneut aus
4. Max. 3 Retry-Versuche

Darüber hinaus lässt sich das Beispiel leicht erweitern.


Test-Agent: Automatisch Tests schreiben

Im Grunde vereinfacht dieser Ansatz den gesamten Workflow erheblich.

// Test-Agent System Prompt:

Du bist ein Test-Generierungs-Agent. 

Input: Ein Quellcode-Verzeichnis
Output: Komplette Test-Suite

Workflow:
1. Lies alle TypeScript-Dateien im src/ Verzeichnis
2. Für jede exportierte Funktion/Klasse:
   a. Analysiere Parameter und Rückgabewerte
   b. Identifiziere Edge Cases
   c. Erstelle Tests:
      - Happy Path (normaler Input)
      - Edge Cases (leere Arrays, null, undefined, 0, "")
      - Error Cases (ungültige Inputs)
      - Boundary Cases (Max/Min Werte)
3. Für jede Datei src/X.ts → erstelle src/__tests__/X.test.ts
4. Führe alle Tests aus (vitest run)
5. Bei Fehlern: Prüfe ob der Bug im Test oder im Code ist
6. Generiere Coverage Report

Testing-Best-Practices:
- Arrange → Act → Assert Pattern
- Jeder Test testet genau eine Sache
- Beschreibende Test-Namen (test("should return empty array when input is null"))
- Keine Test-Interdependenzen
- Mocks nur für externe Dependencies (DB, API, FileSystem)

Dementsprechend ist eine manuelle Überprüfung empfehlenswert.


Code Review Agent

Insbesondere für den Einstieg sind die folgenden Informationen hilfreich.

// Code Review Agent: Prüft PRs automatisch

// System Prompt:
Du bist ein Code Review Agent für Pull Requests.

Input: Git Diff eines PRs
Output: Strukturiertes Review

Analysiere:
1. **Code-Qualität**: Clean Code Prinzipien, Naming, Komplexität
2. **Bugs**: Logik-Fehler, Race Conditions, Null-Pointer
3. **Security**: Injection, Auth-Bypasses, Sensitive Data Exposure
4. **Performance**: N+1 Queries, Memory Leaks, unnötige Renders
5. **Tests**: Sind neue Tests vorhanden? Decken sie den neuen Code ab?
6. **Breaking Changes**: Verändert sich die Public API?

Output-Format:
{
  "summary": "Kurze Zusammenfassung der Änderungen",
  "risk_level": "low | medium | high",
  "issues": [
    {
      "file": "src/services/user.ts",
      "line": 42,
      "severity": "critical | warning | suggestion",
      "category": "security | bug | performance | style",
      "message": "SQL Injection möglich durch String Concatenation",
      "suggestion": "Parameterized Query verwenden: db.query('SELECT * FROM users WHERE id = $1', [id])"
    }
  ],
  "approval": "approve | request_changes | comment"
}

Frameworks & SDKs

Darüber hinaus bietet dieser Abschnitt konkrete Beispiele und Tipps.

FrameworkSpracheStärkePreis
Vercel AI SDKTypeScriptTool Use, Streaming, Multi-ProviderKostenlos
LangChain.jsTypeScriptChains, Agents, Memory, RAGKostenlos
Anthropic SDKTypeScript/PythonDirekter Claude-Zugriff, Tool UseKostenlos*
CrewAIPythonMulti-Agent Systeme, Rollen-basiertKostenlos
AutoGenPythonMicrosoft, Multi-Agent ConversationsKostenlos
MCP SDKTypeScript/PythonStandard für Tool-IntegrationKostenlos

* SDK kostenlos, API-Kosten pro Token.

Empfehlung für Einsteiger: Vercel AI SDK + Anthropic. Einfachstes Setup, beste TypeScript-Integration, Tool Use out-of-the-box.


Agents in Production

Grundsätzlich gibt es dabei einige Punkte zu beachten.

Wenn du Agents nicht nur lokal, sondern in CI/CD oder als Service nutzen willst:

Safety & Guardrails

Somit kannst du direkt mit der Umsetzung beginnen.

  • Sandboxing: Agent in Docker-Container ausführen (kein Zugriff auf Host)
  • Allowlists: Zudem nur erlaubte Befehle (kein rm -rf, kein curl zu externen Servern)
  • Token-Limits: Außerdem max. Kosten pro Agent-Run ($5 Default)
  • Human-in-the-Loop: Approval vor destruktiven Aktionen (delete, deploy)
  • Timeout: Max. 10 Minuten pro Aufgabe

Monitoring

Folglich profitierst du von einem besseren Verständnis dieser Konzepte.

  • Logging: Jeder Tool-Call loggen (was, wann, Ergebnis)
  • Kosten: Token-Verbrauch pro Run tracken
  • Erfolgsrate: Wie oft löst der Agent die Aufgabe beim ersten Versuch?
  • Observability: LangSmith, Helicone oder eigenes Dashboard

CI/CD Integration

Außerdem gibt es hilfreiche Tools, die dich dabei unterstützen.

# GitHub Action: AI Agent für PR Reviews
name: AI Code Review
on: [pull_request]

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Get PR Diff
        run: gh pr diff ${{ github.event.number }} > diff.txt
      - name: Run Review Agent
        run: npx tsx scripts/review-agent.ts diff.txt
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
      - name: Post Review Comment
        run: gh pr comment ${{ github.event.number }} --body-file review-result.md

Tatsächlich lässt sich dieser Code direkt in dein Projekt übernehmen.


FAQ

Brauche ich ML-Kenntnisse um Agents zu bauen?

Dabei spielen mehrere Faktoren eine wichtige Rolle.

Nein. Du nutzt fertige LLMs (Claude, GPT-4) über APIs. Die Agent-Logik ist normaler TypeScript/Python Code. Prompt Engineering und gutes System Design sind wichtiger als ML-Wissen.

Wie teuer sind AI Agents?

Vor allem für den praktischen Einsatz sind diese Informationen wertvoll.

Typische Kosten pro Agent-Run: $0.05 – $0.50 (abhängig von Aufgabenkomplexität und Modell). Ein Code Review Agent mit Claude 3.5 Sonnet kostet ca. $0.10 pro PR. Bei 20 PRs/Tag = $2/Tag.

Welches LLM ist am besten für Agents?

Im Folgenden findest du alle wichtigen Details dazu.

Claude 3.5 Sonnet: Bestes Preis-Leistungs-Verhältnis für Code-Agents. GPT-4o: Schneller, günstiger, gut für einfache Tasks. Claude 3 Opus: Für komplexe Architektur-Entscheidungen. Lokal (Ollama + DeepSeek): Kostenlos, aber schwächere Qualität.

Sind AI Agents zuverlässig genug für Production?

Deshalb lohnt es sich, dieses Thema genauer zu betrachten.

Für klar definierte Aufgaben (Code Review, Test-Generierung, Lint-Fixing): Ja, mit Guardrails. Für offene Aufgaben (Feature implementieren): Gut als Unterstützung, aber Human Review pflicht. Die Zuverlässigkeit steigt mit besseren System Prompts und engeren Constraints.


Verwandte Artikel:


Zuletzt aktualisiert: März 2026