Архитектура AI-агента 2026: MCP, skills и REPL для работы с файлами и CLI | AiManual
AiManual Logo Ai / Manual.
27 Янв 2026 Гайд

Архитектура универсального AI-агента: от MCP к skills и REPL-подходу для работы с файлами и CLI

Глубокий разбор эволюции AI-агентов: от tool-ориентированного подхода к концепции skills и REPL для генерации и выполнения кода под задачи. Практическая архитек

Почему ваш AI-агент все еще не умеет работать с файлами?

Вы создали умного помощника. Он анализирует код, пишет документацию, даже делает код-ревью. Но стоит попросить его "посмотреть содержимое папки и найти все .py файлы" - и он замирает. Или предлагает странные решения вроде "я не могу читать файлы, но могу предположить...". Знакомо?

Это не проблема модели. Это проблема архитектуры. В 2026 году мы все еще пытаемся заставить LLM работать с файловой системой через костыли, хотя решение лежит на поверхности.

Если ваш агент не может выполнить ls -la и проанализировать результат - вы строите дом без фундамента. Файловая система - это операционная среда любого разработчика. Игнорировать ее - все равно что пытаться готовить ужин с завязанными глазами.

Эволюция: от тупых инструментов к умным навыкам

1 MCP: первый шаг к осознанию проблемы

Model Context Protocol от Anthropic - это как первая попытка научить ребенка пользоваться ложкой. Не идеально, но лучше, чем есть руками.

MCP решает базовую проблему: как безопасно дать LLM доступ к внешним ресурсам. Серверы, инструменты, API - все через единый протокол. Звучит логично, пока не сталкиваешься с реальностью.

Вот типичный сценарий провала:

# tools.py - классический MCP подход
@tool
def read_file(path: str) -> str:
    """Читает содержимое файла"""
    with open(path, 'r') as f:
        return f.read()

@tool
def list_directory(path: str) -> list:
    """Список файлов в директории"""
    return os.listdir(path)

Проблема? Агент вызывает read_file. Получает 1000 строк кода. Пытается их анализировать. Забывает контекст. Вызывает еще один инструмент. Контекстное окно переполняется. Результат - хаос.

💡
MCP решает проблему доступа, но не решает проблему контекста. Каждый вызов инструмента - это разрыв в мышлении агента. Он видит результат, но не понимает, как этот результат связан с предыдущими шагами.

2 Skills: когда инструменты становятся умными

Skills - это следующий эволюционный скачок. Если MCP-инструменты - это отдельные функции, то skills - это целые библиотеки с контекстом, памятью и логикой.

Вспомните статью про Skills, MCP и сабагенты. Там мы разбирали, как навыки превращают хаотичный диалог в предсказуемую систему.

Но даже skills не решают главную проблему работы с файлами: агент все еще мыслит дискретными шагами. "Прочитать файл" -> "Проанализировать" -> "Принять решение". Это медленно. Это неэффективно. Это не похоже на то, как работает разработчик.

REPL-подход: когда агент становится разработчиком

REPL (Read-Eval-Print Loop) - это концепция из мира программирования. Вы вводите код, система выполняет его, показывает результат. Цикл повторяется.

Теперь представьте: агент не вызывает инструменты. Он генерирует код, который выполняет задачу. Не "прочитай файл", а "вот скрипт, который найдет все .py файлы и проанализирует их структуру".

Это меняет все.

Подход Как работает Проблема
MCP-инструменты Агент вызывает API для каждого действия Много контекстных переключений, медленно
Skills Агент активирует навык с готовой логикой Ограниченная гибкость, нужно предопределять все сценарии
REPL Агент генерирует код под конкретную задачу Требует контроля безопасности, может генерировать плохой код

3 Как это работает на практике

Давайте разберем реальный пример. Задача: "Найди все Python-файлы в проекте, которые содержат SQL-запросы без параметризации".

Старый подход (MCP):

# Агент делает:
1. Вызывает list_directory("/project")
2. Фильтрует .py файлы (в уме)
3. Для каждого файла вызывает read_file()
4. Ищет SQL-запросы (в уме)
5. Проверяет параметризацию (в уме)
6. Формирует отчет

6 вызовов инструментов. 6 разрывов контекста. Идеальный рецепт для ошибки.

Новый подход (REPL + Skills):

# Агент генерирует:
import os
import re

def find_sql_injections(root_dir):
    results = []
    sql_pattern = re.compile(r'SELECT|INSERT|UPDATE|DELETE.*FROM', re.IGNORECASE)
    param_pattern = re.compile(r'%s|\?|:param|@param')
    
    for root, dirs, files in os.walk(root_dir):
        for file in files:
            if file.endswith('.py'):
                path = os.path.join(root, file)
                with open(path, 'r', encoding='utf-8') as f:
                    content = f.read()
                    
                # Ищем SQL-запросы
                sql_matches = sql_pattern.findall(content)
                if sql_matches:
                    # Проверяем параметризацию
                    has_params = bool(param_pattern.search(content))
                    
                    if not has_params:
                        results.append({
                            'file': path,
                            'sql_count': len(sql_matches),
                            'lines': [i+1 for i, line in enumerate(content.split('\n')) 
                                     if sql_pattern.search(line)]
                        })
    
    return results

