Перейти к основному контенту

Учебник по API Claude Fable 5.1: создаём долгоработающего агента‑разработчика на Python

Узнайте, как использовать флагманскую модель Anthropic для построения Python‑агента, который читает репозиторий Flask перед планированием изменений. Добавьте обновления прогресса, инструменты чтения файлов и контроль стоимости.
Обновлено 3 сент. 2026 г.  · 15 мин читать

Изучить с помощью AI

ChatGPTClaudePerplexity

Когда я пробую новую модель через API-вызов, первый ответ говорит очень мало. Мой первый запуск Fable 5.1 вернул корректную структуру и общий план. Мне нужно было понять, что будет дальше, когда диалог разрастётся: сможет ли приложение сохранять историю в целости, просматривать файлы, не выходя за пределы проекта, сообщать о прогрессе и показывать, откуда возникла стоимость?

Наша обзорная статья по Claude Fable 5.1 охватывает запуск, бенчмарки и сравнение моделей в целом. Здесь мы начнём с небольшого вызова на Python и построим вокруг него петлю агента. Итоговый агент принимает запрос на функцию, читает проект Flask и возвращает план, привязанный к файлам, которые он действительно просмотрел.

Мы разберём, как:

  • Сделать вызов API Claude Fable 5.1 и безопасно читать блоки контента
  • Установить степень рассуждений (effort) и менять её по ходу диалога (бета)
  • Ограничить системную инструкцию одним ходом (бета)
  • Вернуть структурированный план с Pydantic
  • Добавить инструменты репозитория только для чтения с границей корня проекта
  • Запустить многоходовую петлю инструментов
  • Читать обновления прогресса агента между вызовами инструментов (бета)
  • Сохранять валидность thinking-блоков при истории только-добавление
  • Кэшировать повторяющийся контекст и оценивать стоимость запроса по опубликованным тарифам
  • Обрабатывать отказы и публиковать агента через FastAPI

Бета-функции используют датированные заголовки — перед релизом сверьтесь с документацией Anthropic.

Сколько стоит запускать Claude Fable 5.1 в петле агента?

Агент на каждом ходу пересылает один и тот же системный промпт, определения инструментов и контекст репозитория, поэтому ставка, которая формирует счёт, — это чтение из кэша, а не ставка на ввод.

Fable 5.1 стоит $10 за миллион входных токенов и $50 за миллион выходных токенов — без изменений по сравнению с Fable 5. Чтение из кэша — $0.25 за миллион (снижение с $1), а запись в кэш на пять минут остаётся $12.50 за миллион. В нашем руководстве по Claude Fable 5.1 есть полная таблица тарифов и оценки экономии от Anthropic.

Чтение кэшированного префикса дешёвое. Запись — нет, она в 50 раз дороже чтения, поэтому петля окупается, когда префикс читается обратно несколько раз. Далее мы разберём разбивку стоимости на реальном прогоне и увидим, какая категория реально доминировала.

Потолок по токенам задаёт модель, а не ваш бюджет. Fable 5.1 даёт контекстное окно в 1 млн токенов с до 128K выходных токенов на ответ, а max_tokens — это жёсткий лимит одновременно на «мышление» и текст ответа. При высоком effort нужно место и для того, и для другого, поэтому в петле ниже задано 16 000, а не «круглое» значение.

Хранение данных, приоритетный уровень и водяные знаки

Есть несколько деталей доступа, которые важно учесть до написания кода. Две из них полностью остановят ваши запросы:

  • Fable 5.1 требует хранение данных 30 дней и недоступен при нулевом хранении, если только Anthropic не открыл доступ. Запрос из несовместимого рабочего пространства вернёт 400 invalid_request_error без иных подсказок.

  • Модель не поддерживается на Priority Tier. Fable 5 поддерживается, поэтому это часто ловушка при миграции.

  • Текстовый вывод Fable 5.1 имеет текстовый водяной знак Anthropic. Токены не добавляет и не требует изменений запроса.

Используйте Claude Fable 5.1 через API, чтобы собрать агента‑разработчика с контекстом репозитория

Наш рабочий процесс состоит из двух этапов:

  1. Ограниченная петля инспекции читает разрешённые файлы проекта.
  2. Финальный запрос с структурированными ответами превращает этот контекст в план. 

