Создание кодинг-агента на Python: архитектура за 200 строк без API | AiManual
AiManual Logo Ai / Manual.
10 Янв 2026 Инструмент

Создаём свой Claude Code с нуля: архитектура кодинг-агента на Python за 200 строк

Создаём локальный coding assistant с нуля. Архитектура, инструменты LLM, автоматизация программирования на Python. Полный код без зависимостей от дорогих API.

Зачем платить за Claude Code, если можно собрать свой за вечер?

Помните ту статью про Claude Code теперь можно запустить локально? Мы шли вокруг да около, искали обходные пути. А что если взять и собрать ядро с нуля? Без подписок, без ограничений, без магии — только код.

Секрет в том, что все эти коммерческие coding assistants — просто надстройки над теми же LLM. Они берут OpenAI API, добавляют файловую систему, пару инструментов и продают за $20 в месяц. Мы сделаем то же самое, но бесплатно и прозрачно.

Предупреждение: этот проект — образовательный прототип. Для продакшена нужны дополнительные слои безопасности и оптимизации. Но для личного использования? Работает лучше, чем вы думаете.

Архитектура: три слоя, которые работают

Наш агент состоит из трёх частей: мозг (LLM), руки (инструменты) и память (контекст). Всё как у человека, только без эмоций и перерывов на кофе.

1 Мозг: выбираем движок

Можно взять OpenAI API — просто, но дорого. Лучше локальные модели через Ollama или vLLM. Помните статью про Claude Code с локальными LLM? Там вся магия уже расписана.

Я выбрал LiteLLM как абстракцию. Поддерживает десяток провайдеров, от OpenAI до локальных моделей. Меняете одну строку — переключаетесь между облаком и локальным запуском.

2 Руки: инструменты, которые умеют всё

Ключевая разница между чат-ботом и coding assistant — инструменты. Чат-бот болтает, агент — действует. Нам нужно четыре базовых инструмента:

  • Чтение файлов (чтобы понимать код)
  • Запись файлов (чтобы изменять код)
  • Выполнение команд (чтобы тестировать)
  • Поиск в интернете (опционально, но полезно)

Каждый инструмент — это функция Python с чётким описанием для LLM. Нейросеть сама решает, когда какой инструмент использовать. Вы удивитесь, насколько хорошо это работает.

3 Память: контекст, который не теряется

Самая сложная часть. Нужно хранить историю разговора, результаты выполнения инструментов, состояние проекта. И всё это в пределах токен-лимита модели.

Решение — иерархическая память. Длинные диалоги сжимаем, важные результаты оставляем, мусор удаляем. Как в рабочем процессе создателя Claude Code, только автоматизированно.

💡
Совет от практика: не пытайтесь сохранить всю историю. Сжимайте старые сообщения в краткое описание. "Агент создал файл app.py с Flask-приложением" вместо 200 строк кода в контексте.

Код: 200 строк, которые работают

Вот ядро нашего агента. Весь код умещается в один файл, зависимости — только requests и litellm.

import os
import json
import subprocess
from typing import List, Dict, Any
import litellm

class CodingAgent:
    def __init__(self, model: str = "gpt-4"):
        self.model = model
        self.conversation_history = []
        self.tools = {
            "read_file": {
                "description": "Читает содержимое файла",
                "function": self.read_file
            },
            "write_file": {
                "description": "Создает или изменяет файл",
                "function": self.write_file
            },
            "run_command": {
                "description": "Выполняет команду в терминале",
                "function": self.run_command
            }
        }
    
    def read_file(self, path: str) -> str:
        try:
            with open(path, 'r', encoding='utf-8') as f:
                return f.read()
        except Exception as e:
            return f"Ошибка чтения файла: {str(e)}"
    
    def write_file(self, path: str, content: str) -> str:
        try:
            os.makedirs(os.path.dirname(path), exist_ok=True)
            with open(path, 'w', encoding='utf-8') as f:
                f.write(content)
            return f"Файл {path} успешно записан"
        except Exception as e:
            return f"Ошибка записи файла: {str(e)}"
    
    def run_command(self, command: str) -> str:
        try:
            result = subprocess.run(
                command, 
                shell=True, 
                capture_output=True, 
                text=True, 
                timeout=30
            )
            return f"STDOUT:\n{result.stdout}\n\nSTDERR:\n{result.stderr}\n\nКод возврата: {result.returncode}"
        except Exception as e:
            return f"Ошибка выполнения команды: {str(e)}"
    
    def process_message(self, user_input: str) -> str:
        # Добавляем сообщение пользователя в историю
        self.conversation_history.append({"role": "user", "content": user_input})
        
        # Формируем системный промпт с описанием инструментов
        system_prompt = self._build_system_prompt()
        
        # Отправляем запрос к LLM
        response = litellm.completion(
            model=self.model,
            messages=[{"role": "system", "content": system_prompt}] + self.conversation_history,
            temperature=0.1
        )
        
        # Парсим ответ и выполняем инструменты если нужно
        llm_response = response.choices[0].message.content
        result = self._handle_tool_calls(llm_response)
        
        # Добавляем ответ в историю
        self.conversation_history.append({"role": "assistant", "content": result})
        
        # Сжимаем историю если нужно
        self._compress_history()
        
        return result
    
    def _build_system_prompt(self) -> str:
        tools_desc = "\n".join([
            f"{name}: {info['description']}" 
            for name, info in self.tools.items()
        ])
        
        return f"""Ты — AI coding assistant. У тебя есть доступ к инструментам:
        
        {tools_desc}
        
        Для использования инструмента ответь в формате JSON:
        {{"tool": "имя_инструмента", "args": {{...}}}}
        
        После выполнения инструмента я пришлю тебе результат.
        """
    
    def _handle_tool_calls(self, llm_response: str) -> str:
        # Пытаемся найти JSON в ответе LLM
        try:
            tool_call = json.loads(llm_response)
            if "tool" in tool_call and "args" in tool_call:
                tool_name = tool_call["tool"]
                if tool_name in self.tools:
                    result = self.tools[tool_name]["function"](**tool_call["args"])
                    return f"Результат выполнения {tool_name}:\n{result}"
        except json.JSONDecodeError:
            pass
        
        # Если не нашли инструмент, возвращаем обычный ответ
        return llm_response
    
    def _compress_history(self):
        # Простая компрессия: оставляем только последние 10 сообщений
        if len(self.conversation_history) > 20:
            # Сохраняем системные сообщения и последние 10
            self.conversation_history = self.conversation_history[-10:]

