Разработка с Claude API

Запросы, потоковые ответы, tool use, структурированный вывод и стоимость.

92 уроков, первые 3 бесплатно. Полный доступ: 1490 руб.

Уроки курса

  1. Welcome to the course
  2. Overview of Claude models
  3. Accessing the API
  4. Getting an API key
  5. Making a request
  6. Multi-Turn conversations
  7. Chat exercise
  8. System prompts
  9. System prompts exercise
  10. Temperature
  11. Course satisfaction survey
  12. Response streaming
  13. Structured data
  14. Structured data exercise
  15. Quiz on accessing Claude with the API
  16. Prompt evaluation
  17. A typical eval workflow
  18. Generating test datasets
  19. Running the eval
  20. Model based grading
  21. Code based grading
  22. Exercise on prompt evals
  23. Quiz on prompt evaluation
  24. Prompt engineering
  25. Being clear and direct
  26. Being specific
  27. Structure with XML tags
  28. Providing examples
  29. Exercise on prompting
  30. Quiz on prompt engineering techniques
  31. Introducing tool use
  32. Project overview
  33. Tool functions
  34. Tool schemas
  35. Handling message blocks
  36. Sending tool results
  37. Multi-turn conversations with tools
  38. Implementing multiple turns
  39. Using multiple tools
  40. Fine grained tool calling
  41. The text edit tool
  42. The web search tool
  43. Quiz on tool use with Claude
  44. Introducing Retrieval Augmented Generation
  45. Text chunking strategies
  46. Text embeddings
  47. The full RAG flow
  48. Implementing the RAG flow
  49. BM25 lexical search
  50. A Multi-Index RAG pipeline
  51. Extended thinking
  52. Image support
  53. PDF support
  54. Citations
  55. Prompt caching
  56. Rules of prompt caching
  57. Prompt caching in action
  58. Code execution and the Files API
  59. Quiz on features of Claude
  60. Introducing MCP
  61. MCP clients
  62. Project setup
  63. Defining tools with MCP
  64. The server inspector
  65. Implementing a client
  66. Defining resources
  67. Accessing resources
  68. Defining prompts
  69. Prompts in the client
  70. MCP review
  71. Quiz on Model Context Protocol
  72. Anthropic apps
  73. Claude Code setup
  74. Claude Code in action
  75. Enhancements with MCP servers
  76. Agents and workflows
  77. Parallelization workflows
  78. Chaining workflows
  79. Routing workflows
  80. Agents and tools
  81. Environment inspection
  82. Workflows vs agents
  83. Quiz on Agents and Workflows
  84. Final Assessment
  85. Course Wrap Up
  86. What You'll Learn
  87. What You'll Learn
  88. What You'll Learn
  89. What You'll Learn
  90. What You'll Learn
  91. What You'll Learn
  92. What You'll Learn

Многоходовые диалоги с Claude: Управление контекстом

В мире больших языковых моделей (LLM), таких как Claude от Anthropic, возможность вести осмысленные, продолжительные диалоги является ключевой для создания интерактивных и полезных приложений. Однако, за кулисами этих, казалось бы, "умных" бесед скрывается важный принцип, который необходимо понимать каждому разработчику: Claude не хранит историю ваших разговоров. Каждое обращение к API Claude является полностью независимым, не имеющим встроенной памяти о предыдущих обменах репликами. Это означает, что для поддержания контекста в многоходовом диалоге вам потребуется самостоятельно управлять состоянием беседы.

Почему Claude "забывает" предыдущие реплики?

Представьте, что вы общаетесь с кем-то, кто каждый раз, когда вы задаете новый вопрос, полностью забывает все, что было сказано до этого. Именно так работает Claude по умолчанию. Модели LLM, такие как Claude, являются stateless (без сохранения состояния). Это фундаментальная особенность их архитектуры: каждый запрос к API обрабатывается как совершенно новый, изолированный ввод. В результате, если вы сначала спросите Claude: "Что такое квантовые вычисления?" и получите подробный ответ, а затем сразу же последуете вопросом: "Напиши еще одно предложение", Claude не будет знать, к чему относится ваше уточнение. Он может сгенерировать предложение на совершенно случайную тему, потому что у него нет встроенной памяти о предыдущем обсуждении квантовых вычислений.

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

Секрет непрерывного диалога: Передача полной истории

Чтобы Claude мог "помнить" предыдущие реплики и поддерживать контекст в многоходовом диалоге, вам необходимо самостоятельно управлять историей сообщений. Это достигается двумя основными шагами:

Давайте рассмотрим, как это работает на практике. Последовательность действий выглядит следующим образом:

  1. Вы отправляете свое первое сообщение пользователя (user message) Claude.
  2. Получаете ответ от Claude и добавляете его в свой список сообщений как сообщение ассистента (assistant message).
  3. Добавляете свой следующий вопрос или уточнение как новое сообщение пользователя.
  4. Отправляете всю историю диалога (включая первое сообщение, ответ Claude и ваше новое сообщение) обратно Claude.

Каждый раз, когда вы хотите продолжить диалог, вы добавляете новую реплику в список и отправляете весь обновленный список Claude. Это позволяет модели "видеть" весь путь беседы и генерировать релевантные ответы.

Реализация на практике: Вспомогательные функции