Пример — небольшой Flask JSON API для сохранения и поиска закладок с фабрикой приложения, тремя блюпринтами, модулем конфигурации, моделями и pytest-набором. В качестве задачи я использую лимитирование запросов, потому что агенту нужно посмотреть настройку приложения, маршруты, конфиг и тесты, прежде чем он сможет определить нужные файлы и проверки. Полный код и пример проекта доступны в репозитории на GitHub.

Диаграмма: запрос на функцию проходит через агента Claude Fable 5.1, белый список путей и пример проекта, после чего возвращается структурированный план

Запросы попадают к файлам через одну границу. Изображение автора.

Агент может использовать только три инструмента: list_project_files, read_project_file и get_project_metadata. Claude никогда не обращается к файловой системе напрямую. Он запрашивает путь, а ваш код решает, разрешён ли он.

Настройка API Claude Fable 5.1 в Python

Начните с отдельного окружения Python и храните ключ API на сервере.

Необходимые условия

Нужен Python 3.10+ и ключ Anthropic API с доступом к claude-fable-5-1

Чтобы создать ключ API, войдите в консоль Claude, откройте страницу ключей, нажмите Create key и скопируйте ключ. Лучше дать имя, помогающее вспомнить назначение, выбрать срок действия и сохранить ключ безопасно.

Установка SDK и добавление ключа API

Создайте виртуальное окружение и установите пакеты:

python -m venv .venv
source .venv/bin/activate          # macOS или Linux
.venv\Scripts\Activate.ps1         # Windows PowerShell
pip install anthropic==1.3.0 pydantic fastapi uvicorn python-dotenv

Держите версию SDK закреплённой, потому что бета-функции часто меняются. Обновления прогресса требуют как минимум 1.1.0, а примеры используют 1.3.0.

Поместите ключ в .env-файл и добавьте .env в .gitignore до первого коммита. Он должен быть на сервере под вашим контролем, никогда — в браузере или доступном репозитории. Утечка может привести к несанкционированному использованию API и расходам по вводу, выводу и операциям кэша.

ANTHROPIC_API_KEY=sk-ant-your-key-here

После этого клиент сам найдёт ключ.

Сделайте первый вызов API Claude Fable 5.1 на Python

Отправьте самый маленький API‑запрос, прежде чем наращивать функциональность.

Отправьте первый API‑запрос

Инициализируйте клиент, отправьте одно сообщение пользователя и выведите метаданные ответа:

from anthropic import Anthropic
from dotenv import load_dotenv

load_dotenv()

client = Anthropic()
MODEL = "claude-fable-5-1"

response = client.messages.create(
    model=MODEL,
    max_tokens=512,
    messages=[{"role": "user", "content": "Reply in one sentence to confirm the API connection is working."}],
)

text = next((b.text for b in response.content if b.type == "text"), None)
print(text if text is not None else f"No text returned ({response.stop_reason})")
print(f"Model: {response.model}")
print(f"Stop reason: {response.stop_reason}")
print(f"Input tokens: {response.usage.input_tokens}")
print(f"Output tokens: {response.usage.output_tokens}")
print(f"Request ID: {response._request_id}")

Терминал показывает ответ Claude Fable 5.1 API с ID модели, причиной остановки, числом токенов и ID запроса

Первый вызов возвращает текст и метаданные. Изображение автора.

Вызов next(...) выбирает первый текстовый блок. Адаптивное «мышление» всегда включено и не может быть отключено, поэтому ответ может начинаться с thinking‑блока; отправка thinking: {"type": "disabled"} вернёт 400, а не выключит его. Когда первым идёт thinking‑блок, обращение к response.content[0].text вызовет исключение.

Решение — фильтровать по типу блока, а не полагаться на фиксированную позицию. Логируйте и response._request_id, поскольку поддержка Anthropic использует его для трассировки запроса.

Вот запрос, использованный в примерах планирования и effort. Он требует, чтобы агент просмотрел несколько файлов:

feature_request = (
    "Add rate limiting to the public API endpoints so one client cannot exhaust "
    "the search endpoint or brute force the token endpoint."
)

Сохраняйте этот текст неизменным при сравнении уровней effort и числа токенов. Тогда результаты будут описывать настройки API, а не другой промпт.

Задайте степень рассуждений через output_config

Настройте effort через output_config. Допустимы low, medium, high, xhigh и max. По умолчанию API использует high.

response = client.messages.create(
    model=MODEL,
    max_tokens=8192,
    output_config={"effort": "high"},
    messages=[{"role": "user", "content": feature_request}],
)

