Розробка 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"
Вбудований Code Interpreter OpenAI
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 тижні
- Інтеграція з джерелами даних: 1–2 тижні
- Всього: 4–8 тижнів