# Выполняем
injections = find_sql_injections('/project')
print(f"Найдено {len(injections)} файлов с потенциальными SQL-инъекциями")
for item in injections:
    print(f"  {item['file']}: {item['sql_count']} запросов на строках {item['lines']}")

Один вызов. Один результат. Агент мыслит как разработчик, а не как пользователь API.

Архитектура универсального агента 2026

Собираем все вместе. Вот как выглядит современный агент для работы с файлами и CLI:

# architecture.py
class UniversalFileAgent:
    def __init__(self):
        self.skills_registry = SkillsRegistry()  # Динамические навыки
        self.repl_executor = REPLExecutor()      # Безопасное выполнение кода
        self.context_manager = ContextManager()  # Управление контекстом
        self.safety_checker = SafetyChecker()    # Проверка безопасности кода
    
    async def handle_request(self, task: str) -> str:
        """Основной цикл обработки задач"""
        
        # 1. Определяем, нужен ли навык или REPL
        if self._is_standard_task(task):
            # Используем готовый навык
            skill = self.skills_registry.get_skill(task)
            return await skill.execute(task)
        else:
            # 2. Генерируем код под задачу
            generated_code = await self._generate_code(task)
            
            # 3. Проверяем безопасность
            if not self.safety_checker.is_safe(generated_code):
                return "Код не прошел проверку безопасности"
            
            # 4. Выполняем в sandbox
            result = await self.repl_executor.execute(generated_code)
            
            # 5. Анализируем результат, учимся
            self._learn_from_execution(task, generated_code, result)
            
            return result
    
    def _is_standard_task(self, task: str) -> bool:
        """Определяем, есть ли готовый навык"""
        # Здесь логика определения типа задачи
        standard_tasks = [
            "code review",
            "documentation",
            "security scan",
            "dependency update"
        ]
        return any(st in task.lower() for st in standard_tasks)

Ключевое отличие от традиционной архитектуры: агент не просто выбирает между инструментами. Он выбирает между парадигмами. "Использовать готовое решение" или "создать новое под задачу". Это уровень мышления, а не просто выполнения.

4 Безопасность: самая сложная часть

REPL-подход - это мощно. И страшно. Дать агенту возможность выполнять произвольный код - все равно что дать ребенку бензопилу.

Вот что НЕЛЬЗЯ делать:

# НИКОГДА ТАК НЕ ДЕЛАЙТЕ
exec(generated_code)  # Прямое выполнение
os.system(user_input) # Выполнение shell-команд
subprocess.run(unsafe_command) # Без проверки

Вот как делать правильно:

# security.py
class SafeREPLExecutor:
    def __init__(self):
        self.allowed_modules = {
            'os': ['path', 'listdir', 'walk'],
            're': ['compile', 'search', 'findall'],
            'json': ['loads', 'dumps'],
            'pathlib': ['Path'],
            'sys': ['version']
        }
        
        self.banned_patterns = [
            r'__import__\s*\(',
            r'eval\s*\(',
            r'exec\s*\(',
            r'open\s*\(.*[wax]\s*[,)]',  # Запись в файлы
            r'os\.(system|popen|remove|rmdir)',
            r'subprocess\.',
            r'import\s+shutil',
            r'import\s+subprocess'
        ]
    
    async def execute(self, code: str) -> str:
        """Безопасное выполнение кода"""
        
        # 1. Статический анализ
        for pattern in self.banned_patterns:
            if re.search(pattern, code):
                raise SecurityError(f"Запрещенная конструкция: {pattern}")
        
        # 2. Sandbox выполнение
        try:
            # Ограниченное пространство имен
            safe_globals = {
                '__builtins__': {
                    'len': len,
                    'range': range,
                    'str': str,
                    'list': list,
                    'dict': dict,
                    'bool': bool,
                    'int': int,
                    'float': float
                }
            }
            
            # Добавляем разрешенные модули
            for module, functions in self.allowed_modules.items():
                imported = __import__(module)
                safe_globals[module] = {f: getattr(imported, f) for f in functions}
            
            # Выполняем в изолированном контексте
            exec_globals = {}
            exec(code, safe_globals, exec_globals)
            
            # Ищем результат (предполагаем, что код что-то возвращает)
            if 'result' in exec_globals:
                return str(exec_globals['result'])
            else:
                return "Код выполнен, но не вернул результат"
                
        except Exception as e:
            return f"Ошибка выполнения: {str(e)}"