Effort может влиять на расход токенов, поведение инструментов и задержку. Я прогнал один и тот же запрос функции трижды на каждом из четырёх уровней effort; в таблице — средние значения:

Effort

Секунды

Thinking‑токены

Всего выходных токенов

Стоимость

low

7.7

111

173

$0.0093

medium

8.1

129

186

$0.0099

high

7.9

136

199

$0.0106

xhigh

20.0

151

1,764

$0.0888

Thinking‑токены включены во «всего выходных», так что не складывайте эти столбцы. В этих прогонах low, medium и high были близки по задержке и стоимости.

xhigh занял в два с половиной раза больше времени, выдал почти в девять раз больше выходных токенов и стоил в восемь раз дороже. 

Вывод: Начинайте с high, опускайтесь до medium для рутинных шагов и поднимайте уровень только когда ваши тесты показывают измеримое улучшение. На low модель может отвечать «по памяти», не вызывая инструмент извлечения. Если ходу нужна свежая информация, скажите об этом или поднимите уровень.

Ограничьте область агента системным промптом

Системный промпт определяет поведение агента:

SYSTEM_PROMPT = """You are a senior engineer who turns feature requests into implementation plans for an existing codebase.

Stay inside the requested feature. Do not propose unrelated refactors, dependency upgrades, or style changes.

If a file or dependency you need does not exist, say so plainly instead of inventing it.

Write in plain sentences and do not use em dashes.

Finish with concrete guidance: what changes, where, in what order, what could break, and which tests to add."""

В рекомендациях по промптам Anthropic отмечает, что модель может расширять задачу или останавливаться слишком рано. Промпт велит держаться рамок и заканчивать конкретными указаниями. Схема позже задаст формат вывода.

Верните структурированный план с Pydantic

Определите план через Pydantic, чтобы приложение могло валидировать его и передавать дальше:

from pydantic import BaseModel, Field

class FeaturePlan(BaseModel):
    summary: str = Field(description="One or two sentences on what will be built.")
    implementation_steps: list[str]
    files_to_modify: list[str]
    risks: list[str]
    tests: list[str]

response = client.messages.parse(
    model=MODEL,
    max_tokens=8192,
    system=SYSTEM_PROMPT,
    messages=[{"role": "user", "content": feature_request}],
    output_format=FeaturePlan,
)

if response.stop_reason == "refusal":
    category = (
        response.stop_details.category
        if response.stop_details and response.stop_details.category
        else "unspecified"
    )
    print(f"Declined: {category}")
elif response.parsed_output is None:
    print(f"No plan. Stop reason: {response.stop_reason}")
else:
    print(response.parsed_output.summary)

messages.parse() преобразует модель Pydantic в JSON‑схему, отправляет её, валидирует ответ и возвращает типизированный объект в parsed_output. Структурированные ответы доступны в общем режиме, без бета‑заголовков. Сначала проверяйте stop_reason, потому что при отказе (ниже) схема пропускается, и парсить нечего.

Тот общий результат из введения сделал одну вещь правильно: он не называл файлов, которых не видел. Схема валидирует структуру, а не фактическую обоснованность.

Claude Fable 5.1 против Fable 5: изменения при миграции API

Прежде чем добавлять инструменты, учтите запрет на принудительный выбор инструмента, совместимость thinking‑блоков и историю только-добавление.

  • Fable 5.1 отклоняет принудительный выбор инструмента. В разделе про петлю инструментов ниже показана ошибка и использованная конфигурация auto.

  • Thinking‑блоки совместимы только в одну сторону. Fable 5.1 читает блоки из более ранних моделей Claude, но более ранние модели не могут читать его блоки. 

Когда роутер или фолбэк переводит диалог на более старую модель, API удаляет несовместимые блоки до того, как целевая модель их увидит. Остальная история сохраняется, но старшая модель планирует без этих блоков.

Редактирование ранних ходов инвалидирует thinking‑блоки, которые шли после них. Это может ломать обрезку истории и клиентскую суммаризацию.

Полный набор изменений — в руководстве по миграции.

Добавьте инструменты репозитория только для чтения

Теперь дайте модели контекст репозитория через инструменты только для чтения.

Определите инструменты только для чтения

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

Ограничьте пути корнем проекта

Только чтение — не значит безопасно. Модель так же легко запросит ../../.env как и config.py, поэтому защита должна быть в вашем коде, а не в промпте:

