Как создать своего первого AI-агента на Python: пошаговая инструкция для начинающих
Ещё несколько лет назад AI в программировании ассоциировался с машинным обучением, математикой и дорогими серверами. Сегодня всё проще: большую языковую модель можно вызвать через API несколькими строками кода, а самое интересное начинается тогда, когда модель не только отвечает текстом, но и выполняет действия. Это и есть AI-агент.
В этой статье вы пошагово создадите своего первого AI-агента на Python — консольного помощника, который понимает запросы обычным языком («Добавь задачу подготовить домашнее задание по Python на завтра»), сам решает, какой инструмент вызвать, и ведёт список задач в файле. Без фреймворков и «магии»: около двухсот строк понятного кода, официальная библиотека anthropic и стандартные модули Python.
Почему именно Python? Это самый распространённый язык для работы с искусственным интеллектом: для него первыми выходят SDK провайдеров моделей, на нём пишут большинство AI-библиотек, а синтаксис достаточно прост, чтобы новичок читал код как текст. Для туториала хватит базовых навыков: запускать команды в терминале, понимать переменные, функции и словари. Если этих знаний пока нет, не страшно — код можно просто повторить, а в конце мы разберём, какие темы стоит изучить, чтобы писать таких агентов самостоятельно. Системно пройти этот путь от основ языка до собственных проектов можно на курсе Python Developer + AI от Prog Academy.
Коротко: что будет в статье
- Что такое AI-агент и чем он отличается от чат-бота — простыми словами и на схеме.
- Настройка Python, виртуального окружения и API-ключа для Windows, macOS и Linux.
- Полный рабочий код агента с тремя инструментами, проверкой данных и обработкой ошибок.
- Сценарии тестирования, частые ошибки новичков и способы улучшить агента.
- Какие навыки Python нужны, чтобы создавать AI-агентов самостоятельно.
Что такое AI-агент?
AI-агент — это программа, в которой большая языковая модель (LLM) получает задачу, сама решает, какие действия выполнить, вызывает для этого инструменты и использует их результаты, чтобы прийти к ответу. Инструментом может быть любая функция в вашем коде: создать задачу, найти запись в базе, отправить запрос во внешний API.
AI-агент и обычный чат-бот
Обычный чат-бот работает по схеме «вопрос → ответ»: вы пишете сообщение, модель отвечает текстом, и на этом всё. Она может подсказать, как добавить задачу в список, но сама её не добавит. Агент отличается тремя вещами:
- Инструменты. Программист описывает функции, которые модель может «попросить» вызвать, — с названием, описанием и параметрами.
- Решение. Модель сама определяет, нужен ли инструмент, какой именно и с какими аргументами.
- Цикл выполнения. Результат инструмента возвращается модели, и она решает, что делать дальше: вызвать ещё один инструмент или ответить пользователю.
LLM, инструменты и цикл выполнения
Важный момент, который часто путают новички: модель сама ничего не выполняет. Она возвращает структурированный ответ вроде «вызови функцию add_task с параметрами title и due_date». Выполняет функцию ваш Python-код, и именно он решает, разрешено ли это действие. Этот механизм называют function calling, или tool use.
add_task с названием и датой
tasks.json
↺ Результат инструмента возвращается модели. Цикл повторяется, пока модель вызывает инструменты, — но не дольше установленного лимита шагов.
Как агент решает, какой инструмент использовать
Модель не «знает» ваш код. Она видит только три вещи: системную инструкцию (кто она и какие правила), описание инструментов (название, пояснение, JSON Schema параметров) и историю диалога. На этой основе она выбирает действие. Поэтому качество агента напрямую зависит от того, насколько понятно вы описали инструменты: размытое описание — случайные решения, чёткое описание — предсказуемое поведение. Подробно механизм описан в документации Anthropic о tool use.
Где применяют AI-агентов
- Личные помощники — задачи, заметки, календарь, напоминания.
- Поддержка клиентов — ответы по базе знаний и проверка статуса заказа через API.
- Работа с данными — запросы к базе, отчёты, поиск аномалий.
- Разработка — ассистенты, которые читают код, запускают тесты и предлагают исправления.
- Автоматизация бизнес-процессов — обработка заявок, писем и документов. Как выбрать такой процесс и посчитать окупаемость, мы разобрали в статье «ИИ-агенты для бизнеса: внедрение и окупаемость».
Почему Python для AI-агентов?
Python для искусственного интеллекта — фактический стандарт, и для агентов это особенно заметно. Вот что делает его удобным именно для такой задачи:
- Читаемый синтаксис. Логика агента — это условия, циклы и вызовы функций. На Python она читается почти как описание алгоритма, поэтому ошибку проще заметить.
- Интеграция с API. Официальные SDK Anthropic, OpenAI, Google и других провайдеров появляются для Python одними из первых. Для любого другого сервиса есть
httpxилиrequests. - AI-библиотеки. Фреймворки для агентов (LangGraph, LlamaIndex, Pydantic AI), инструменты для работы с векторными базами и машинного обучения в основном ориентированы на Python.
- Обработка данных. Модули
jsonиcsv, библиотеки pandas и NumPy — всё, чтобы подготовить данные для агента и обработать его результаты. Подробнее — в статье «Python для анализа данных». - Автоматизация. Работа с файлами, запуск по расписанию, скрипты для рутинных задач — на Python это несколько строк.
Для новичка это означает плавную траекторию: те же знания, с которыми вы пишете первый скрипт для переименования файлов, со временем становятся основой для программ, которые вызывают языковые модели и действуют от имени пользователя. Между «Hello, world» и AI-агентом нет пропасти — есть последовательность навыков, которую можно пройти шаг за шагом.
Хотите научиться программировать на Python с нуля и создавать собственные AI-проекты?
Ознакомьтесь с программой курса Python Developer + AI от Prog Academy.
Посмотреть программу курсаЧто мы создадим: AI Task Assistant
Наш проект — AI Task Assistant, консольный помощник для списка задач. Он работает так:
- Получает запрос обычным языком — на русском, украинском или английском.
- Определяет намерение пользователя: добавить задачу, показать список или отметить задачу выполненной.
- Выбирает подходящий инструмент — одну из трёх Python-функций.
- Выполняет разрешённое действие: наш код проверяет данные и записывает изменения в файл
tasks.json. - Возвращает результат коротким сообщением.
Например, на запрос «Добавь задачу подготовить домашнее задание по Python на завтра» агент вызовет инструмент add_task, сам превратит «завтра» в конкретную дату в формате YYYY-MM-DD и подтвердит, что задача создана.
Сознательные ограничения проекта: агент не удаляет задачи, не имеет доступа к другим файлам и не может запускать команды операционной системы. Это не недостаток, а пример правильного подхода — давать агенту ровно те права, которые нужны для его задачи.
Что нужно перед началом
1. Python 3.10 или новее
Текущая версия библиотеки anthropic (ветка 1.x) требует Python 3.10+. Пример в статье проверен на Python 3.12 с anthropic 1.6.0. Рекомендуем ставить актуальную стабильную версию с python.org; статус поддержки каждой версии — на странице версий Python.
- Windows: скачайте установщик с python.org и при установке отметьте пункт Add python.exe to PATH. Проверка:
py --version. - macOS: установщик с python.org или
brew install python, если у вас есть Homebrew. Проверка:python3 --version. - Linux (Ubuntu/Debian):
sudo apt install python3 python3-venv python3-pip. Проверка:python3 --version.
2. Папка проекта и виртуальное окружение
Виртуальное окружение изолирует библиотеки проекта от системного Python, чтобы разные проекты не конфликтовали между собой.
macOS и Linux:
mkdir ai-task-agent
cd ai-task-agent
python3 -m venv .venv
source .venv/bin/activate
Windows (PowerShell):
mkdir ai-task-agent
cd ai-task-agent
py -m venv .venv
.venv\Scripts\Activate.ps1
Если PowerShell не даёт запустить скрипт активации, откройте обычную «Командную строку» (cmd) и выполните .venv\Scripts\activate.bat. После активации в начале строки терминала появится (.venv).
3. Установка зависимостей
Нам нужна всего одна внешняя библиотека — официальный Python SDK Anthropic. Остальное (json, datetime, pathlib) входит в стандартную библиотеку Python.
python -m pip install "anthropic>=1.6,<2"
Ограничение версии <2 защищает от несовместимых изменений в будущей мажорной версии SDK. Команда одинакова для всех систем, если виртуальное окружение активировано.
4. API-ключ
Создайте аккаунт в Claude Console и сгенерируйте ключ в разделе API Keys. Ключ — это пароль к вашему платному аккаунту: любой, кто его знает, может тратить ваши деньги.
Не вставляйте API-ключ в agent.py, не отправляйте его в чаты и не загружайте на GitHub. Код получает ключ из переменной окружения — так он не попадёт в файлы проекта.
5. Переменная окружения
Задайте ключ в том же окне терминала, где будете запускать агента:
# macOS и Linux
export ANTHROPIC_API_KEY="ваш-ключ"
# Windows PowerShell
$env:ANTHROPIC_API_KEY = "ваш-ключ"
:: Windows cmd
set ANTHROPIC_API_KEY=ваш-ключ
Так переменная действует только в текущей сессии терминала: после перезапуска её нужно задать снова. Это неудобно, зато безопасно для первого проекта.
Запросы к API платные: оплата идёт за количество токенов (фрагментов текста) на входе и выходе. В примере используется модель claude-opus-5; на момент публикации её цена — $5 за миллион входных и $25 за миллион выходных токенов, у более дешёвых моделей цены ниже. Актуальные тарифы — на странице цен. Каждый шаг агента — отдельный запрос, и вся история диалога отправляется каждый раз заново, поэтому длинные разговоры дорожают. Для обучения установите лимит расходов в настройках аккаунта.
Пошаговая инструкция: пишем AI-агента на Python
Весь код агента находится в одном файле agent.py. Ниже он разбит на пять частей с пояснениями: вставляйте их в файл по очереди, одну за другой. Полный файл целиком — в конце раздела.
Шаг 1. Создайте проект
Если вы выполнили подготовку, у вас уже есть папка ai-task-agent с активированным окружением .venv. Откройте её в редакторе кода (например, VS Code) и создайте пустой файл agent.py. Файл tasks.json создавать не нужно: агент создаст его сам при первой записи.
Шаг 2. Установите зависимости
Проверьте, что SDK установлен именно в виртуальное окружение:
python -c "import anthropic; print(anthropic.__version__)"
Команда должна вывести номер версии, например 1.6.0. Если видите ModuleNotFoundError, окружение не активировано или библиотека установлена в другой Python — смотрите раздел «Частые ошибки».
Шаг 3. Настройте API
Убедитесь, что переменная ANTHROPIC_API_KEY задана в текущем терминале. SDK автоматически читает ключ именно из неё, поэтому в коде достаточно написать anthropic.Anthropic() — без паролей в тексте программы. Дополнительно наш main() проверяет переменную перед стартом и понятно сообщает, если её нет.
Шаг 4. Подключите языковую модель
Первая часть файла — импорты и настройки. MODEL — название модели, MAX_TOKENS — максимальная длина одного ответа, MAX_STEPS — предохранитель, который не даст агенту бесконечно вызывать инструменты.
"""AI Task Assistant — первый AI-агент на Python.
Агент получает запрос на естественном языке, сам решает, какой инструмент вызвать,
выполняет разрешённое действие со списком задач и возвращает результат.
"""
import json
import os
import sys
from datetime import date
from pathlib import Path
import anthropic
MODEL = "claude-opus-5"
MAX_TOKENS = 16000
MAX_STEPS = 5 # сколько раз подряд агент может вызывать инструменты за один запрос
TASKS_FILE = Path(__file__).with_name("tasks.json")
Шаг 5. Определите инструмент для управления задачами
Инструменты — это обычные Python-функции. Обратите внимание: каждая функция сама проверяет входные данные. Модель может ошибиться с форматом даты или передать пустое название, поэтому доверять её аргументам без проверки нельзя. Функции выбрасывают ValueError с понятным пояснением — позже этот текст вернётся модели, и она сможет исправиться.
# ---------- 1. Хранилище: обычный JSON-файл рядом со скриптом ----------
def load_tasks() -> list[dict]:
if not TASKS_FILE.exists():
return []
return json.loads(TASKS_FILE.read_text(encoding="utf-8"))
def save_tasks(tasks: list[dict]) -> None:
TASKS_FILE.write_text(
json.dumps(tasks, ensure_ascii=False, indent=2), encoding="utf-8"
)
# ---------- 2. Инструменты: обычные Python-функции с проверкой данных ----------
def add_task(title: str, due_date: str | None = None) -> dict:
"""Создаёт задачу. due_date — строка YYYY-MM-DD или None."""
if not isinstance(title, str) or not title.strip():
raise ValueError("Название задачи не может быть пустым.")
title = title.strip()
if len(title) > 200:
raise ValueError("Название задачи слишком длинное: максимум 200 символов.")
if due_date is not None:
try:
due_date = date.fromisoformat(due_date).isoformat()
except (TypeError, ValueError):
raise ValueError("Дата должна быть в формате YYYY-MM-DD.") from None
tasks = load_tasks()
task = {
"id": max((t["id"] for t in tasks), default=0) + 1,
"title": title,
"due_date": due_date,
"done": False,
}
tasks.append(task)
save_tasks(tasks)
return task
def list_tasks() -> list[dict]:
"""Возвращает все задачи."""
return load_tasks()
def complete_task(task_id: int) -> dict:
"""Отмечает задачу выполненной."""
if not isinstance(task_id, int) or isinstance(task_id, bool):
raise ValueError("task_id должен быть целым числом.")
tasks = load_tasks()
for task in tasks:
if task["id"] == task_id:
task["done"] = True
save_tasks(tasks)
return task
raise ValueError(f"Задача с id={task_id} не найдена.")
# Белый список: агент может вызывать ТОЛЬКО эти функции и ничего больше.
TOOL_FUNCTIONS = {
"add_task": add_task,
"list_tasks": list_tasks,
"complete_task": complete_task,
}
Словарь TOOL_FUNCTIONS — это белый список: агент может вызвать только эти три функции. Даже если модель «придумает» инструмент вроде run_shell, код его не найдёт и ничего не выполнит.
Дальше описываем инструменты для модели: название, пояснение, когда их использовать, и JSON Schema параметров. Параметр "strict": True включает строгий режим, в котором аргументы модели гарантированно соответствуют схеме. Там же — системная инструкция: в ней мы сообщаем модели сегодняшнюю дату (иначе она не сможет посчитать «завтра») и объясняем, как вести себя с неясными и неподдерживаемыми запросами.
# ---------- 3. Описание инструментов для модели (JSON Schema) ----------
TOOLS = [
{
"name": "add_task",
"description": (
"Добавляет новую задачу в список пользователя. Используй, когда "
"пользователь просит что-то добавить, запомнить или напомнить."
),
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "Короткое название задачи, до 200 символов.",
},
"due_date": {
"type": "string",
"format": "date",
"description": "Дедлайн в формате YYYY-MM-DD, если пользователь его назвал.",
},
},
"required": ["title"],
"additionalProperties": False,
},
},
{
"name": "list_tasks",
"description": "Возвращает все задачи пользователя с id, дедлайном и статусом.",
"strict": True,
"input_schema": {
"type": "object",
"properties": {},
"additionalProperties": False,
},
},
{
"name": "complete_task",
"description": (
"Отмечает задачу выполненной по её id. Если id неизвестен, "
"сначала вызови list_tasks."
),
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"task_id": {"type": "integer", "description": "id задачи."},
},
"required": ["task_id"],
"additionalProperties": False,
},
},
]
def system_prompt() -> str:
today = date.today()
return (
"Ты — помощник, который управляет списком задач пользователя. "
f"Сегодня {today.isoformat()} ({today.strftime('%A')}). "
"Для работы с задачами используй только предоставленные инструменты. "
"Относительные даты («завтра», «в пятницу») переводи в формат YYYY-MM-DD. "
"Если из запроса непонятно, какую именно задачу создать, задай один "
"уточняющий вопрос и ничего не создавай. Если пользователь просит "
"о том, чего твои инструменты не умеют, честно скажи об этом. "
"Отвечай коротко, на языке пользователя."
)
Шаг 6. Реализуйте цикл агента
Это сердце программы. Функция run_tool безопасно выполняет инструмент, который выбрала модель, и превращает результат или ошибку в текст. Функция run_agent реализует цикл со схемы выше:
- Отправляем модели историю диалога, системную инструкцию и описание инструментов.
- Если модель отказалась отвечать (
refusal) или ответ оборвался из-за лимита (max_tokens), останавливаемся с ошибкой. - Если модель хочет вызвать инструменты (
stop_reason == "tool_use"), выполняем каждый и возвращаем все результаты одним сообщением с теми жеtool_use_id. - Если инструменты больше не нужны, возвращаем текстовый ответ пользователю.
# ---------- 4. Выполнение инструмента, который выбрала модель ----------
def run_tool(name: str, tool_input: dict) -> tuple[str, bool]:
"""Возвращает (результат в виде текста, произошла ли ошибка)."""
func = TOOL_FUNCTIONS.get(name)
if func is None:
return f"Неизвестный инструмент: {name}", True
try:
result = func(**tool_input)
except (TypeError, ValueError) as error:
return f"Ошибка: {error}", True
return json.dumps(result, ensure_ascii=False), False
class AgentError(Exception):
"""Агент не смог завершить запрос."""
# ---------- 5. Цикл агента: модель -> инструмент -> модель -> ... ----------
def run_agent(client: anthropic.Anthropic, messages: list) -> str:
for _ in range(MAX_STEPS):
response = client.messages.create(
model=MODEL,
max_tokens=MAX_TOKENS,
system=system_prompt(),
tools=TOOLS,
messages=messages,
)
if response.stop_reason == "refusal":
raise AgentError("Модель отказалась выполнять этот запрос.")
if response.stop_reason == "max_tokens":
raise AgentError("Ответ оборвался: увеличьте MAX_TOKENS.")
# Сохраняем ответ модели полностью — вместе с блоками tool_use.
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
return "".join(b.text for b in response.content if b.type == "text")
tool_results = []
for block in response.content:
if block.type != "tool_use":
continue
print(f" [инструмент] {block.name} {json.dumps(block.input, ensure_ascii=False)}")
content, is_error = run_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": content,
"is_error": is_error,
})
# Все результаты инструментов возвращаем одним сообщением.
messages.append({"role": "user", "content": tool_results})
raise AgentError(f"Агент не справился за {MAX_STEPS} шагов.")
Ошибки инструментов не останавливают программу: они возвращаются модели с пометкой is_error: True. Получив сообщение «Дата должна быть в формате YYYY-MM-DD», модель может повторить вызов с правильной датой или уточнить дату у пользователя.
Шаг 7. Запустите приложение
Последняя часть — диалог в терминале. История сообщений хранится в списке messages, поэтому агент помнит контекст в пределах сессии. Ошибки API обрабатываются отдельно: неверный ключ и несуществующая модель завершают программу с пояснением, а временные сбои только убирают неудачный шаг из истории, чтобы диалог можно было продолжить.
# ---------- 6. Диалог в терминале ----------
def main() -> None:
if not os.environ.get("ANTHROPIC_API_KEY"):
sys.exit("Не найден ANTHROPIC_API_KEY. Задайте переменную окружения и запустите снова.")
client = anthropic.Anthropic() # ключ берётся из переменной окружения
messages: list = []
print("AI Task Assistant. Напишите запрос или «выход», чтобы завершить.")
while True:
try:
user_input = input("\nВы: ").strip()
except (EOFError, KeyboardInterrupt):
break
if user_input.lower() in {"выход", "exit", "quit"}:
break
if not user_input:
continue
start = len(messages)
messages.append({"role": "user", "content": user_input})
try:
answer = run_agent(client, messages)
except anthropic.AuthenticationError:
sys.exit("Неверный API-ключ. Проверьте ANTHROPIC_API_KEY.")
except anthropic.NotFoundError:
sys.exit(f"Модель {MODEL} не найдена. Проверьте значение MODEL.")
except (AgentError, anthropic.APIError) as error:
# Неудачный шаг убираем из истории, чтобы диалог можно было продолжить.
del messages[start:]
answer = f"Не удалось выполнить запрос: {error}"
print(f"Агент: {answer}")
if __name__ == "__main__":
main()
Сохраните файл и запустите агента:
python agent.py
Полный код agent.py одним файлом
"""AI Task Assistant — первый AI-агент на Python.
Агент получает запрос на естественном языке, сам решает, какой инструмент вызвать,
выполняет разрешённое действие со списком задач и возвращает результат.
"""
import json
import os
import sys
from datetime import date
from pathlib import Path
import anthropic
MODEL = "claude-opus-5"
MAX_TOKENS = 16000
MAX_STEPS = 5 # сколько раз подряд агент может вызывать инструменты за один запрос
TASKS_FILE = Path(__file__).with_name("tasks.json")
# ---------- 1. Хранилище: обычный JSON-файл рядом со скриптом ----------
def load_tasks() -> list[dict]:
if not TASKS_FILE.exists():
return []
return json.loads(TASKS_FILE.read_text(encoding="utf-8"))
def save_tasks(tasks: list[dict]) -> None:
TASKS_FILE.write_text(
json.dumps(tasks, ensure_ascii=False, indent=2), encoding="utf-8"
)
# ---------- 2. Инструменты: обычные Python-функции с проверкой данных ----------
def add_task(title: str, due_date: str | None = None) -> dict:
"""Создаёт задачу. due_date — строка YYYY-MM-DD или None."""
if not isinstance(title, str) or not title.strip():
raise ValueError("Название задачи не может быть пустым.")
title = title.strip()
if len(title) > 200:
raise ValueError("Название задачи слишком длинное: максимум 200 символов.")
if due_date is not None:
try:
due_date = date.fromisoformat(due_date).isoformat()
except (TypeError, ValueError):
raise ValueError("Дата должна быть в формате YYYY-MM-DD.") from None
tasks = load_tasks()
task = {
"id": max((t["id"] for t in tasks), default=0) + 1,
"title": title,
"due_date": due_date,
"done": False,
}
tasks.append(task)
save_tasks(tasks)
return task
def list_tasks() -> list[dict]:
"""Возвращает все задачи."""
return load_tasks()
def complete_task(task_id: int) -> dict:
"""Отмечает задачу выполненной."""
if not isinstance(task_id, int) or isinstance(task_id, bool):
raise ValueError("task_id должен быть целым числом.")
tasks = load_tasks()
for task in tasks:
if task["id"] == task_id:
task["done"] = True
save_tasks(tasks)
return task
raise ValueError(f"Задача с id={task_id} не найдена.")
# Белый список: агент может вызывать ТОЛЬКО эти функции и ничего больше.
TOOL_FUNCTIONS = {
"add_task": add_task,
"list_tasks": list_tasks,
"complete_task": complete_task,
}
# ---------- 3. Описание инструментов для модели (JSON Schema) ----------
TOOLS = [
{
"name": "add_task",
"description": (
"Добавляет новую задачу в список пользователя. Используй, когда "
"пользователь просит что-то добавить, запомнить или напомнить."
),
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "Короткое название задачи, до 200 символов.",
},
"due_date": {
"type": "string",
"format": "date",
"description": "Дедлайн в формате YYYY-MM-DD, если пользователь его назвал.",
},
},
"required": ["title"],
"additionalProperties": False,
},
},
{
"name": "list_tasks",
"description": "Возвращает все задачи пользователя с id, дедлайном и статусом.",
"strict": True,
"input_schema": {
"type": "object",
"properties": {},
"additionalProperties": False,
},
},
{
"name": "complete_task",
"description": (
"Отмечает задачу выполненной по её id. Если id неизвестен, "
"сначала вызови list_tasks."
),
"strict": True,
"input_schema": {
"type": "object",
"properties": {
"task_id": {"type": "integer", "description": "id задачи."},
},
"required": ["task_id"],
"additionalProperties": False,
},
},
]
def system_prompt() -> str:
today = date.today()
return (
"Ты — помощник, который управляет списком задач пользователя. "
f"Сегодня {today.isoformat()} ({today.strftime('%A')}). "
"Для работы с задачами используй только предоставленные инструменты. "
"Относительные даты («завтра», «в пятницу») переводи в формат YYYY-MM-DD. "
"Если из запроса непонятно, какую именно задачу создать, задай один "
"уточняющий вопрос и ничего не создавай. Если пользователь просит "
"о том, чего твои инструменты не умеют, честно скажи об этом. "
"Отвечай коротко, на языке пользователя."
)
# ---------- 4. Выполнение инструмента, который выбрала модель ----------
def run_tool(name: str, tool_input: dict) -> tuple[str, bool]:
"""Возвращает (результат в виде текста, произошла ли ошибка)."""
func = TOOL_FUNCTIONS.get(name)
if func is None:
return f"Неизвестный инструмент: {name}", True
try:
result = func(**tool_input)
except (TypeError, ValueError) as error:
return f"Ошибка: {error}", True
return json.dumps(result, ensure_ascii=False), False
class AgentError(Exception):
"""Агент не смог завершить запрос."""
# ---------- 5. Цикл агента: модель -> инструмент -> модель -> ... ----------
def run_agent(client: anthropic.Anthropic, messages: list) -> str:
for _ in range(MAX_STEPS):
response = client.messages.create(
model=MODEL,
max_tokens=MAX_TOKENS,
system=system_prompt(),
tools=TOOLS,
messages=messages,
)
if response.stop_reason == "refusal":
raise AgentError("Модель отказалась выполнять этот запрос.")
if response.stop_reason == "max_tokens":
raise AgentError("Ответ оборвался: увеличьте MAX_TOKENS.")
# Сохраняем ответ модели полностью — вместе с блоками tool_use.
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
return "".join(b.text for b in response.content if b.type == "text")
tool_results = []
for block in response.content:
if block.type != "tool_use":
continue
print(f" [инструмент] {block.name} {json.dumps(block.input, ensure_ascii=False)}")
content, is_error = run_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": content,
"is_error": is_error,
})
# Все результаты инструментов возвращаем одним сообщением.
messages.append({"role": "user", "content": tool_results})
raise AgentError(f"Агент не справился за {MAX_STEPS} шагов.")
# ---------- 6. Диалог в терминале ----------
def main() -> None:
if not os.environ.get("ANTHROPIC_API_KEY"):
sys.exit("Не найден ANTHROPIC_API_KEY. Задайте переменную окружения и запустите снова.")
client = anthropic.Anthropic() # ключ берётся из переменной окружения
messages: list = []
print("AI Task Assistant. Напишите запрос или «выход», чтобы завершить.")
while True:
try:
user_input = input("\nВы: ").strip()
except (EOFError, KeyboardInterrupt):
break
if user_input.lower() in {"выход", "exit", "quit"}:
break
if not user_input:
continue
start = len(messages)
messages.append({"role": "user", "content": user_input})
try:
answer = run_agent(client, messages)
except anthropic.AuthenticationError:
sys.exit("Неверный API-ключ. Проверьте ANTHROPIC_API_KEY.")
except anthropic.NotFoundError:
sys.exit(f"Модель {MODEL} не найдена. Проверьте значение MODEL.")
except (AgentError, anthropic.APIError) as error:
# Неудачный шаг убираем из истории, чтобы диалог можно было продолжить.
del messages[start:]
answer = f"Не удалось выполнить запрос: {error}"
print(f"Агент: {answer}")
if __name__ == "__main__":
main()
Шаг 8. Проверьте результат
После запуска агент ждёт запрос. Попробуйте, например, «Добавь задачу подготовить домашнее задание по Python на завтра». В терминале появится строка с инструментом, который выбрала модель, — что-то вроде [инструмент] add_task {"title": "Подготовить домашнее задание по Python", "due_date": "…"} с завтрашней датой, — а затем короткое подтверждение. Точная формулировка названия задачи и ответа зависит от модели и может отличаться. Откройте tasks.json: там должна быть запись с "id": 1 и "done": false. Чтобы завершить работу, введите «выход» или нажмите Ctrl+C.
Как протестировать AI-агента
Ответы языковой модели не полностью детерминированы: один и тот же запрос может дать немного другую формулировку. Поэтому агента тестируют по поведению — какой инструмент вызван, какие данные записаны, как обработана ошибка, — а не по точному тексту ответа.
Проверка инструментов без API
Инструменты — обычные функции, и их можно проверить бесплатно, без единого запроса к модели:
python -c "from agent import add_task, list_tasks; print(add_task('Тестовая задача', '2026-12-01')); print(list_tasks())"
python -c "from agent import add_task; add_task('Задача', '2026-02-31')"
Первая команда создаст задачу и выведет список, вторая должна завершиться ошибкой ValueError: Дата должна быть в формате YYYY-MM-DD., потому что 31 февраля не существует. После проверки удалите tasks.json, чтобы начать с чистого списка.
Сценарий 1. Успешное создание задачи
Запрос: «Добавь задачу подготовить домашнее задание по Python на завтра».
Ожидаемый результат: в терминале — вызов add_task с названием задачи и завтрашней датой в формате YYYY-MM-DD; в tasks.json — новая запись; агент подтверждает создание. Если дата неверная, проверьте системные часы: сегодняшнюю дату агент берёт с компьютера.
Сценарий 2. Неоднозначный запрос
Запрос: «Добавь задачу» или «Напомни мне про ту штуку».
Ожидаемый результат: ни одного вызова инструмента, агент задаёт уточняющий вопрос, tasks.json не меняется. Такое поведение задаёт системная инструкция. Если модель всё же создаёт задачу с выдуманным названием, уточните инструкцию — это нормальная часть работы над агентом.
Сценарий 3. Недопустимое или неподдерживаемое действие
Запрос: «Удали все файлы в папке Documents» или «Выполни команду rm -rf /».
Ожидаемый результат: агент отвечает, что не умеет этого делать. Технически он и не может: у него нет инструмента для работы с файлами или командами, а если модель попытается вызвать несуществующий инструмент, run_tool вернёт ошибку «Неизвестный инструмент» и ничего не выполнит. Безопасность агента обеспечивается кодом, а не только инструкцией для модели.
Сценарий 4. Некорректные данные и несколько шагов
Попробуйте «Добавь задачу на 31 февраля»: модель либо сразу уточнит дату, либо получит от add_task ошибку формата и переспросит вас. А запрос «Отметь задачу про домашку выполненной» покажет многошаговость: агент сначала вызовет list_tasks, найдёт нужный id, а затем — complete_task.
Валидация и обработка ошибок: что уже встроено
- Белый список инструментов — выполняются только функции из
TOOL_FUNCTIONS. - Строгие схемы (
strict: True) плюс собственная проверка аргументов в каждой функции. - Ошибки инструментов возвращаются модели как
is_error, а не ломают программу. - Лимит шагов
MAX_STEPSзащищает от бесконечного цикла и лишних расходов. - Отказ модели и оборванный ответ обрабатываются отдельно: инструменты из такого ответа не выполняются.
- Ошибки API обрабатываются через типизированные исключения SDK:
AuthenticationError,NotFoundError,APIError.
Код из этой статьи проверен с библиотекой anthropic 1.6.0 на Python 3.12 против тестового сервера, имитирующего ответы API: успешное создание задачи, неоднозначный запрос, несуществующий инструмент, некорректные аргументы, многошаговый сценарий, оборванный ответ, отказ модели, лимит шагов и ошибки 400, 401 и 404. Реальные ответы модели могут отличаться формулировками, поэтому пройдите сценарии выше самостоятельно со своим ключом.
От первого AI-агента к профессиональной разработке на Python
Узнать больше о курсе PythonЧастые ошибки начинающих
Отсутствующий или неверный API-ключ
Сообщение «Не найден ANTHROPIC_API_KEY» означает, что переменная задана в другом окне терминала или пропала после перезапуска. Задайте её снова в том же окне, где запускаете agent.py. Сообщение «Неверный API-ключ» (ошибка 401) — ключ скопирован с ошибкой, с пробелом или уже удалён в Console.
Проблемы с установкой зависимостей
ModuleNotFoundError: No module named 'anthropic'— окружение не активировано или библиотека установлена в другой интерпретатор. Активируйте.venvи устанавливайте черезpython -m pip, а не простоpip: так пакет гарантированно попадёт в тот Python, которым вы запускаете скрипт.ERROR: No matching distribution found for anthropic…— устаревшая версия Python. Текущая ветка SDK требует Python 3.10+.- На Linux
python3 -m venvсообщает об отсутствииensurepip— установите пакетpython3-venv.
Неверная конфигурация модели
Ошибка 404 с сообщением «Модель … не найдена» означает опечатку в названии модели или модель, которую уже вывели из обращения. Актуальные идентификаторы — в обзоре моделей. Ошибка 400 обычно означает некорректный запрос или проблему с аккаунтом, например недостаточный баланс, — текст ошибки подскажет причину.
Ошибки при выполнении инструментов
Если вы добавляете собственные инструменты, помните: run_tool перехватывает только TypeError и ValueError. Другие исключения, например PermissionError при записи файла, остановят программу. Это сознательное решение: неожиданную ошибку лучше увидеть сразу, чем незаметно передать модели. Когда поймёте причину, обработайте её явно.
Избыточные права
Самая опасная ошибка — дать агенту «универсальный» инструмент: выполнение команд терминала, eval() для произвольного кода или доступ ко всей файловой системе. Модель может ошибиться, а текст, который она обрабатывает, может содержать вредоносные инструкции (так называемая prompt injection). Правило простое: каждый инструмент делает одно узкое действие, проверяет свои аргументы, а необратимые операции требуют подтверждения человека.
Расходы на API
Расходы растут незаметно: каждый шаг цикла — отдельный платный запрос, а история диалога с каждым сообщением становится длиннее. Следите за расходами в Console, установите лимит, не увеличивайте MAX_STEPS без необходимости и перезапускайте агента, чтобы начать диалог с чистой историей.
Как улучшить агента
- Дополнительные инструменты. Редактирование задачи, приоритеты, фильтр по дате. Каждый новый инструмент — функция с проверкой данных плюс описание в
TOOLS. Понадобится: функции, словари, работа с датами. - Постоянное хранилище. Вместо JSON-файла — база SQLite через встроенный модуль
sqlite3, чтобы задачи не повреждались и быстро искались. Понадобится: основы SQL и работы с базами данных. - Интеграции с внешними API. Календарь, почта, Telegram-бот, который присылает напоминания. Понадобится: API, HTTP-запросы, JSON, аутентификация.
- Логирование. Модуль
loggingвместоprint: записывать каждый вызов инструмента, аргументы и ошибки, чтобы разбираться, что именно сделал агент. Понадобится: стандартная библиотека, декораторы. - Безопасность. Минимальные права, проверка всех аргументов, лимиты на количество действий, отдельные учётные записи с ограниченным доступом для интеграций. Понадобится: обработка исключений, понимание аутентификации.
- Подтверждение человеком для чувствительных действий. Например, инструмент
delete_task, который перед удалением спрашивает «Удалить задачу 3? (y/n)» и выполняется только после «y». Этот подход называют human-in-the-loop. Понадобится: условия и управление потоком программы.
Когда инструментов станет больше, стоит посмотреть на готовые решения: tool runner в SDK Anthropic берёт цикл агента на себя, а протокол MCP позволяет подключать к агенту готовые интеграции. Но именно цикл, написанный своими руками, даёт понимание того, что происходит внутри любого фреймворка. Более широкий обзор AI-инструментов для разработчиков — в статье «AI-инструменты для программистов».
Какие навыки Python нужны, чтобы создавать AI-агентов?
Посмотрите на код ещё раз: в нём нет ничего «искусственно-интеллектуального», кроме одного вызова client.messages.create. Всё остальное — обычное программирование на Python. Именно поэтому умение программировать на Python с нуля важнее знания конкретного AI-фреймворка: фреймворки меняются каждый год, а основы остаются.
| Навык | Где он в нашем агенте | Когда нужен |
|---|---|---|
| Переменные и типы данных | Настройки MODEL, MAX_STEPS, поля задачи | Сразу |
| Функции | Каждый инструмент, run_tool, run_agent | Сразу |
| Условные операторы | Проверка stop_reason и входных данных | Сразу |
| Циклы | Цикл агента и диалог в терминале | Сразу |
| Списки и словари | История messages, TOOLS, белый список инструментов | Сразу |
| Работа с файлами | Чтение и запись tasks.json | Сразу |
| JSON | Схемы инструментов, хранение задач, результаты для модели | Сразу |
| Обработка ошибок | try/except, ValueError, исключения API | Сразу |
| HTTP-запросы и API | Вызов модели (SDK делает HTTP-запрос за вас) | Для интеграций с другими сервисами |
| ООП | Класс AgentError, объект клиента SDK | Для больших агентов и фреймворков |
| Асинхронное программирование | В этом агенте не используется | Для параллельных запросов и веб-сервисов |
Как эти темы ложатся на программу курса Python в Prog Academy:
- Python Start — переменные и приведение типов, условные и булевы операторы, циклы, списки, строки, словари, функции и передача параметров, чтение и запись файлов. Это всё, что нужно, чтобы читать код нашего агента.
- Python для Data Analytics — чтение и запись JSON и CSV,
*argsи**kwargs, декораторы (в том числе для логирования), введение в ООП, обработка исключений (try…except,else,finally), базы данных и основы SQL. - Python + Django (бонус) — ООП и наследование, модули, работа с исключениями, Django, запросы и ответы, работа с базами данных, авторизация и безопасность — фундамент, чтобы превратить агента в веб-сервис.
- AI Start — практическое использование ChatGPT и Claude, промпты для разработчиков.
Асинхронного программирования в перечне тем курса нет: его обычно изучают позже, когда агент превращается в веб-сервис со многими пользователями.
Где учить Python с нуля?
Сегодня AI-ассистент сгенерирует похожий код за минуту. Зачем тогда учить язык? Потому что скопировать код и понимать код — разные навыки. Когда агент ведёт себя не так, как ожидалось, — записывает не ту дату, зацикливается, падает с исключением, — нужно прочитать трассировку ошибки, найти место, где данные изменились, и понять, виновата модель или ваш код. AI-сгенерированный код часто выглядит убедительно, но содержит неочевидные ошибки: пропущенную проверку аргументов, опасный eval(), неправильную работу с историей сообщений. Заметить их может только тот, кто знает основы.
Несколько советов, как обучение Python для начинающих превратить в реальные навыки:
- Пишите код руками. Даже этот туториал полезнее набрать, чем скопировать: ошибки при наборе учат больше, чем правильный код.
- Делайте практические задания. Чтение теории даёт ощущение понимания, а задачи показывают, настоящее ли оно. Особенно ценна обратная связь: опытный человек увидит в вашем коде то, чего не заметите вы.
- Двигайтесь от упражнений к проектам. Сначала отдельные задачи на циклы и словари, потом маленькие скрипты для себя (переименовать файлы, посчитать расходы), потом программы с API, как наш агент, и наконец — проект для портфолио.
- Используйте AI как наставника, а не как замену. Просите объяснить ошибку или незнакомую конструкцию, но решения пишите сами.
Чтобы попробовать без обязательств, начните с бесплатного курса Python или подборки книг по Python для начинающих. Если нужен системный путь, курсы Python с нуля в Prog Academy сочетают теорию, практику с преподавателем, домашние задания с обратной связью и дипломный проект. Программа курса Python Developer + AI аккредитована в ЕС, рассчитана на новичков без технического образования, длится 4,5 месяца и проходит онлайн — в группе или индивидуально. Отдельный модуль AI Start учит использовать AI-инструменты в работе разработчика.
Посмотреть программу курса Python →
Частые вопросы
Можно ли создать AI-агента без знания Python?
Простого агента можно собрать без кода в no-code платформах вроде n8n: там модель подключается к инструментам визуально — об этом подходе мы писали в полном руководстве по AI Automation. Но как только нужна собственная логика, проверка данных, интеграция с системой без готового коннектора или контроль безопасности, понадобится код. Скопировать готовый пример можно и без знаний, но исправить ошибку или изменить поведение агента без понимания Python не получится.
Сложно ли выучить Python новичку?
Python считают одним из самых удобных языков для старта: синтаксис короткий и читаемый, а первые программы работают уже в первый день. Сложность растёт постепенно — от переменных и циклов к функциям, работе с файлами, обработке ошибок и ООП. Главное — регулярная практика, а не количество прочитанной теории.
Сколько времени нужно, чтобы выучить Python?
Зависит от цели и регулярности занятий. Чтобы понимать код, как в этой статье, нужны основы: переменные, условия, циклы, функции, словари, файлы, JSON и обработка ошибок. Для работы разработчиком добавляются ООП, базы данных, фреймворки и проекты. Для ориентира: полная программа курса Python в Prog Academy рассчитана на 4,5 месяца.
Нужно ли знать машинное обучение, чтобы создавать AI-агентов?
Нет. Агент в этой статье использует готовую языковую модель через API — её не нужно обучать. Нужны навыки обычного программиста: вызывать API, работать с JSON, писать функции, проверять входные данные и обрабатывать ошибки. Машинное обучение понадобится, если вы захотите обучать или дообучать собственные модели.
Можно ли создать AI-агента бесплатно?
Python, библиотека anthropic и весь код из этой статьи бесплатны. Платные запросы к API языковой модели — оплата идёт за количество токенов. Для учебных экспериментов это обычно небольшие суммы, но стоит установить лимит расходов в аккаунте. Альтернатива — локальные открытые модели, но им нужен мощный компьютер и другая настройка.
Чем AI-агент отличается от чат-бота?
Чат-бот отвечает текстом на сообщения. AI-агент получает цель, сам решает, какой инструмент вызвать, выполняет действие (например, создаёт задачу или делает запрос к API), видит результат и решает, что делать дальше. Модель внутри может быть той же — разница в доступе к инструментам и цикле выполнения.
Какие библиотеки Python используют для AI-агентов?
Для простого агента достаточно официального SDK провайдера модели — например, anthropic, как в этой статье. Для более сложных систем используют фреймворки: LangChain и LangGraph, LlamaIndex, Pydantic AI, Claude Agent SDK или OpenAI Agents SDK. Рядом обычно работают pydantic для проверки данных, httpx или requests для HTTP-запросов и стандартные модули json, logging и sqlite3.
Где выучить Python с нуля?
Начать можно с бесплатного курса Python от Prog Academy и книг для начинающих, а для системного обучения с преподавателем, проверкой домашних заданий и проектом для портфолио — пройти курс Python Developer + AI, где программа ведёт от основ языка к ООП, базам данных и Django.
Заключение
Вы создали полноценного, хоть и маленького AI-агента: он понимает запросы обычным языком, сам выбирает один из трёх инструментов, выполняет только разрешённые действия, проверяет данные, обрабатывает ошибки и не может выйти за пределы своего белого списка. Главное, что стоит вынести из этого туториала: AI-агент — это обычная Python-программа, в которой решение «что сделать дальше» принимает языковая модель, а контроль остаётся за вашим кодом.
Следующие практические шаги: добавьте инструмент delete_task с подтверждением человеком, перенесите задачи в SQLite, замените print на logging и сохраните проект в Git — как начать, рассказывает статья «Git для начинающих». Каждое такое улучшение упирается в основы языка: функции, исключения, работу с данными, ООП.
Готовы изучать Python системно?
Курс Python Developer + AI от Prog Academy — программа, аккредитованная в ЕС: от первой программы и основ языка к ООП, базам данных, Django и AI-инструментам для разработчика. Практические задания с проверкой преподавателя, проект для портфолио, онлайн в группе или индивидуально.
Узнать больше о курсе Python