Интеграция с существующей экосистемой

Вы не строите агента с нуля. Вы интегрируете его в существующий workflow. Вот как это выглядит на практике.

Сценарий: вы используете динамические навыки через файловую систему. У вас уже есть структура:

agent_skills/
├── code_review/
├── documentation/
└── security_scan/

Добавляем REPL-навык:

agent_skills/
├── code_review/
├── documentation/
├── security_scan/
└── repl_generator/          # Новый навык
    ├── SKILL.md
    ├── safety_rules.yaml
    ├── code_templates/
    └── examples/

SKILL.md для REPL-навыка:

# repl_generator/SKILL.md
name: "code_generator"
description: "Генерация и выполнение Python кода для работы с файлами"
triggers:
  - "напиши скрипт для"
  - "создай программу которая"
  - "автоматизируй задачу"
  - "обработай файлы"

safety_rules:
  - "запрещено выполнение shell-команд"
  - "запрещена запись в системные файлы"
  - "максимальное время выполнения: 30 секунд"
  - "максимальный размер вывода: 10MB"

code_templates:
  file_processing: |
    import os
    import re
    
    def process_files(directory, pattern):
        results = []
        for root, dirs, files in os.walk(directory):
            for file in files:
                if re.search(pattern, file):
                    path = os.path.join(root, file)
                    # Добавьте свою логику здесь
                    results.append(path)
        return results

Ошибки, которые все еще совершают в 2026

Даже с современными инструментами разработчики наступают на одни и те же грабли.

Ошибка 1: Слишком много доверия

# ПЛОХО: полагаться на то, что агент сам все проверит
result = await agent.execute("удали все .log файлы старше 30 дней")
# Агент может сгенерировать: os.system("find / -name '*.log' -mtime +30 -delete")
# Поздравляем, вы только что удалили системные логи

Ошибка 2: Игнорирование контекста

# ПЛОХО: каждый запрос обрабатывается изолированно
agent.handle("покажи структуру проекта")
agent.handle("найди все тесты")
agent.handle("проверь покрытие")
# Три отдельных вызова, три раза агент обходит файловую систему

Ошибка 3: Отсутствие обучения

Самый большой провал - не учиться на успешных выполнениях. Если агент сгенерировал идеальный скрипт для обработки CSV-файлов - сохраните его как новый навык. В следующий раз он будет использовать готовое решение, а не изобретать велосипед.

💡
REPL-подход - это не замена skills, а их дополнение. Skills для стандартных задач, REPL для уникальных. Хороший агент знает, когда использовать готовое решение, а когда создать новое.

Практический пример: миграция проекта

Давайте посмотрим, как универсальный агент справляется с реальной задачей: "Перенеси все конфигурационные файлы из формата YAML в TOML".

Вместо того чтобы писать длинный промпт с инструкциями, агент:

  1. Анализирует структуру проекта (используя навык анализа файлов)
  2. Определяет, что задача нестандартная (нет навыка YAML-TOML конвертации)
  3. Генерирует скрипт, который:
    • Находит все .yaml и .yml файлы
    • Анализирует их структуру
    • Конвертирует в TOML с учетом специфики (комментарии, многоуровневые структуры)
    • Создает backup оригинальных файлов
    • Генерирует отчет о конвертации
  4. Выполняет скрипт в sandbox
  5. Предлагает сохранить скрипт как новый навык для будущего использования

Весь процесс занимает минуты, а не часы ручной работы.

Что дальше? Эволюция не остановится

К 2027 году мы увидим еще больший сдвиг. REPL-подход эволюционирует в то, что я называю "когнитивным программированием". Агент не просто генерирует код - он понимает контекст проекта, знает историю изменений, предсказывает побочные эффекты.

Представьте агента, который:

  • Видит, что вы меняете API endpoint
  • Автоматически находит все клиенты этого API в кодовой базе
  • Генерирует миграционные скрипты для каждого клиента
  • Запускает тесты, чтобы убедиться, что ничего не сломалось
  • Создает PR с изменениями и описанием

Это не фантастика. Это следующий логический шаг после REPL-подхода.

Самый важный урок 2026 года: перестаньте думать об агентах как о чат-ботах с инструментами. Начинайте думать о них как о автономных разработчиках, которые могут не только использовать инструменты, но и создавать их под задачи. Разница фундаментальная.

Если вы до сих пор строите агентов, которые не умеют работать с файловой системой - вы отстали на два поколения архитектур. MCP был вчера. Skills - сегодня. REPL-подход - завтра. И это завтра уже наступило.

Начните с малого. Добавьте REPL-навык в своего агента. Дайте ему возможность генерировать простые скрипты для обработки файлов. Увидите - через неделю вы не сможете представить работу без этого. Потому что это не просто еще одна фича. Это изменение парадигмы.