def _resolve(self, relative_path: str) -> Path:
    relative = Path(relative_path)
    if relative.is_absolute() or relative.drive:
        raise ToolError(f"path is outside the project root: {relative_path}")

    cursor = self.root
    for part in relative.parts:
        cursor /= part
        if cursor.is_symlink():
            raise ToolError(f"symlinks are not followed: {relative_path}")

    candidate = (self.root / relative).resolve()

    # After resolving "..", the path still has to sit under the allowed root.
    if candidate != self.root and self.root not in candidate.parents:
        raise ToolError(f"path is outside the project root: {relative_path}")
    if candidate.name in DENY_NAMES:
        raise ToolError(f"reading {candidate.name} is not allowed")

    return candidate

Отклоняйте абсолютные пути и компоненты‑симлинки, затем резолвьте путь и подтверждайте, что он остаётся под корнем проекта. Запрос ../.env вернёт «path is outside the project root». Ошибка инструмента позволяет агенту продолжить с разрешёнными файлами.

Определите строгие схемы инструментов

Класс‑ридер контролирует, что Python может открыть. Claude также нужны JSON‑схемы, описывающие три действия, которые он может запросить:

EMPTY_SCHEMA = {
    "type": "object",
    "properties": {},
    "additionalProperties": False,
}

TOOLS = [
    {
        "name": "list_project_files",
        "description": "List readable text files in the project.",
        "input_schema": EMPTY_SCHEMA,
        "strict": True,
    },
    {
        "name": "read_project_file",
        "description": "Read one text file relative to the project root.",
        "input_schema": {
            "type": "object",
            "properties": {"path": {"type": "string"}},
            "required": ["path"],
            "additionalProperties": False,
        },
        "strict": True,
    },
    {
        "name": "get_project_metadata",
        "description": "Read project metadata and dependency manifests.",
        "input_schema": EMPTY_SCHEMA,
        "strict": True,
    },
]

strict проверяет аргументы, когда модель выбирает инструмент. Он не принуждает к вызову инструмента — это важно для Fable 5.1.

Запустите многоходовую петлю инструментов

Начните с базовой петли: отправьте инструменты, проверьте stop_reason, выполните запрошенное, добавьте результаты и повторите.

MAX_AGENT_TURNS = 8
reader = ProjectReader("sample_project")
messages = [{"role": "user", "content": feature_request}]

for turn in range(1, MAX_AGENT_TURNS + 1):
    response = client.messages.create(
        model=MODEL,
        max_tokens=16000,
        system=SYSTEM_PROMPT,
        tools=TOOLS,
        messages=messages,
    )

    if response.stop_reason == "refusal":
        return declined(response.stop_details.category)
    if response.stop_reason == "max_tokens":
        return cutoff()
    if response.stop_reason != "tool_use":
        messages.append({"role": "assistant", "content": response.content})
        break

    messages.append({"role": "assistant", "content": response.content})
    results = []
    for block in response.content:
        if block.type != "tool_use":
            continue
        output, is_error = reader.run(block.name, block.input)
        results.append({
            "type": "tool_result",
            "tool_use_id": block.id,
            "content": output,
            "is_error": is_error,
        })

    messages.append({"role": "user", "content": results})
else:
    return turn_limit()

MAX_AGENT_TURNS ограничивает запросы модели, а не расходы, поэтому при необходимости введите отдельный лимит по стоимости. Петля напрямую обрабатывает refusal, max_tokens и tool_use ; иные причины завершения останавливают этап инспекции. Поле is_error сообщает модели, что путь был отклонён, чтобы она выбрала другое действие.

Почему принудительный выбор инструмента возвращает 400

В Fable 5 можно было принудить первый вызов через tool_choice: {"type": "any"}. Fable 5.1 вернёт такую ошибку до выполнения запроса:

tool_choice: type "tool" and "any" are not supported for this model.

Принудительные вызовы обходили всегда включённое «мышление». Оставьте tool_choice на auto, используйте строгие схемы выше и упоминайте инструменты в промпте, когда шагу он нужен.

Fable 5.1 иногда делает по одному вызову инструмента за ход, тогда как Fable 5 группировал несколько. Это добавляет обменов. Добавьте в промпт строку: «Запрашивайте независимые файлы в одном и том же ходе, а не по одному за ход». В одном прогоне было сгруппировано девять независимых запросов, хотя число варьируется.

Стриминг ответов и обновлений прогресса Claude Fable 5.1

Стриминг текста отдаёт содержимое по мере генерации; обновления прогресса покрывают паузы между вызовами инструментов.