Для упрощения управления диалогом в вашем приложении можно создать несколько вспомогательных функций. Эти функции помогут вам структурировать сообщения и отправлять их в правильном формате, который ожидает API Claude. Сообщения обычно представляются в виде списка словарей, где каждый словарь содержит "role" (роль отправителя: "user" или "assistant") и "content" (текст сообщения).

Рассмотрим пример таких функций на псевдокоде, который имитирует работу с API:


# Функция для добавления сообщения пользователя в историю
def add_user_message(messages_list, text):
    user_message = {"role": "user", "content": text}
    messages_list.append(user_message)

# Функция для добавления ответа ассистента (Claude) в историю
def add_assistant_message(messages_list, text):
    assistant_message = {"role": "assistant", "content": text}
    messages_list.append(assistant_message)

# Функция для отправки истории сообщений Claude и получения ответа
def chat_with_claude(messages_list, model_name="claude-3-opus-20240229", max_tokens_to_sample=1000):
    # В реальном коде здесь происходит вызов API Claude через клиентскую библиотеку (SDK).
    # Например, с использованием Anthropic Python SDK:
    # from anthropic import Anthropic
    # client = Anthropic()
    # response = client.messages.create(
    #     model=model_name,
    #     max_tokens=max_tokens_to_sample,
    #     messages=messages_list,
    # )
    # return response.content[0].text

    # Для демонстрации мы имитируем ответ Claude на основе последнего сообщения и контекста
    last_message_content = messages_list[-1]["content"]
    if last_message_content == "Напиши еще одно предложение":
        # Проверяем, был ли в истории контекст про квантовые вычисления
        if any("квантовые вычисления" in msg["content"].lower() for msg in messages_list[:-1]):
            return "Квантовые вычисления обещают революционизировать области, такие как криптография и разработка новых материалов."
        else:
            return "Это еще одно предложение, не связанное с предыдущим контекстом."
    elif last_message_content == "Определи квантовые вычисления в одном предложении":
        return "Квантовые вычисления используют принципы квантовой механики для выполнения вычислений, которые выходят за рамки возможностей классических компьютеров."
    else:
        return "Я получил ваше сообщение."

Эти функции позволяют абстрагироваться от деталей форматирования сообщений и сосредоточиться на логике диалога. Функция chat_with_claude (или ее реальный аналог, использующий client.messages.create из Anthropic SDK) будет отвечать за взаимодействие с API, принимая на вход весь список сообщений.

Пример использования: От вопроса к уточнению

Теперь, когда мы понимаем принцип и имеем вспомогательные функции, давайте посмотрим, как они используются для поддержания контекста в нашем примере с квантовыми вычислениями:


# 1. Начинаем с пустого списка сообщений
messages = []

# 2. Добавляем первоначальный вопрос пользователя
add_user_message(messages, "Определи квантовые вычисления в одном предложении")
# На этом этапе messages = [{"role": "user", "content": "Определи квантовые вычисления в одном предложении"}]

# 3. Отправляем историю Claude и получаем ответ
answer_1 = chat_with_claude(messages)
# answer_1 будет: "Квантовые вычисления используют принципы квантовой механики для выполнения вычислений, которые выходят за рамки возможностей классических компьютеров."

# 4. Добавляем ответ Claude в историю диалога
add_assistant_message(messages, answer_1)
# Теперь messages = [
#   {"role": "user", "content": "Определи квантовые вычисления в одном предложении"},
#   {"role": "assistant", "content": "Квантовые вычисления используют принципы квантовой механики для выполнения вычислений, которые выходят за рамки возможностей классических компьютеров."}
# ]

# 5. Добавляем последующий вопрос
add_user_message(messages, "Напиши еще одно предложение")
# messages теперь содержит все три сообщения:
# [
#   {"role": "user", "content": "Определи квантовые вычисления в одном предложении"},
#   {"role": "assistant", "content": "Квантовые вычисления используют принципы квантовой механики для выполнения вычислений, которые выходят за рамки возможностей классических компьютеров."},
#   {"role": "user", "content": "Напиши еще одно предложение"}
# ]

# 6. Получаем ответ на последующий вопрос, передавая полную историю
answer_2 = chat_with_claude(messages)
# answer_2 будет: "Квантовые вычисления обещают революционизировать области, такие как криптография и разработка новых материалов."

В этом сценарии, когда chat_with_claude вызывается во второй раз, список messages содержит не только "Напиши еще одно предложение", но и предыдущий вопрос о квантовых вычислениях, а также первый ответ Claude. Благодаря этому, Claude теперь "понимает", что "Напиши еще одно предложение" относится к расширению определения квантовых вычислений, а не к какой-то случайной теме. Результатом будет связное продолжение мысли.

Заключение

Управление историей сообщений — это фундаментальный навык при разработке приложений с использованием Claude API. Хотя Claude сам по себе является stateless, правильное поддержание и передача полного контекста диалога позволяет создавать сложные, многоходовые беседы, которые ощущаются естественными и интеллектуальными. Эти вспомогательные функции и паттерны будут чрезвычайно полезны на протяжении всей вашей работы с Claude, значительно упрощая создание приложений, способных поддерживать значимые диалоги на протяжении многих обменов репликами. Освоив этот подход, вы сможете эффективно использовать Claude для решения широкого круга задач, от простых чат-ботов до сложных агентов, использующих tool use, RAG и другие продвинутые техники.