Зачем платить за 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, только автоматизированно.
Код: 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 от промпта до продакшена. Там много практических советов по масштабированию.
А теперь идите и соберите своего агента. И когда он впервые самостоятельно починит баг в вашем коде — вы поймёте, зачем всё это было нужно.