Стримьте текстовые ответы

В полном проекте используется context_system() для объединения SYSTEM_PROMPT с кратким описанием проекта перед запуском стрима:

with client.messages.stream(
    model=MODEL,
    max_tokens=8192,
    system=context_system(),
    messages=[{"role": "user", "content": feature_request}],
) as stream:
    for chunk in stream.text_stream:
        print(chunk, end="", flush=True)
    final = stream.get_final_message()

print(f"\nOutput tokens: {final.usage.output_tokens}")

get_final_message() даёт собранное сообщение с usage и причиной остановки после завершения стрима. Стрим‑чанки не гарантируют полный JSON, поэтому дождитесь финального сообщения перед парсингом.

Показывайте прогресс между вызовами инструментов

Стриминг текста не покрывает задержки во время вызовов инструментов. Fable 5.1 может писать короткие обновления прогресса перед вызовами инструментов. При значении по умолчанию thinking.display = "omitted" соответствующие thinking‑блоки пустые, хотя модель может дать обычную текстовую подводку.

С display: "updates" и бета‑заголовком thinking-display-updates-2026-08-18 документация API определяет читаемое обновление прогресса как непустой блок thinking при скрытом рассуждении. В живых прогонах этого проекта поле thinking оставалось пустым, а читаемый статус приходил обычным блоком text сразу перед tool_use. Поэтому хелпер проверяет оба типа блоков, а петля вызывает его только в ходах, заканчивающихся на tool_use:

PROGRESS_BETA = "thinking-display-updates-2026-08-18"

response = client.beta.messages.create(
    model=MODEL,
    max_tokens=16000,
    betas=[PROGRESS_BETA],
    thinking={"type": "adaptive", "display": "updates"},
    system=SYSTEM_PROMPT,
    tools=TOOLS,
    messages=messages,
)

def status_lines(response) -> list[str]:
    lines = []
    for block in response.content:
        if block.type == "thinking":
            text = (block.thinking or "").strip()
        elif block.type == "text":
            text = (block.text or "").strip()
        else:
            continue
        if text:
            lines.append(text)
    return lines

Сообщения о прогрессе описывают файлы, которые модель планирует прочитать: «Прочту wiring приложения, конфиг, расширения, публичные и auth‑маршруты, а также существующие тесты — именно туда встраивается rate limiting». Показывайте эти сообщения и игнорируйте пустые блоки.

Терминал показывает петлю агента Claude Fable 5.1 с поминутным расходом токенов, сообщениями прогресса и пакетным чтением файлов

Агент читает файлы и сообщает о прогрессе. Изображение автора.

Fable 5.1 пишет их меньше, чем Fable 5, особенно на высоком effort. Если вашему интерфейсу нужны регулярные обновления, попросите вступительную строку, сообщения о прогрессе и заключительное резюме.

Меняйте effort Claude Fable 5.1 по ходу диалога

Следующая функция очень удобна. Как мы знаем, агенту репозитория не нужна одна и та же глубина рассуждений на каждом ходу.

Меняйте effort между ходами

В петле агента понижайте effort для рутинного извлечения и снова поднимайте для финального планирования.

С бета‑заголовком mid-conversation-output-config-2026-07-01 можно добавить системное сообщение, которое меняет только уровень effort:

EFFORT_BETA = "mid-conversation-output-config-2026-07-01"

messages.append({"role": "system", "content": [], "output_config": {"effort": "low"}})
messages.append({"role": "user", "content": "Summarize the repository evidence in five words."})

response = client.beta.messages.create(
    model=MODEL,
    max_tokens=4096,
    betas=[EFFORT_BETA],
    output_config={"effort": "high"},
    messages=messages,
)

Новый уровень применяется с следующего хода пользователя, а не посередине текущего, и не инвалидирует кэш промпта. Изменение верхнеуровневого output_config.effort между запросами инвалидирует кэш. 

Агент держит верхнеуровневую настройку на high, добавляет пер‑сообщения с medium перед рутиной и high перед финальным планом. В парном тесте на пониженном effort ушло 18 выходных токенов против 76 ранее. Считайте это примером, а не гарантией.

Применяйте системную инструкцию к одному ходу

Используйте инструкцию с областью одного хода, чтобы заблокировать дополнительные чтения файлов при финальном планировании.