# Пример использования
if __name__ == "__main__":
    agent = CodingAgent(model="gpt-4")
    print(agent.process_message("Создай файл hello.py с программой 'Hello, World!'"))

Видите? Никакой магии. LLM получает описание инструментов, решает, что делать, возвращает JSON с командой. Мы выполняем, отправляем результат обратно. Цикл замыкается.

Чем наш агент лучше коммерческих аналогов?

Критерий Claude Code Наш агент
Стоимость $20/месяц Бесплатно (или цена API)
Прозрачность Закрытый код Весь код перед вами
Кастомизация Ограничена Любая
Зависимости Требует их инфраструктуру Работает везде с Python

Главное преимущество — контроль. Хотите добавить инструмент для работы с Git? 10 строк кода. Нужна интеграция с вашей CI/CD? Пишите плагин. Устали от ограничений токенов? Реализуйте свою стратегию сжатия.

Вспомните статью про Codex, Gemini и Claude Code. Там говорилось о трёх путях к одному коду. Мы открываем четвёртый — путь полного контроля.

Реальные примеры использования

Что можно делать с этим агентом? Практически всё, что делает Claude Code, но дешевле и прозрачнее.

Рефакторинг кода

Дайте агенту доступ к вашей кодовой базе. Скажите: "Найди все функции длиннее 50 строк и разбей их на более мелкие". Агент прочитает файлы, проанализирует, предложит изменения, даже протестирует их запуском юнит-тестов.

Автоматическая документация

"Сгенерируй документацию в формате Markdown для всех модулей в папке src/". Агент пройдётся по файлам, проанализирует функции и классы, создаст структурированную документацию. Как в статье про one-shot декомпиляцию, только для документации.

Миграция кода

Нужно перенести проект с Python 2 на Python 3? Агент может автоматически находить устаревшие конструкции и заменять их. С контролем каждого изменения, с возможностью отката.

Важный нюанс: никогда не давайте агенту права на запись без ревью. Всегда проверяйте изменения перед коммитом. Или настройте автоматические тесты для каждого изменения.

Как улучшить базовую версию?

Наш код — минимальная рабочая версия. Вот что можно добавить для реального использования:

  • Безопасность: sandbox для выполнения команд, whitelist разрешённых операций
  • Контекстное окно: умное сжатие истории, выделение ключевых фрагментов
  • Плагины: система расширений для добавления новых инструментов
  • Веб-интерфейс: простой UI на Streamlit или FastAPI
  • Интеграция с IDE: плагин для VS Code или Cursor

Для вдохновения посмотрите обзор Ollie — там много идей по организации локального coding assistant.

Кому подойдёт этот подход?

Не всем. Если вам нужен готовый продукт "из коробки" — покупайте Claude Code или Cursor. Но если вы:

  • Любите контролировать каждый аспект своего инструментария
  • Хотите понять, как работают AI-агенты изнутри
  • Имеете специфические требования к workflow
  • Не хотите платить подписку за базовый функционал
  • Любите собирать LEGO из кода

Тогда этот проект для вас. Это как собрать свой фреймворк вместо использования готового. Сложнее, но гибче и понятнее.

Помните статью про взлом ограничений NVIDIA? Там тот же принцип — когда готовые решения не подходят, создаём свои.

Что дальше?

Попробуйте запустить базовую версию. Поймите принцип работы. Затем добавьте свой первый инструмент — например, поиск по документации или генерацию SQL-запросов.

Самое интересное начинается, когда вы осознаете: это не просто coding assistant. Это платформа для автоматизации любых задач. От анализа данных до управления инфраструктурой. Как в статье про MRI-GPT, только для программирования.

И главное — теперь вы знаете, как это работает изнутри. Никакой магии, только код. 200 строк Python, которые могут заменить $20-месячную подписку.

Кстати, если соберётесь расширять этого агента — посмотрите статью про Claude Code от промпта до продакшена. Там много практических советов по масштабированию.

А теперь идите и соберите своего агента. И когда он впервые самостоятельно починит баг в вашем коде — вы поймёте, зачем всё это было нужно.