В уроке 2.3 мы создали чат с Claude в терминале. Но чат — это только начало. API можно использовать для автоматизации реальных задач: перевод текстов, анализ отзывов, генерация контента. В этом уроке мы напишем 4 полезных скрипта — каждый решает конкретную задачу. Заодно закрепим всё, что знаем: переменные, функции, файлы, циклы и API.
В предыдущих уроках мы изучали вещи по отдельности: - Python: переменные, функции, файлы (уроки 1.3-1.6) - AI: API, промпты, токены (уроки 2.1-2.5)
Теперь соединим всё вместе. Каждый скрипт в этом уроке использует и Python, и Claude API для решения задачи, которую вручную делать долго и скучно.
Что мы построим:
Скрипт 1: Переводчик файлов
Читает текст из файла → переводит через Claude → сохраняет результат
Скрипт 2: Анализатор отзывов
Читает отзывы из файла → Claude определяет тональность каждого
Скрипт 3: Генератор описаний товаров
Список товаров → Claude пишет описание для каждого
Скрипт 4: Умный обработчик CSV
Читает таблицу → Claude анализирует данные → сохраняет отчёт
Каждый скрипт — несколько десятков строк. Но они делают реальную работу, которая вручную заняла бы часы.
Убедись, что установлены библиотеки (из урока 2.3):
pip3 install anthropic python-dotenv
Файл .env в папке проекта:
ANTHROPIC_API_KEY=sk-ant-api03-твой-ключ
Базовая настройка — одинаковая для всех скриптов:
import os
from dotenv import load_dotenv
from anthropic import Anthropic
load_dotenv() # загружает API-ключ из .env
client = Anthropic() # создаёт клиент для работы с Claude
Мы уже делали это в уроке 2.3. Если что-то непонятно — вернись туда.
У тебя есть текст на русском. Нужно перевести на английский и сохранить в файл. Вручную — копировать в переводчик, ждать, копировать обратно. Скрипт делает это за секунды.
# translator.py — переводит текст из файла через Claude
import os
from dotenv import load_dotenv
from anthropic import Anthropic
load_dotenv()
client = Anthropic()
def translate(text, target_language="English"):
"""
Отправляет текст в Claude и получает перевод.
text — текст для перевода (строка)
target_language — на какой язык переводить (по умолчанию English)
"""
response = client.messages.create(
model="claude-haiku-4-5", # Haiku — быстрый и дешёвый (урок 2.5)
max_tokens=2048, # максимум токенов в ответе
messages=[{
"role": "user",
"content": f"Translate the following text to {target_language}. "
f"Return ONLY the translation, nothing else.\n\n{text}"
# f-строка (урок 1.3) — вставляем переменные прямо в текст
}]
)
return response.content[0].text
# response.content — список блоков ответа
# [0] — первый блок
# .text — текст этого блока
# === ГЛАВНАЯ ЧАСТЬ ПРОГРАММЫ ===
# Шаг 1: Читаем файл с текстом
input_file = "text_to_translate.txt"
# open() открывает файл, read() читает содержимое (урок 1.6)
with open(input_file, "r", encoding="utf-8") as f:
original_text = f.read()
print(f"Прочитан файл: {input_file}")
print(f"Длина текста: {len(original_text)} символов")
# Шаг 2: Переводим
print("Перевожу...")
translated = translate(original_text, target_language="English")
# Шаг 3: Сохраняем результат
output_file = "translated.txt"
with open(output_file, "w", encoding="utf-8") as f:
f.write(translated)
print(f"Перевод сохранён в: {output_file}")
text_to_translate.txt с любым текстом на русском:Искусственный интеллект меняет мир. Компании используют AI для автоматизации рутинных задач, анализа данных и создания новых продуктов. Через несколько лет AI-ассистенты станут такими же привычными, как смартфоны.
python3 translator.py
translated.txt — там будет перевод.def translate(text, target_language="English"):
Функция с параметром по умолчанию (урок 1.5). Если не указать язык — переведёт на английский. Но можно вызвать translate(text, "Spanish") — и переведёт на испанский.
f"Translate the following text to {target_language}. "
f"Return ONLY the translation, nothing else.\n\n{text}"
Промпт (урок 2.4). Чёткая инструкция: переведи, верни ТОЛЬКО перевод. Без этого Claude может добавить пояснения вроде «Вот перевод:».
with open(input_file, "r", encoding="utf-8") as f:
original_text = f.read()
Чтение файла (урок 1.6). encoding="utf-8" — чтобы кириллица читалась правильно.
У тебя список отзывов клиентов. Нужно понять: какие позитивные, какие негативные, какие нейтральные. Вручную — читать каждый и решать. При 100 отзывах — это час работы. Скрипт делает это за минуту.
# review_analyzer.py — анализирует тональность отзывов
import os
import json
from dotenv import load_dotenv
from anthropic import Anthropic
load_dotenv()
client = Anthropic()
def analyze_review(review_text):
"""
Отправляет отзыв в Claude → получает тональность.
Возвращает словарь: {"sentiment": "positive/negative/neutral", "summary": "..."}
"""
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=200,
messages=[{
"role": "user",
"content": f"""Analyze this customer review. Respond in JSON format:
{{"sentiment": "positive" or "negative" or "neutral", "summary": "one sentence summary in Russian"}}
Review: {review_text}"""
# Двойные фигурные скобки {{ }} — чтобы Python не путал их
# с f-строковыми подстановками {review_text}
}]
)
# Парсим JSON из ответа Claude
result = json.loads(response.content[0].text)
# json.loads() превращает строку JSON в словарь Python (урок 1.6)
return result
# === ГЛАВНАЯ ЧАСТЬ ===
# Список отзывов (в реальном проекте — из файла или базы данных)
reviews = [
"Отличный магазин! Заказ пришёл на следующий день, всё целое.",
"Ужасное обслуживание. Ждала посылку 3 недели, никто не отвечал.",
"Нормально, но упаковка могла бы быть лучше.",
"Качество супер, но доставка дорогая. В целом доволен.",
"Больше никогда не закажу. Товар не соответствует описанию.",
"Быстро, удобно, рекомендую!",
"Средненько. Ничего особенного.",
]
# Счётчики для статистики
stats = {"positive": 0, "negative": 0, "neutral": 0}
print("=== Анализ отзывов ===\n")
# Проходим по каждому отзыву (цикл for — урок 1.4)
for i, review in enumerate(reviews, 1):
# enumerate(reviews, 1) — нумерация с 1
# i = номер, review = текст отзыва
result = analyze_review(review)
sentiment = result["sentiment"]
summary = result["summary"]
# Обновляем статистику
stats[sentiment] += 1
# stats["positive"] += 1 — увеличиваем счётчик на 1
# Выводим результат
print(f" #{i}: [{sentiment.upper():8s}] {summary}")
# :8s — форматирование: текст занимает минимум 8 символов (для ровных колонок)
print(f"\n=== Статистика ===")
print(f" Позитивных: {stats['positive']}")
print(f" Негативных: {stats['negative']}")
print(f" Нейтральных: {stats['neutral']}")
total = len(reviews)
positive_pct = stats["positive"] / total * 100
print(f"\n Позитивных отзывов: {positive_pct:.0f}%")
# :.0f — форматирование числа: 0 знаков после запятой
=== Анализ отзывов ===
#1: [POSITIVE] Быстрая доставка, товар в порядке.
#2: [NEGATIVE] Долгая доставка и отсутствие поддержки.
#3: [NEUTRAL ] Средняя оценка, замечание к упаковке.
#4: [POSITIVE] Хорошее качество, но дорогая доставка.
#5: [NEGATIVE] Товар не соответствует описанию.
#6: [POSITIVE] Быстро и удобно.
#7: [NEUTRAL ] Ничего особенного.
=== Статистика ===
Позитивных: 3
Негативных: 2
Нейтральных: 2
Позитивных отзывов: 43%
json.loads(response.content[0].text)
Claude возвращает строку '{"sentiment": "positive", "summary": "..."}'. json.loads() превращает эту строку в словарь Python, чтобы можно было обращаться к полям: result["sentiment"].
for i, review in enumerate(reviews, 1):
enumerate() — функция Python, которая добавляет нумерацию. Без неё у тебя только review (текст). С ней — i (номер) и review (текст). 1 — начать нумерацию с единицы, а не с нуля.
stats[sentiment] += 1
+= — сокращение для «прибавить». stats["positive"] += 1 — то же самое, что stats["positive"] = stats["positive"] + 1.
У тебя список товаров с характеристиками. Нужно написать привлекательное описание для сайта. Вручную — 5-10 минут на товар. При 50 товарах — целый день. Скрипт генерирует все за несколько минут.
# product_descriptions.py — генерирует описания товаров для сайта
import os
from dotenv import load_dotenv
from anthropic import Anthropic
load_dotenv()
client = Anthropic()
def generate_description(product):
"""
Генерирует описание товара для сайта.
product — словарь с полями: name, category, features, price
"""
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=300,
messages=[{
"role": "user",
"content": f"""Напиши короткое продающее описание товара для интернет-магазина.
2-3 предложения, дружелюбный тон, упомяни ключевые преимущества.
Товар: {product['name']}
Категория: {product['category']}
Характеристики: {product['features']}
Цена: {product['price']} руб."""
}]
)
return response.content[0].text
# === СПИСОК ТОВАРОВ ===
# Список словарей (урок 1.3: словари, урок 1.4: списки)
products = [
{
"name": "Беспроводные наушники AirSound Pro",
"category": "Электроника",
"features": "Bluetooth 5.3, шумоподавление, 24 часа работы, быстрая зарядка",
"price": 4990
},
{
"name": "Рюкзак Urban Explorer",
"category": "Аксессуары",
"features": "30 литров, водоотталкивающий, отделение для ноутбука, USB-порт",
"price": 3490
},
{
"name": "Умная колонка HomeVoice",
"category": "Умный дом",
"features": "Голосовой ассистент, Wi-Fi, Bluetooth, стерео звук, таймеры",
"price": 5990
},
]
# === ГЕНЕРИРУЕМ ОПИСАНИЯ ===
print("=== Генерация описаний товаров ===\n")
# Открываем файл для записи всех описаний
with open("descriptions.txt", "w", encoding="utf-8") as f:
for product in products:
print(f"Генерирую: {product['name']}...")
description = generate_description(product)
# Выводим на экран
print(f"\n {product['name']} — {product['price']} руб.")
print(f" {description}\n")
# Записываем в файл
f.write(f"## {product['name']} — {product['price']} руб.\n\n")
f.write(f"{description}\n\n")
f.write("---\n\n")
print("Все описания сохранены в descriptions.txt")
product['name']
Обращение к значению в словаре по ключу (урок 1.3). product — это словарь с ключами name, category, features, price.
with open("descriptions.txt", "w", encoding="utf-8") as f:
for product in products:
...
f.write(...)
Файл открывается один раз перед циклом. Внутри цикла каждое описание дописывается в тот же файл. Когда цикл завершится, файл закроется автоматически (так работает with — урок 1.6).
У тебя таблица с данными (расходы, продажи, обращения). Нужно проанализировать и написать отчёт. Скрипт читает CSV-файл, отправляет данные в Claude и получает анализ.
CSV (Comma-Separated Values) — формат таблицы в текстовом файле. Как Excel, но без оформления. Каждая строка — строка таблицы. Значения разделены запятыми.
Пример файла expenses.csv:
дата,категория,сумма,описание
2025-03-01,еда,1500,Продукты на неделю
2025-03-02,транспорт,350,Такси до работы
2025-03-03,еда,800,Обед с коллегами
2025-03-04,развлечения,2000,Кино и ужин
2025-03-05,еда,1200,Продукты
2025-03-06,транспорт,200,Метро
2025-03-07,здоровье,3500,Стоматолог
# expense_analyzer.py — анализирует расходы из CSV-файла
import os
import csv
from dotenv import load_dotenv
from anthropic import Anthropic
load_dotenv()
client = Anthropic()
# === ШАГ 1: ЧИТАЕМ CSV ===
expenses = [] # список для хранения всех строк
with open("expenses.csv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f)
# csv.DictReader — читает CSV и превращает каждую строку в словарь
# Первая строка (дата,категория,сумма,описание) становится ключами
# Каждая следующая строка — словарь:
# {"дата": "2025-03-01", "категория": "еда", "сумма": "1500", ...}
for row in reader:
expenses.append(row)
# append() добавляет элемент в конец списка (урок 1.4)
print(f"Прочитано {len(expenses)} записей из expenses.csv")
# === ШАГ 2: СЧИТАЕМ СТАТИСТИКУ (Python, без Claude) ===
total = 0
by_category = {} # словарь: категория → сумма
for expense in expenses:
amount = int(expense["сумма"])
# int() превращает строку "1500" в число 1500
# CSV хранит всё как текст — нужно конвертировать
category = expense["категория"]
total += amount
# Если категория уже есть — прибавляем. Если нет — создаём.
if category in by_category:
by_category[category] += amount
else:
by_category[category] = amount
print(f"Общая сумма расходов: {total} руб.")
print(f"По категориям: {by_category}")
# === ШАГ 3: ПРОСИМ CLAUDE ПРОАНАЛИЗИРОВАТЬ ===
# Формируем текст с данными для Claude
data_summary = f"""
Период: {expenses[0]['дата']} — {expenses[-1]['дата']}
Общая сумма: {total} руб.
Количество транзакций: {len(expenses)}
Расходы по категориям:
"""
for category, amount in by_category.items():
# .items() возвращает пары (ключ, значение) из словаря
percentage = amount / total * 100
data_summary += f" {category}: {amount} руб. ({percentage:.1f}%)\n"
# Отправляем в Claude
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=500,
messages=[{
"role": "user",
"content": f"""Проанализируй мои расходы. Дай короткий отчёт:
1. На что уходит больше всего
2. Что можно оптимизировать
3. Общая оценка
Данные:
{data_summary}"""
}]
)
analysis = response.content[0].text
# === ШАГ 4: СОХРАНЯЕМ ОТЧЁТ ===
with open("expense_report.txt", "w", encoding="utf-8") as f:
f.write("=== ОТЧЁТ О РАСХОДАХ ===\n\n")
f.write(f"Период: {expenses[0]['дата']} — {expenses[-1]['дата']}\n")
f.write(f"Общая сумма: {total} руб.\n\n")
f.write("--- По категориям ---\n")
for category, amount in by_category.items():
f.write(f" {category}: {amount} руб.\n")
f.write(f"\n--- Анализ от Claude ---\n\n")
f.write(analysis)
f.write("\n")
print(f"\nОтчёт сохранён в expense_report.txt")
print(f"\n{analysis}")
expenses.csv (содержимое выше)python3 expense_analyzer.pyexpense_report.txtimport csv
Встроенный модуль Python для работы с CSV-файлами. Не нужно устанавливать через pip — он уже есть в Python.
reader = csv.DictReader(f)
DictReader читает CSV и превращает каждую строку в словарь. Первая строка файла — это ключи (дата, категория, сумма, описание). Каждая следующая строка — значения.
expenses[-1]['дата']
[-1] — последний элемент списка. expenses[0] — первый, expenses[-1] — последний. Так мы получаем дату первой и последней записи.
for category, amount in by_category.items():
.items() возвращает пары из словаря. Если by_category = {"еда": 3500, "транспорт": 550}, то цикл пройдёт по парам: ("еда", 3500), ("транспорт", 550).
Заметь: все 4 скрипта построены по одной схеме:
1. ПРОЧИТАТЬ данные (из файла, списка, CSV)
│
▼
2. ОБРАБОТАТЬ через Claude API (перевод, анализ, генерация)
│
▼
3. СОХРАНИТЬ результат (в файл, на экран)
Это базовый паттерн AI-автоматизации: вход → обработка → выход. Он встречается везде:
Бот поддержки: сообщение клиента → Claude → ответ
RAG-система: вопрос → поиск + Claude → ответ с источниками
Анализатор: данные → Claude → отчёт
Генератор: параметры → Claude → контент
В Этапе 3 мы усложним этот паттерн: добавим инструменты (Claude сам решает, что прочитать), цикл (Claude делает несколько шагов) и память (Claude помнит предыдущие действия). Но основа — та же самая.
Здесь собраны ошибки, которые чаще всего встречаются при написании скриптов с API. Сохрани эту страницу — пригодится в следующих уроках.
anthropic.AuthenticationError: Error code: 401
Причина: неправильный API-ключ или его нет.
Что проверить:
1. Файл .env существует в папке проекта
2. В нём ANTHROPIC_API_KEY=sk-ant-api03-... (без пробелов вокруг =)
3. Ключ скопирован полностью (не обрезан)
4. load_dotenv() вызывается ДО создания клиента
ModuleNotFoundError: No module named 'anthropic'
Причина: библиотека не установлена.
Решение:
pip3 install anthropic (macOS)
pip install anthropic (Windows)
Если используешь виртуальное окружение — убедись, что оно активировано:
source venv/bin/activate (macOS)
venv\Scripts\activate (Windows)
FileNotFoundError: [Errno 2] No such file or directory: 'text_to_translate.txt'
Причина: файл не найден. Либо его нет, либо ты запускаешь скрипт из другой папки.
Решение:
1. Убедись, что файл существует
2. Убедись, что ты в правильной папке:
pwd (macOS) — покажет текущую папку
cd ~/Documents/Projects/ai-academy — перейти в нужную
3. Или укажи полный путь к файлу:
"/Users/katya/Documents/text.txt" вместо "text.txt"
json.decoder.JSONDecodeError: Expecting value: line 1 column 1
Причина: Claude вернул не чистый JSON, а текст с пояснениями.
Что Claude вернул:
"Вот результат анализа: {"sentiment": "positive"}"
^^^^^^^^^^^^^^^^^^^^^^^^ — это лишний текст
Решение: улучшить промпт
Плохо: "Проанализируй отзыв"
Хорошо: "Respond in JSON format ONLY. No other text."
anthropic.RateLimitError: Error code: 429
Причина: слишком много запросов за короткое время.
Решение:
Добавь паузу между запросами в цикле:
import time
for review in reviews:
result = analyze_review(review)
time.sleep(1) # ждём 1 секунду между запросами
Возьми любой текст (статью, описание, пост) и переведи через translator.py. Попробуй перевести на разные языки: English, Spanish, French, Chinese.
Добавь 10 своих отзывов в review_analyzer.py (можно скопировать с Wildberries, Ozon или любого магазина). Посмотри, правильно ли Claude определяет тональность.
Придумай свою задачу и напиши скрипт по паттерну «вход → Claude → выход». Примеры: - Генератор постов для соцсетей (список тем → посты) - Анализатор резюме (текст резюме → оценка и советы) - Корректор текста (текст с ошибками → исправленный текст)
Задача 1: По какому паттерну работают все скрипты в этом уроке?
Задача 2: Почему в скрипте с отзывами мы используем json.loads(), а не просто читаем текст ответа?
Задача 3: Что делает enumerate(reviews, 1)?
Задача 4: Почему в скрипте с CSV мы делаем int(expense["сумма"]), а не просто используем expense["сумма"]?
| Термин | Что значит |
|---|---|
| CSV | Comma-Separated Values — табличный формат файла, где значения разделены запятыми. Как Excel, но текстовый |
| csv.DictReader | Функция Python, которая читает CSV и превращает каждую строку в словарь |
| enumerate() | Функция Python, которая добавляет нумерацию к элементам списка при переборе в цикле |
| json.loads() | Функция, которая превращает строку JSON в словарь Python. loads = load string |
| json.dumps() | Функция, которая превращает словарь Python в строку JSON. dumps = dump string |
| f-строка | Строка с f перед кавычками: f"Привет, {name}!". Позволяет вставлять переменные прямо в текст |
| append() | Метод списка: добавляет элемент в конец. my_list.append("новый") |
| items() | Метод словаря: возвращает пары (ключ, значение). Для перебора в цикле |
| Параметр по умолчанию | Значение аргумента функции, если его не передали: def f(x, lang="en") |
| Паттерн | Повторяющийся шаблон решения. «Вход → обработка → выход» — паттерн AI-скриптов |
| RateLimitError | Ошибка: слишком много запросов к API за короткое время. Решение: добавить паузу |
| time.sleep() | Функция Python: пауза на N секунд. time.sleep(1) — ждать 1 секунду |
Все AI-скрипты работают по одному паттерну:
ВХОД → ОБРАБОТКА (Claude API) → ВЫХОД
Этот паттерн масштабируется:
Один текст → translate() → один перевод
100 отзывов → analyze_review()→ таблица тональностей
Список товаров → generate() → описания для сайта
CSV с данными → analyze() → отчёт
Python читает и готовит данные.
Claude думает и генерирует.
Python сохраняет результат.
Частые ошибки:
AuthenticationError → проверь .env и API-ключ
ModuleNotFoundError → pip install anthropic
FileNotFoundError → проверь путь к файлу
JSONDecodeError → улучши промпт ("JSON only")
RateLimitError → добавь time.sleep(1) между запросами
Ты написала 4 скрипта, которые делают реальную работу. Каждый из них — прямая линия: данные → Claude → результат. Но что если программа должна сама решать, какие данные нужны и что делать дальше? Не ты говоришь «переведи файл» — а программа сама находит файл, решает, что с ним делать, и действует. Это и есть AI-агент — тема Этапа 3.