Установите clear_at: "next_user_message" в системном сообщении с бета‑заголовком mid-conversation-system-clear-at-2026-08-21 . API трактует его текст как системную инструкцию текущего хода, а затем перестаёт её рендерить после следующего сообщения пользователя. Она остаётся в messages, так что ранняя история не меняется, кэш продолжает совпадать, и «очищенное» сообщение не стоит входных токенов.

SCOPED_SYSTEM_BETA = "mid-conversation-system-clear-at-2026-08-21"

messages.append({"role": "system", "content": [], "output_config": {"effort": "high"}})
messages.append({"role": "user", "content": "Write the implementation plan now."})
messages.append({
    "role": "system",
    "content": (
        "For this turn only: do not request more files. Base the plan on what "
        "you have already read, and name only paths you actually opened."
    ),
    "clear_at": "next_user_message",
})

response = client.beta.messages.create(
    model=MODEL,
    max_tokens=16000,
    betas=[EFFORT_BETA, SCOPED_SYSTEM_BETA],
    tool_choice={"type": "none"},
    output_config={"format": {"type": "json_schema", "schema": plan_schema()}},
    system=agent_system(),
    tools=TOOLS,
    messages=messages,
)

tool_choice={"type": "none"} не даёт финальному запросу вызвать очередной инструмент. Инструкция с областью одного хода ограничивает план файлами, которые агент уже просмотрел. Не добавляйте напоминание и не удаляйте его в следующем запросе. Такое редактирование инвалидирует последующие thinking‑блоки.

Исправляйте ошибки 400 на thinking‑блоках Claude Fable 5.1

Ошибка The block is bound to a different conversation означает, что история до thinking‑блока изменилась. Каждый thinking‑блок Fable 5.1 привязан к точному системному промпту, определениям инструментов и сообщениям, которые были до него.

Результат зависит от даты создания вашего аккаунта. 

  • Аккаунты, созданные 31 августа 2026 года и позже, получают 400 с указанием, что блок привязан к другой беседе. 

  • Для более ранних аккаунтов API фиксирует несоответствие, но учитывает его только если в запросе задано thinking.block_binding.prefix_mismatch_behavior

Это можно обнаружить с бета‑заголовком thinking-binding-controls-2026-08-01, установив thinking.block_binding.prefix_mismatch_behavior в "drop_block", и проверив массив input_transformations. Отредактированная история проявится как reason: "prefix_binding_mismatch". Прогоните эту проверку один раз для своей интеграции.

Следующие операции вызывают несоответствие:

  • Редактирование, переупорядочивание или удаление раннего хода при сохранении последующих

  • Вставка текста «на запрос» в ранний ход и его удаление в следующем запросе

  • Изменение содержимого или порядка верхнеуровневого промпта system или массива tools по ходу беседы

  • Подача других байтов по URL изображения или документа в более позднем запросе

У каждого есть альтернатива, сохраняющая привязки:

  • Добавляйте инструкции через системные сообщения внутри беседы вместо редактирования system

  • Меняйте инструменты через изменения инструментов в беседе вместо правки верхнеуровневого массива. 

  • Обрезайте историю через серверное редактирование контекста или компактацию — это не считается правкой. 

  •  Передавайте thinking‑блоки обратно без изменений.

Перемещение маркеров cache_control и изменение effort на уровне запроса безопасны и не инвалидируют привязки thinking‑блоков. Однако изменение effort на верхнем уровне перезапускает кэширование промпта, так что используйте effort на уровне сообщения, когда кэшируемый префикс должен оставаться неизменным.

Кэширование подсказок и стоимость API Claude Fable 5.1

Следующий прогон разделяет свежий ввод, записи в кэш, чтения из кэша и стоимость вывода.

Добавьте автоматическое кэширование подсказок

Кэширование подсказок снижает стоимость контекста, который повторяется между ходами. По мере роста истории меняется место разрыва, поэтому здесь проще подходит автоматическое кэширование.

Верхнеуровневое поле cache_control переносит разрыв к последнему кэшируемому блоку в каждом запросе:

response = client.beta.messages.create(
    model=MODEL,
    cache_control={"type": "ephemeral"},
    system=system,
    tools=TOOLS,
    messages=messages,
    # Other request fields...
)

Кэшируемый префикс короче 512 токенов в Fable 5.1 не кэшируется, даже помеченный cache_control. API обрабатывает его обычно и возвращает нули в обоих счётчиках кэша. Запись префикса в 583 токена стоила $0.0073; чтение на следующем ходу — $0.00015. Второй ход всё равно записывал свою новую часть в кэш, так что попадание в кэш не убрало все входные расходы.

