Разработка AI-агента с возможностью выполнения кода (Code Interpreter)
AI-агент с Code Interpreter выполняет произвольный код внутри изолированной среды, получает реальные результаты вычислений и использует их для ответа. Это принципиально отличается от генерации кода без выполнения: агент может итеративно писать, запускать и исправлять код до получения корректного результата.
Архитектура Code Interpreter
Запрос → LLM генерирует код → Sandbox выполняет → Результат/ошибка
↑ |
└──────────── Итерация при ошибке ─────────┘
Ключевое требование: безопасная изолированная среда выполнения. Без sandboxing агент может выполнить произвольный системный код.
Реализация через Docker Sandbox
import docker
import tempfile
import os
from pathlib import Path
class DockerCodeExecutor:
"""Безопасное выполнение кода в Docker контейнере"""
def __init__(self, image: str = "python:3.11-slim", timeout: int = 30):
self.client = docker.from_env()
self.image = image
self.timeout = timeout
# Предварительно загруженный образ с numpy, pandas, matplotlib
# docker build -t code-executor-sandbox -f Dockerfile.sandbox .
def execute(self, code: str, files: dict = None) -> dict:
"""
Выполняет код в изолированном контейнере
files: {filename: content} для передачи данных
"""
with tempfile.TemporaryDirectory() as tmpdir:
# Записываем файлы данных
if files:
for fname, content in files.items():
(Path(tmpdir) / fname).write_bytes(content)
# Записываем код
code_file = Path(tmpdir) / "script.py"
code_file.write_text(code, encoding="utf-8")
try:
result = self.client.containers.run(
self.image,
command=["python", "/workspace/script.py"],
volumes={tmpdir: {"bind": "/workspace", "mode": "rw"}},
remove=True,
stdout=True,
stderr=True,
mem_limit="512m",
cpu_quota=50000, # 50% одного CPU
network_disabled=True, # Без сети!
read_only=False,
timeout=self.timeout,
)
return {
"status": "success",
"output": result.decode("utf-8"),
"files": self._list_output_files(tmpdir),
}
except docker.errors.ContainerError as e:
return {
"status": "error",
"output": e.stderr.decode("utf-8"),
"error_type": "runtime",
}
except Exception as e:
return {"status": "error", "output": str(e), "error_type": "system"}
def _list_output_files(self, tmpdir: str) -> list:
return [f.name for f in Path(tmpdir).iterdir() if f.suffix in [".png", ".csv", ".json", ".txt"]]
Агент с Code Interpreter
from openai import OpenAI
import json
client = OpenAI()
executor = DockerCodeExecutor()
code_tools = [{
"type": "function",
"function": {
"name": "execute_python",
"description": "Выполнить Python-код и вернуть результат. Используй для вычислений, анализа данных, визуализации.",
"parameters": {
"type": "object",
"properties": {
"code": {"type": "string", "description": "Python-код для выполнения"},
"description": {"type": "string", "description": "Что делает этот код (для логирования)"},
},
"required": ["code"]
}
}
}]
def code_interpreter_agent(user_request: str, data_files: dict = None) -> str:
messages = [
{
"role": "system",
"content": """Ты — аналитик данных с доступом к Python.
Для вычислений всегда пиши и выполняй код, не отвечай «примерно».
Доступные библиотеки: pandas, numpy, matplotlib, scipy, sklearn, json, csv.
При ошибке — анализируй traceback и исправляй код."""
},
{"role": "user", "content": user_request},
]
for _ in range(8): # Max 8 итераций
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=code_tools,
tool_choice="auto",
)
message = response.choices[0].message
messages.append(message)
if not message.tool_calls:
return message.content
for tool_call in message.tool_calls:
code = json.loads(tool_call.function.arguments)["code"]
result = executor.execute(code, files=data_files)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result, ensure_ascii=False),
})
return "Max iterations reached"
OpenAI встроенный Code Interpreter
OpenAI Assistants API предоставляет встроенный code interpreter (без необходимости своего Docker):
from openai import OpenAI
client = OpenAI()
# Создание ассистента с Code Interpreter
assistant = client.beta.assistants.create(
name="Data Analyst",
instructions="Анализируй данные используя Python. Создавай визуализации.",
tools=[{"type": "code_interpreter"}],
model="gpt-4o",
)
# Загрузка файла данных
with open("sales_data.csv", "rb") as f:
file = client.files.create(file=f, purpose="assistants")
# Запрос с файлом
thread = client.beta.threads.create()
client.beta.threads.messages.create(
thread_id=thread.id,
role="user",
content="Проанализируй данные продаж и построй график по месяцам",
attachments=[{"file_id": file.id, "tools": [{"type": "code_interpreter"}]}]
)
run = client.beta.threads.runs.create_and_poll(
thread_id=thread.id,
assistant_id=assistant.id,
)
Практический кейс: финансовый аналитик с Code Interpreter
Задача: автоматическое построение финансовых отчётов — агент получает CSV с транзакциями, самостоятельно пишет код для анализа, строит графики, формирует Excel-отчёт.
Запрос: «Проанализируй прилагаемые данные продаж Q1 2026. Рассчитай динамику по месяцам, топ-10 продуктов, конверсию воронки. Создай PDF-отчёт с визуализациями.»
Итерации агента:
- Загрузка и проверка структуры CSV (5 колонок, 45K строк)
- Очистка данных (дубликаты, null-значения)
- Расчёт помесячной динамики + bar chart
- ABC-анализ продуктов + Pareto chart
- Воронка конверсии + funnel visualization
-
reportlab→ генерация PDF
Результаты:
- Время создания отчёта: 3–4 часа (аналитик вручную) → 8 минут
- Покрытие показателей: идентично
- Требует проверки: интерпретации и выводы (агент их формулирует, человек валидирует)
E2B Sandbox как альтернатива Docker
E2B — managed sandbox для Code Interpreter без DevOps:
import e2b_code_interpreter as e2b
sandbox = e2b.CodeInterpreter()
# Выполнение кода
execution = sandbox.notebook.exec_cell("""
import pandas as pd
df = pd.read_csv('/data/sales.csv')
print(df.describe())
""")
print(execution.stdout)
sandbox.close()
Сроки
- Настройка Docker sandbox + базовый агент: 1–2 недели
- Специализированный аналитический агент: 2–4 недели
- Интеграция с data sources: 1–2 недели
- Итого: 4–8 недель