Оцените стоимость API с учётом кэша

response.usage отдельно показывает свежий ввод, создание кэша, чтения из кэша и вывод. Оценивайте все четыре счётчика по своим ставкам; суммирование только ввода и вывода скрывает стоимость записи в кэш и завышает цену попаданий.

Вот разбивка стоимости из полного прогона, где были прочитаны 12 файлов за три хода и сгенерирован финальный план:

Статья

Токены

Оценочная стоимость

Доля

Вывод

5,713

$0.2857

59.4%

Записи в кэш

15,426

$0.1928

40.1%

Свежий ввод

50

$0.0005

0.1%

Чтения из кэша

6,549

$0.0016

0.3%

Итого

27,738

$0.4806

100%

Чтения из кэша составили доли процентов. По старой ставке Fable 5 прогон стоил бы примерно $0.4855 вместо $0.4806. Экономия растёт, когда каждый ход переиспользует больше контекста.

В этом прогоне почти 60% оценки дал вывод, а около 40% — записи в кэш. При пятиминутной ставке токен записи стоит в 50 раз дороже токена чтения. При записи на час — в 80 раз дороже.

Обрабатывайте отказы и фолбэки Claude Fable 5.1

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

Определяйте отказы до парсинга вывода

Отказ до вывода приходит с HTTP 200, stop_reason: "refusal", пустым содержимым и stop_details. Категория может быть null. Отказ позже в стриме может следовать за частичным выводом, который приложению нужно отбросить. try/except вокруг вызова ни тот, ни другой случай не поймает.

response = client.messages.create(model=MODEL, max_tokens=8192, messages=messages)

if response.stop_reason == "refusal":
    category = (
        response.stop_details.category
        if response.stop_details and response.stop_details.category
        else "unspecified"
    )
    return f"This request was declined ({category})."

Обрабатывайте это как состояние приложения. Если разрешённый запрос неясен, перепишите его точнее. Не строите повторные попытки с целью обойти классификатор.

Отказ приходит как HTTP 200. Изображение автора.

Настройте серверный фолбэк

Серверный фолбэк может повторить отклонённый запрос на другой модели, используя fallbacks: "default" с бета‑заголовком server-side-fallback-2026-07-01 . Допустимые цели для Fable 5.1 — Opus 4.8 и Opus 5

Фолбэк по умолчанию срабатывает только если у категории отказа есть рекомендованная цель. Проверенный отказ reasoning_extraction не запустил фолбэк; проверяйте usage.iterations, а не предполагайте повтор при каждом отказе. Как отмечалось, переход на старшую модель также удаляет thinking‑блоки Fable 5.1.

Публикуйте агента Claude Fable 5.1 с FastAPI

Локальный агент теперь может обслуживать тот же процесс через HTTP‑API.

Создайте endpoint плана

Если вам нужен только локальный скрипт, пропустите этот раздел. Для веб‑сервиса используйте FastAPI с AsyncAnthropic. Создайте один клиент на процесс в lifespan‑хендлере. Импортируйте схему и промпты из модуля агента.

@asynccontextmanager
async def lifespan(_: FastAPI):
    global client
    client = AsyncAnthropic()
    try:
        yield
    finally:
        await client.close()


@app.post("/plan", response_model=PlanResponse)
async def create_plan(body: PlanRequest):
    reader = resolve_project(body.project)
    messages, totals, turns, tool_calls = await inspect(reader, body.feature_request)
    plan, final_usage = await write_plan(messages)
    totals.add(final_usage)
    return PlanResponse(plan=plan, turns=turns, tool_calls=tool_calls, usage=as_usage(totals))

Обратите внимание: вызывающий передаёт имя проекта, а не путь. resolve_project() сопоставляет его с одним из небольшого набора разрешённых корней, чтобы запрос не мог заставить сервер читать произвольные места. Этот сервис мапит отказы в 422 как выбор приложения. Сам API Claude возвращает их с HTTP 200.

Запускайте uvicorn app:app --reload. Интерактивная документация доступна по адресу http://localhost:8000/docs.

Endpoint возвращает план с оценкой стоимости. Видео автора.

Endpoint /plan/stream запускает инспекцию в фоновом задании, помещает события прогресса и инструментов в asyncio.Queue и отдаёт их через StreamingResponse. Когда стрим закрывается, генератор отменяет фоновую задачу. Интерфейс Streamlit в репозитории рендерит тот же поток событий.

Streamlit показывает живой прогресс агента. Видео автора.

Чек‑лист развёртывания агента Claude Fable 5.1

Ограничения и проверки, добавленные ранее, остаются частью сервиса. Перед развёртыванием добавьте операционные элементы, невидимые в локальном прогоне.

  • Проверьте два ретрая SDK по умолчанию для ответов 429 и 5xx, затем задайте max_retries и таймауты под бюджет задержки сервиса

  • Установите таймаут запроса и подтвердите, что существующая отмена SSE‑задачи останавливает незавершённую работу при отключении клиента

  • Логируйте ID модели, версию SDK, ID запроса, причину остановки и четыре категории токенов для каждого прогона

  • Настройте алерты на рост записей в кэш, выходных токенов, отказов и прогонов, доходящих до лимита ходов

  • Подтвердите, что настройка хранения данных в аккаунте соответствует требованию модели

  • Закрепляйте SDK и перепроверяйте бета‑заголовки перед каждым релизом

Когда выбирать Claude Fable 5.1 вместо Opus 5 или Sonnet 5

  • Anthropic рекомендует Opus 5 как разумный дефолт.
  • Тестируйте Fable 5.1, когда Opus 5 не справляется с длинным анализом репозитория, сложной отладкой или агентными задачами с большим контекстом.
  • Для работы с репозиториями и повседневных задач сравните Sonnet 5 и Opus 5 по качеству, задержке и стоимости.
  • Для классификации, извлечения, коротких ответов и простых запросов Sonnet 5 — хороший дефолт; для самых простых задач может хватить и Haiku 4.5.

Не выбирайте Fable 5.1 только потому, что он новее. Один запрос по‑прежнему может использовать effort и структурированные ответы; стриминг тоже работает. Выгоды от петли и кэширования повторяющегося префикса здесь нет.

Итоги

Общий план из первого вызова стал полезным только после чтения репозитория агентом. В завершённом прогоне он просмотрел 12 файлов за три хода, а на вывод и записи в кэш пришлось 99.5% оценочной стоимости. Я бы сохранил границу путей и историю только‑добавление, затем проверил, снижает ли пониженный effort стоимость без того, чтобы модель пропускала инструменты репозитория.

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

Подробности выбора моделей — в нашем курсе Introduction to Claude Models. О промптах и рабочих процессах агента — в курсе Software Development with Cursor.

FAQs

Может ли Claude Fable 5.1 читать изображения так же, как код?

Да. Он принимает изображения и умеет читать диаграммы и PDF. Я не включал vision в основной пример, потому что план репозитория в нём не нуждается. Если бы я расширял этого агента для планирования UI‑изменений, отправил бы текущий скриншот вместе с запросом на функцию. Уменьшите его заранее, если мелкие визуальные детали не влияют на задачу.

Почему мой агент стал медленнее после перехода с Fable 5?

Сначала проверьте результаты инструментов, прежде чем винить модель. Если инструкция о пакетировании из раннего раздела уже присутствует, сравните и их число, и размеры. Текущий ридер ограничивает каждый файл 40 000 байтов. Если это всё ещё слишком много, добавьте аргументы диапазона строк или поиска, чтобы инструмент мог возвращать только релевантные фрагменты.

Почему Claude Fable 5.1 возвращает 400 invalid_request_error?

Не ретрайте сразу. invalid_request_error обычно указывает на форму запроса или настройку аккаунта, которые нужно поменять. В этом проекте вероятные причины — принудительный tool_choice, несовместимая настройка хранения, отредактированный префикс при сохранённых thinking‑блоках или бета‑поле без соответствующего заголовка. Исправьте указанную причину и повторите запрос.

Кэшировать исходные файлы или сводку?

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

Может ли Batch API запускать этого агента?

Сам по себе — нет. Batch API отправляет отдельные запросы Messages; он не запускает эту клиентскую петлю инструментов. Я бы использовал его для самодостаточных обзоров репозитория, когда не нужны живые обновления. Запуск полной петли батчами требует вашего кода, который обработает запросы инструментов одного батча перед отправкой следующего.

Темы

Учите ИИ с DataCamp!

Track

Ассоциированный AI-инженер для разработчиков

26 ч
Узнайте, как интегрировать ИИ в программные приложения с помощью API и библиотек с открытым исходным кодом. Начните свой путь к профессии AI Engineer уже сегодня!
ПодробнееRight Arrow
Начать Курс
Смотрите большеRight Arrow