---
title: Резюмирование юридических документов
url: https://platform.claude.com/docs/ru/about-claude/use-case-guides/legal-summarization
description: В этом руководстве рассматривается, как использовать расширенные возможности Claude по обработке естественного языка для эффективного резюмирования юридических документов, извлечения ключевой информации и ускорения юридических исследований. С помощью Claude вы можете оптимизировать проверку договоров, подготовку к судебным разбирательствам и работу с нормативными требованиями, экономя время и обеспечивая точность ваших юридических процессов.
---

> Посетите [сборник рецептов по резюмированию](https://platform.claude.com/cookbook/capabilities-summarization-guide), чтобы увидеть пример реализации резюмирования юридических документов с помощью Claude.

## Перед началом работы с Claude

### Решите, стоит ли использовать Claude для резюмирования юридических документов

Вот несколько ключевых признаков того, что вам следует использовать «large language model» (большую языковую модель), или LLM, такую как Claude, для резюмирования юридических документов:

<AccordionGroup>
  <Accordion title="Вы хотите эффективно и недорого проверять большой объём документов">
    Масштабная проверка документов может быть трудоёмкой и дорогостоящей, если выполняется вручную. Claude может быстро обрабатывать и резюмировать огромные объёмы юридических документов, значительно сокращая время и затраты, связанные с проверкой документов. Эта возможность особенно ценна для таких задач, как комплексная юридическая проверка (due diligence), анализ договоров или раскрытие доказательств в судебных разбирательствах, где эффективность имеет решающее значение.
  </Accordion>

  <Accordion title="Вам требуется автоматическое извлечение ключевых метаданных">
    Claude может эффективно извлекать и классифицировать важные метаданные из юридических документов, такие как участвующие стороны, даты, условия договора или конкретные положения. Такое автоматическое извлечение помогает упорядочить информацию, упрощая поиск, анализ и управление большими наборами документов. Это особенно полезно для управления договорами, проверок соответствия требованиям или создания баз данных юридической информации с возможностью поиска. 
  </Accordion>

  <Accordion title="Вы хотите создавать чёткие, краткие и стандартизированные резюме">
    Claude может создавать структурированные резюме, соответствующие заранее определённым форматам, что позволяет юристам быстро уловить ключевые моменты различных документов. Такие стандартизированные резюме улучшают читаемость, облегчают сравнение документов и повышают общее понимание, особенно при работе со сложным юридическим языком или техническим жаргоном.
  </Accordion>

  <Accordion title="Вам нужны точные ссылки на источники в ваших резюме">
    При создании юридических резюме надлежащее указание источников и цитирование имеют решающее значение для обеспечения достоверности и соответствия юридическим стандартам. Claude можно попросить включать точные ссылки на источники для всех упомянутых юридических положений, что упрощает юристам проверку и верификацию резюмированной информации.
  </Accordion>

  <Accordion title="Вы хотите оптимизировать и ускорить процесс юридических исследований">
    Claude может помочь в юридических исследованиях, быстро анализируя большие объёмы судебной практики, законодательных актов и юридических комментариев. Он может выявлять релевантные прецеденты, извлекать ключевые правовые принципы и резюмировать сложные юридические аргументы. Эта возможность может значительно ускорить процесс исследования, позволяя юристам сосредоточиться на анализе более высокого уровня и разработке стратегии.
  </Accordion>
</AccordionGroup>

### Определите, какие сведения должно извлекать резюмирование

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

Например, при резюмировании договора субаренды вы можете захотеть извлечь следующие ключевые моменты:

<CodeGroup exclude="shell">
  ```python Python
  details_to_extract = [
      "Parties involved (sublessor, sublessee, and original lessor)",
      "Property details (address, description, and permitted use)",
      "Term and rent (start date, end date, monthly rent, and security deposit)",
      "Responsibilities (utilities, maintenance, and repairs)",
      "Consent and notices (landlord's consent, and notice requirements)",
      "Special provisions (furniture, parking, and subletting restrictions)",
  ]
  ```

  ```typescript TypeScript
  const detailsToExtract = [
    "Parties involved (sublessor, sublessee, and original lessor)",
    "Property details (address, description, and permitted use)",
    "Term and rent (start date, end date, monthly rent, and security deposit)",
    "Responsibilities (utilities, maintenance, and repairs)",
    "Consent and notices (landlord's consent, and notice requirements)",
    "Special provisions (furniture, parking, and subletting restrictions)"
  ];
  ```

  ```csharp C#
  List<string> detailsToExtract =
  [
      "Parties involved (sublessor, sublessee, and original lessor)",
      "Property details (address, description, and permitted use)",
      "Term and rent (start date, end date, monthly rent, and security deposit)",
      "Responsibilities (utilities, maintenance, and repairs)",
      "Consent and notices (landlord's consent, and notice requirements)",
      "Special provisions (furniture, parking, and subletting restrictions)",
  ];
  ```

  ```go Go
  var detailsToExtract = []string{
  	"Parties involved (sublessor, sublessee, and original lessor)",
  	"Property details (address, description, and permitted use)",
  	"Term and rent (start date, end date, monthly rent, and security deposit)",
  	"Responsibilities (utilities, maintenance, and repairs)",
  	"Consent and notices (landlord's consent, and notice requirements)",
  	"Special provisions (furniture, parking, and subletting restrictions)",
  }
  ```

  ```java Java
  List<String> detailsToExtract = List.of(
          "Parties involved (sublessor, sublessee, and original lessor)",
          "Property details (address, description, and permitted use)",
          "Term and rent (start date, end date, monthly rent, and security deposit)",
          "Responsibilities (utilities, maintenance, and repairs)",
          "Consent and notices (landlord's consent, and notice requirements)",
          "Special provisions (furniture, parking, and subletting restrictions)");
  ```

  ```php PHP
  $detailsToExtract = [
      'Parties involved (sublessor, sublessee, and original lessor)',
      'Property details (address, description, and permitted use)',
      'Term and rent (start date, end date, monthly rent, and security deposit)',
      'Responsibilities (utilities, maintenance, and repairs)',
      "Consent and notices (landlord's consent, and notice requirements)",
      'Special provisions (furniture, parking, and subletting restrictions)',
  ];
  ```

  ```ruby Ruby
  details_to_extract = [
    "Parties involved (sublessor, sublessee, and original lessor)",
    "Property details (address, description, and permitted use)",
    "Term and rent (start date, end date, monthly rent, and security deposit)",
    "Responsibilities (utilities, maintenance, and repairs)",
    "Consent and notices (landlord's consent, and notice requirements)",
    "Special provisions (furniture, parking, and subletting restrictions)"
  ]
  ```
</CodeGroup>

### Установите критерии успеха

Оценка качества резюме — общеизвестно сложная задача. В отличие от многих других задач обработки естественного языка, оценка резюме часто не имеет чётких, объективных метрик. Процесс может быть весьма субъективным, поскольку разные читатели ценят разные аспекты резюме. Вот критерии, которые вы можете учитывать при оценке того, насколько хорошо Claude справляется с резюмированием юридических документов.

<AccordionGroup>
  <Accordion title="Фактическая корректность">
    Резюме должно точно отражать факты, правовые концепции и ключевые моменты документа.
  </Accordion>

  <Accordion title="Юридическая точность">
    Терминология и ссылки на законодательные акты, судебную практику или нормативные положения должны быть корректными и соответствовать юридическим стандартам.
  </Accordion>

  <Accordion title="Краткость">
     Резюме должно сжимать юридический документ до его существенных моментов без потери важных деталей.
  </Accordion>

  <Accordion title="Единообразие">
    При резюмировании нескольких документов LLM должна придерживаться единообразной структуры и подхода к каждому резюме.
  </Accordion>

  <Accordion title="Читаемость">
    Текст должен быть ясным и лёгким для понимания. Если аудитория не является экспертами в области права, резюме не должно содержать юридического жаргона, который может запутать аудиторию.
  </Accordion>

  <Accordion title="Непредвзятость и справедливость">
    Резюме должно представлять непредвзятое и справедливое изложение юридических аргументов и позиций.
  </Accordion>
</AccordionGroup>

Дополнительную информацию см. в руководстве по [установлению критериев успеха](https://platform.claude.com/docs/ru/test-and-evaluate/develop-tests).

***

## Как резюмировать юридические документы с помощью Claude

### Выберите подходящую модель Claude

Точность модели чрезвычайно важна при резюмировании юридических документов. Claude Opus 5.5 — отличный выбор для подобных сценариев использования, где требуется высокая точность. Если размер и количество ваших документов настолько велики, что затраты начинают вызывать беспокойство, вы также можете попробовать использовать модель меньшего размера, например Claude Haiku 5.5.

Чтобы помочь оценить эти затраты, ниже приведено сравнение стоимости резюмирования 1 000 договоров субаренды с использованием моделей Opus и Haiku:

* **Размер контента**

  * Количество договоров: 1 000
  * Символов на договор: 300 000
  * Всего символов: 300 млн

* **Оценочное количество токенов**

  * Входные токены: 108 млн, около 108 000 на договор (примерно 1 токен на 2,8 символа — такое соотношение обе модели показали на образце договора из этого руководства)
  * Выходные токены на одно резюме, включая токены размышлений, которые тарифицируются как выходные: около 6 200 для Claude Opus 5.5 и 3 100 для Claude Haiku 5.5
  * Всего выходных токенов: 6,2 млн для Claude Opus 5.5 и 3,1 млн для Claude Haiku 5.5

* **Оценочная стоимость Claude Opus 5.5**

  * Стоимость входных токенов: 108 MTok \* $4,00/MTok = $432,00 USD
  * Стоимость выходных токенов: 6,2 MTok \* $20,00/MTok = $124,00 USD
  * Общая стоимость: $432,00 + $124,00 = $556,00 USD

* **Оценочная стоимость Claude Haiku 5.5** по ценам для подсказок длиной более 100 000 токенов

  * Стоимость входных токенов: 108 MTok \* $0,50/MTok = $54,00 USD
  * Стоимость выходных токенов: 3,1 MTok \* $2,50/MTok = $7,75 USD
  * Общая стоимость: $54,00 + $7,75 = $61,75 USD

<Tip>
  Фактические затраты могут отличаться от этих оценок. Количество токенов получено при запуске примера из раздела 

  [Создайте сильную подсказку](https://platform.claude.com/docs/ru/about-claude/use-case-guides/legal-summarization#build-a-strong-prompt)

   на образце договора из этого руководства — около 105 000 входных токенов, а длина вывода зависит от документа и меняется от запуска к запуску. Каждый договор здесь — это одна подсказка примерно из 108 000 токенов, что превышает порог в 100 000 токенов для 

  [цен на длинные подсказки](https://platform.claude.com/docs/ru/about-claude/pricing#long-context-pricing)

   Claude Haiku 5.5. Документ, подсказка для которого не превышает 100 000 токенов, вместо этого оплачивается по $0,10/MTok за вход и $0,50/MTok за выход. Чтобы узнать, какие цены применяются, подсчитайте токены ваших документов с помощью 

  [подсчёта токенов](https://platform.claude.com/docs/ru/build-with-claude/token-counting)

  , указав для 

  `model`

   значение 

  `claude-haiku-5-5`

  .
</Tip>

### Преобразуйте документы в формат, который Claude может обработать

Прежде чем приступить к резюмированию документов, вам необходимо подготовить данные. Это включает извлечение текста из PDF-файлов, очистку текста и обеспечение его готовности к обработке Claude.

Вот демонстрация этого процесса на примере PDF-файла:

<CodeGroup exclude="shell">
  <CodeGroupItem language="cURL">
    Извлеките текст из PDF-файла в коде.
  </CodeGroupItem>

  <CodeGroupItem language="CLI">
    Извлеките текст из PDF-файла в коде.
  </CodeGroupItem>

  ```python Python
  from io import BytesIO
  import re

  import pypdf
  import requests


  def get_llm_text(pdf_file):
      reader = pypdf.PdfReader(pdf_file)
      text = "\n".join([page.extract_text() for page in reader.pages])

      # Удаляем номера страниц
      text = re.sub(r"\n\s*\d+\s*\n", "\n", text)

      # Удаляем лишние пробелы
      text = re.sub(r"\s+", " ", text)

      return text


  # Формируем полный URL из репозитория GitHub
  url = "https://raw.githubusercontent.com/anthropics/claude-cookbooks/main/capabilities/summarization/data/Sample Sublease Agreement.pdf"
  url = url.replace(" ", "%20")

  # Загружаем PDF-файл в память
  response = requests.get(url)

  # Загружаем PDF из памяти
  pdf_file = BytesIO(response.content)

  document_text = get_llm_text(pdf_file)
  print(document_text[:50000])
  ```

  ```typescript TypeScript
  import { PDFParse } from "pdf-parse";

  async function getLlmText(pdfData: Uint8Array): Promise<string> {
    const parser = new PDFParse({ data: pdfData });
    const result = await parser.getText();
    await parser.destroy();
    let text = result.pages.map((page) => page.text).join("\n");

    // Удаляем номера страниц
    text = text.replace(/\n\s*\d+\s*\n/g, "\n");

    // Удаляем лишние пробелы
    text = text.replace(/\s+/g, " ");

    return text;
  }

  // Загружаем пример договора субаренды из cookbook по суммаризации
  const response = await fetch(
    "https://raw.githubusercontent.com/anthropics/claude-cookbooks/main/capabilities/summarization/data/Sample%20Sublease%20Agreement.pdf"
  );
  const pdfData = new Uint8Array(await response.arrayBuffer());

  const documentText = await getLlmText(pdfData);
  console.log(documentText.slice(0, 50000));
  ```

  ```csharp C#
  using System.Text.RegularExpressions;
  using UglyToad.PdfPig;
  using UglyToad.PdfPig.DocumentLayoutAnalysis.TextExtractor;

  string GetLlmText(byte[] pdfData)
  {
      using var document = PdfDocument.Open(pdfData);
      var text = string.Join("\n", document.GetPages().Select(page => ContentOrderTextExtractor.GetText(page)));

      // Удаляем номера страниц
      text = Regex.Replace(text, @"\n\s*\d+\s*\n", "\n");

      // Удаляем лишние пробелы
      text = Regex.Replace(text, @"\s+", " ");

      return text;
  }

  // Загружаем пример договора субаренды из руководства по суммаризации
  using var httpClient = new HttpClient();
  var pdfData = await httpClient.GetByteArrayAsync(
      "https://raw.githubusercontent.com/anthropics/claude-cookbooks/main/capabilities/summarization/data/Sample%20Sublease%20Agreement.pdf"
  );

  var documentText = GetLlmText(pdfData);
  Console.WriteLine(documentText[..Math.Min(50000, documentText.Length)]);
  ```

  ```go Go
  import (
  	"bytes"
  	"io"
  	"net/http"
  	"regexp"

  	"github.com/ledongthuc/pdf"
  )

  // Текст образца договора субаренды
  var documentText string

  func getLLMText(pdfData []byte) (string, error) {
  	reader, err := pdf.NewReader(bytes.NewReader(pdfData), int64(len(pdfData)))
  	if err != nil {
  		return "", err
  	}

  	var pages []string
  	for pageIndex := 1; pageIndex <= reader.NumPage(); pageIndex++ {
  		pageText, err := reader.Page(pageIndex).GetPlainText(nil)
  		if err != nil {
  			return "", err
  		}
  		pages = append(pages, pageText)
  	}
  	text := strings.Join(pages, "\n")

  	// Удаляем номера страниц
  	text = regexp.MustCompile(`\n\s*\d+\s*\n`).ReplaceAllString(text, "\n")

  	// Удаляем лишние пробелы
  	text = regexp.MustCompile(`\s+`).ReplaceAllString(text, " ")

  	return text, nil
  }

  // extractDocumentText скачивает образец договора субаренды и извлекает из него текст.
  func extractDocumentText() {
  	// Скачиваем образец договора субаренды из cookbook по суммаризации
  	response, err := http.Get("https://raw.githubusercontent.com/anthropics/claude-cookbooks/main/capabilities/summarization/data/Sample%20Sublease%20Agreement.pdf")
  	if err != nil {
  		log.Fatal(err)
  	}
  	defer response.Body.Close()

  	pdfData, err := io.ReadAll(response.Body)
  	if err != nil {
  		log.Fatal(err)
  	}

  	documentText, err = getLLMText(pdfData)
  	if err != nil {
  		log.Fatal(err)
  	}
  	fmt.Println(documentText[:min(50000, len(documentText))])
  }
  ```

  ```java Java
  import java.io.IOException;
  import java.net.URI;
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;
  import org.apache.pdfbox.Loader;
  import org.apache.pdfbox.pdmodel.PDDocument;
  import org.apache.pdfbox.text.PDFTextStripper;

  // Текст образца договора субаренды
  String documentText;

  String getLlmText(byte[] pdfData) throws IOException {
      try (PDDocument document = Loader.loadPDF(pdfData)) {
          String text = new PDFTextStripper().getText(document);

          // Удаляем номера страниц
          text = text.replaceAll("\\n\\s*\\d+\\s*\\n", "\n");

          // Удаляем лишние пробелы
          return text.replaceAll("\\s+", " ");
      }
  }

  void extractDocumentText() throws IOException, InterruptedException {
      // Загружаем образец договора субаренды из cookbook по суммаризации
      HttpRequest request = HttpRequest.newBuilder(URI.create(
                      "https://raw.githubusercontent.com/anthropics/claude-cookbooks/main/capabilities/summarization/data/Sample%20Sublease%20Agreement.pdf"))
              .build();
      byte[] pdfData;
      try (HttpClient httpClient = HttpClient.newHttpClient()) {
          pdfData = httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray()).body();
      }

      documentText = getLlmText(pdfData);
      IO.println(documentText.substring(0, Math.min(50000, documentText.length())));
  }
  ```

  ```php PHP
  use Smalot\PdfParser\Parser;

  $getLlmText = function (string $pdfData): string {
      $document = (new Parser())->parseContent($pdfData);
      $text = implode("\n", array_map(fn ($page) => $page->getText(), $document->getPages()));

      // Удаляем номера страниц
      $text = preg_replace('/\n\s*\d+\s*\n/', "\n", $text);

      // Удаляем лишние пробелы
      return preg_replace('/\s+/', ' ', $text);
  };

  // Загружаем пример договора субаренды из cookbook по суммаризации
  $pdfData = file_get_contents(
      'https://raw.githubusercontent.com/anthropics/claude-cookbooks/main/capabilities/summarization/data/Sample%20Sublease%20Agreement.pdf'
  );

  $documentText = $getLlmText($pdfData);
  echo substr($documentText, 0, 50000) . "\n";
  ```

  ```ruby Ruby
  require "net/http"
  require "pdf-reader"
  require "stringio"

  def get_llm_text(pdf_data)
    reader = PDF::Reader.new(StringIO.new(pdf_data))
    text = reader.pages.map(&:text).join("\n")

    # Удаляем номера страниц
    text = text.gsub(/\n\s*\d+\s*\n/, "\n")

    # Удаляем лишние пробелы
    text.gsub(/\s+/, " ")
  end

  # Загружаем пример договора субаренды из cookbook по суммаризации
  pdf_data = Net::HTTP.get(
    URI("https://raw.githubusercontent.com/anthropics/claude-cookbooks/main/capabilities/summarization/data/Sample%20Sublease%20Agreement.pdf")
  )

  document_text = get_llm_text(pdf_data)
  puts document_text[0, 50_000]
  ```
</CodeGroup>

В этом примере вы сначала загружаете PDF-файл с образцом договора субаренды, используемым в [сборнике рецептов по резюмированию](https://platform.claude.com/cookbook/capabilities-summarization-guide). Этот договор был взят из общедоступного договора субаренды с [сайта sec.gov](https://www.sec.gov/Archives/edgar/data/1045425/000119312507044370/dex1032.htm).

В примере используется библиотека `pypdf` (typescript: `pdf-parse`; csharp: `PdfPig`; go: `github.com/ledongthuc/pdf`; java: `org.apache.pdfbox:pdfbox`; php: `smalot/pdfparser`; ruby: `pdf-reader`) для извлечения содержимого PDF-файла и преобразования его в текст. Затем текстовые данные очищаются путём удаления номеров страниц и лишних пробелов.

### Создайте сильную подсказку

Claude может адаптироваться к различным стилям резюмирования. Вы можете изменять детали «prompt» (подсказки), чтобы направить Claude быть более или менее многословным, включать больше или меньше технической терминологии либо предоставлять резюме рассматриваемого контекста более высокого или более низкого уровня.

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

<CodeGroup exclude="shell">
  <CodeGroupItem language="cURL">
    Этот рабочий процесс требует больше логики, чем одна команда оболочки. Используйте Claude SDK для его запуска.
  </CodeGroupItem>

  <CodeGroupItem language="CLI">
    Этот рабочий процесс требует больше логики, чем одна команда оболочки. Используйте Claude SDK для его запуска.
  </CodeGroupItem>

  ```python Python
  # Инициализируем клиент Anthropic
  client = anthropic.Anthropic()


  def summarize_document(
      text, details_to_extract, model="claude-opus-5-5", max_tokens=16000
  ):
      # Форматируем извлекаемые сведения для размещения в контексте подсказки
      details_to_extract_str = "\n".join(details_to_extract)

      # Просим модель кратко изложить договор субаренды
      prompt = f"""Summarize the following sublease agreement. Focus on these key aspects:

      {details_to_extract_str}

      Provide the summary in bullet points nested within the XML header for each section. For example:

      <parties involved>
      - Sublessor: [Name]
      // Add more details as needed
      </parties involved>

      If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.

      Sublease agreement text:
      {text}
      """

      response = client.messages.create(
          model=model,
          max_tokens=max_tokens,
          system="You are a legal analyst specializing in real estate law, known for highly accurate and detailed summaries of sublease agreements.",
          messages=[
              {"role": "user", "content": prompt},
          ],
      )

      return next(block.text for block in response.content if block.type == "text")


  sublease_summary = summarize_document(document_text, details_to_extract)
  print(sublease_summary)
  ```

  ```typescript TypeScript
  // Инициализируем клиент Anthropic
  const client = new Anthropic();

  async function summarizeDocument(
    text: string,
    detailsToExtract: string[],
    model: Anthropic.Model = "claude-opus-5-5",
    maxTokens = 16000
  ): Promise<string> {
    // Форматируем извлекаемые сведения для размещения в контексте подсказки
    const detailsToExtractStr = detailsToExtract.join("\n");

    // Просим модель кратко изложить договор субаренды
    const prompt = `Summarize the following sublease agreement. Focus on these key aspects:

      ${detailsToExtractStr}

      Provide the summary in bullet points nested within the XML header for each section. For example:

      <parties involved>
      - Sublessor: [Name]
      // Add more details as needed
      </parties involved>

      If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.

      Sublease agreement text:
      ${text}
      `;

    const response = await client.messages.create({
      model,
      max_tokens: maxTokens,
      system:
        "You are a legal analyst specializing in real estate law, known for highly accurate and detailed summaries of sublease agreements.",
      messages: [{ role: "user", content: prompt }]
    });

    const textBlock = response.content.find((block) => block.type === "text");
    if (!textBlock) {
      throw new Error("Expected a text block in the response");
    }
    return textBlock.text;
  }

  const subleaseSummary = await summarizeDocument(documentText, detailsToExtract);
  console.log(subleaseSummary);
  ```

  ```csharp C#
  // Инициализируем клиент Anthropic
  var client = new AnthropicClient();

  async Task<string> SummarizeDocument(
      string text,
      IReadOnlyList<string> detailsToExtract,
      Model model = Model.ClaudeOpus5_5,
      long maxTokens = 16000
  )
  {
      // Форматируем извлекаемые сведения для размещения в контексте подсказки
      var detailsToExtractStr = string.Join("\n", detailsToExtract);

      // Просим модель кратко изложить договор субаренды
      var prompt = $"""
          Summarize the following sublease agreement. Focus on these key aspects:

              {detailsToExtractStr}

              Provide the summary in bullet points nested within the XML header for each section. For example:

              <parties involved>
              - Sublessor: [Name]
              // Add more details as needed
              </parties involved>

              If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.

              Sublease agreement text:
              {text}
          """;

      var response = await client.Messages.Create(
          new()
          {
              Model = model,
              MaxTokens = maxTokens,
              System = "You are a legal analyst specializing in real estate law, known for highly accurate and detailed summaries of sublease agreements.",
              Messages = [new() { Role = Role.User, Content = prompt }],
          }
      );

      foreach (var block in response.Content)
      {
          if (block.TryPickText(out var textBlock))
          {
              return textBlock.Text;
          }
      }
      throw new InvalidOperationException("Expected a text block in the response.");
  }

  var subleaseSummary = await SummarizeDocument(documentText, detailsToExtract);
  Console.WriteLine(subleaseSummary);
  ```

  ```go Go
  // Инициализируем клиент Anthropic
  var client = anthropic.NewClient()

  func summarizeDocument(text string, detailsToExtract []string, model anthropic.Model, maxTokens int64) string {
  	// Форматируем извлекаемые сведения для размещения в контексте подсказки
  	detailsToExtractStr := strings.Join(detailsToExtract, "\n")

  	// Просим модель кратко изложить договор субаренды
  	prompt := fmt.Sprintf(`Summarize the following sublease agreement. Focus on these key aspects:

      %s

      Provide the summary in bullet points nested within the XML header for each section. For example:

      <parties involved>
      - Sublessor: [Name]
      // Add more details as needed
      </parties involved>

      If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.

      Sublease agreement text:
      %s
      `, detailsToExtractStr, text)

  	response, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{
  		Model:     model,
  		MaxTokens: maxTokens,
  		System: []anthropic.TextBlockParam{
  			{Text: "You are a legal analyst specializing in real estate law, known for highly accurate and detailed summaries of sublease agreements."},
  		},
  		Messages: []anthropic.MessageParam{
  			anthropic.NewUserMessage(anthropic.NewTextBlock(prompt)),
  		},
  	})
  	if err != nil {
  		log.Fatal(err)
  	}

  	for _, block := range response.Content {
  		if textBlock, ok := block.AsAny().(anthropic.TextBlock); ok {
  			return textBlock.Text
  		}
  	}
  	panic("expected a text block in the response")
  }

  // printSubleaseSummary кратко излагает договор субаренды и выводит резюме.
  func printSubleaseSummary() {
  	subleaseSummary := summarizeDocument(documentText, detailsToExtract, anthropic.ModelClaudeOpus5_5, 16000)
  	fmt.Println(subleaseSummary)
  }
  ```

  ```java Java
  // Инициализируем клиент Anthropic
  AnthropicClient client = AnthropicOkHttpClient.fromEnv();

  String summarizeDocument(String text, List<String> detailsToExtract, Model model, long maxTokens) {
      // Форматируем извлекаемые сведения для размещения в контексте подсказки
      String detailsToExtractStr = String.join("\n", detailsToExtract);

      // Просим модель кратко изложить договор субаренды
      String prompt = """
              Summarize the following sublease agreement. Focus on these key aspects:

                  %s

                  Provide the summary in bullet points nested within the XML header for each section. For example:

                  <parties involved>
                  - Sublessor: [Name]
                  // Add more details as needed
                  </parties involved>

                  If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.

                  Sublease agreement text:
                  %s
              """
              .formatted(detailsToExtractStr, text);

      Message response = client.messages().create(MessageCreateParams.builder()
              .model(model)
              .maxTokens(maxTokens)
              .system("You are a legal analyst specializing in real estate law, known for highly accurate and detailed summaries of sublease agreements.")
              .addUserMessage(prompt)
              .build());

      return response.content().stream()
              .flatMap(block -> block.text().stream())
              .findFirst()
              .orElseThrow()
              .text();
  }

  void printSubleaseSummary() {
      String subleaseSummary = summarizeDocument(
              documentText, detailsToExtract, Model.CLAUDE_OPUS_5_5, 16000);
      IO.println(subleaseSummary);
  }
  ```

  ```php PHP
  // Инициализируем клиент Anthropic
  $client = new Client();

  $summarizeDocument = function (
      string $text,
      array $detailsToExtract,
      Model $model = Model::CLAUDE_OPUS_5_5,
      int $maxTokens = 16000,
  ) use ($client): string {
      // Форматируем извлекаемые сведения для размещения в контексте подсказки
      $detailsToExtractStr = implode("\n", $detailsToExtract);

      // Просим модель кратко изложить договор субаренды
      $prompt = <<<PROMPT
          Summarize the following sublease agreement. Focus on these key aspects:

              {$detailsToExtractStr}

              Provide the summary in bullet points nested within the XML header for each section. For example:

              <parties involved>
              - Sublessor: [Name]
              // Add more details as needed
              </parties involved>

              If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.

              Sublease agreement text:
              {$text}
          PROMPT;

      $response = $client->messages->create(
          model: $model,
          maxTokens: $maxTokens,
          system: 'You are a legal analyst specializing in real estate law, known for highly accurate and detailed summaries of sublease agreements.',
          messages: [['role' => 'user', 'content' => $prompt]],
      );

      $textBlock = array_find($response->content, fn ($block) => $block instanceof \Anthropic\Messages\TextBlock)
          ?? throw new \RuntimeException('Expected a text block in the response.');

      return $textBlock->text;
  };

  $subleaseSummary = $summarizeDocument($documentText, $detailsToExtract);
  echo $subleaseSummary . "\n";
  ```

  ```ruby Ruby
  # Инициализируем клиент Anthropic
  CLIENT = Anthropic::Client.new

  def summarize_document(text, details_to_extract, model: Anthropic::Model::CLAUDE_OPUS_5_5, max_tokens: 16_000)
    # Форматируем извлекаемые сведения для размещения в контексте подсказки
    details_to_extract_str = details_to_extract.join("\n")

    # Просим модель кратко изложить договор субаренды
    prompt = <<~PROMPT
      Summarize the following sublease agreement. Focus on these key aspects:

          #{details_to_extract_str}

          Provide the summary in bullet points nested within the XML header for each section. For example:

          <parties involved>
          - Sublessor: [Name]
          // Add more details as needed
          </parties involved>

          If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.

          Sublease agreement text:
          #{text}
    PROMPT

    response = CLIENT.messages.create(
      model:,
      max_tokens:,
      system_: "You are a legal analyst specializing in real estate law, known for highly accurate and detailed summaries of sublease agreements.",
      messages: [{role: :user, content: prompt}]
    )

    response.content.find { |block| block.is_a?(Anthropic::Models::TextBlock) }.text
  end

  sublease_summary = summarize_document(document_text, details_to_extract)
  puts sublease_summary
  ```
</CodeGroup>

Этот код реализует функцию `summarize_document` (typescript, go, java: `summarizeDocument`; php: `$summarizeDocument`; csharp: `SummarizeDocument`), которая использует Claude для резюмирования содержимого договора субаренды. Функция принимает на вход текстовую строку и список сведений для извлечения. В этом примере код вызывает функцию с переменными `document_text` (typescript, go, java, csharp: `documentText`; php: `$documentText`) и `details_to_extract` (typescript, go, java, csharp: `detailsToExtract`; php: `$detailsToExtract`), которые были определены в предыдущих фрагментах кода.

Внутри функции для Claude формируется подсказка, включающая документ для резюмирования, сведения для извлечения и конкретные инструкции по резюмированию документа. Подсказка предписывает Claude ответить резюме по каждому извлекаемому сведению, вложенным в XML-заголовки.

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

### Оцените вашу подсказку

Подсказки часто требуют тестирования и оптимизации, чтобы быть готовыми к промышленной эксплуатации. Чтобы определить готовность вашего решения, оцените качество ваших резюме с помощью систематического процесса, сочетающего количественные и качественные методы. Создание [надёжной эмпирической оценки](https://platform.claude.com/docs/ru/test-and-evaluate/develop-tests#build-evaluations) на основе определённых вами критериев успеха позволяет оптимизировать ваши подсказки. Вот некоторые метрики, которые вы можете включить в свою эмпирическую оценку:

<AccordionGroup>
  <Accordion title="Оценки ROUGE">
    Эта метрика измеряет совпадение между созданным резюме и эталонным резюме, составленным экспертом. Она в первую очередь ориентирована на полноту (recall) и полезна для оценки охвата содержания.
  </Accordion>

  <Accordion title="Оценки BLEU">
    Хотя изначально эта метрика была разработана для машинного перевода, её можно адаптировать для задач резюмирования. Оценки BLEU измеряют точность (precision) совпадений n-грамм между созданным резюме и эталонными резюме. Более высокая оценка указывает на то, что созданное резюме содержит фразы и терминологию, схожие с эталонным резюме. 
  </Accordion>

  <Accordion title="Сходство контекстных эмбеддингов">
    Эта метрика предполагает создание векторных представлений (эмбеддингов) как созданного, так и эталонного резюме. Затем вычисляется сходство между этими эмбеддингами, часто с использованием косинусного сходства. Более высокие показатели сходства указывают на то, что созданное резюме передаёт семантический смысл и контекст эталонного резюме, даже если точные формулировки различаются.
  </Accordion>

  <Accordion title="Оценка на основе LLM">
    Этот метод предполагает использование LLM, такой как Claude, для оценки качества созданных резюме по оценочной рубрике. Рубрику можно адаптировать под ваши конкретные потребности, оценивая ключевые факторы, такие как точность, полнота и связность. Рекомендации по реализации см. в разделе 

    [Советы по оценке на основе LLM](https://platform.claude.com/docs/ru/test-and-evaluate/develop-tests#tips-for-llm-based-grading)

    .
  </Accordion>

  <Accordion title="Оценка человеком">
    Помимо создания эталонных резюме, эксперты в области права также могут оценивать качество созданных резюме. Хотя в больших масштабах это дорого и трудоёмко, такую оценку часто проводят на нескольких резюме в качестве проверки перед развёртыванием в промышленной среде.
  </Accordion>
</AccordionGroup>

### Разверните вашу подсказку

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

1. **Исключите ответственность:** Осознайте юридические последствия ошибок в резюме, которые могут привести к юридической ответственности вашей организации или клиентов. Предоставьте оговорки или юридические уведомления, разъясняющие, что резюме созданы ИИ и должны быть проверены юристами.

2. **Обрабатывайте различные типы документов:** В этом руководстве рассматривается, как извлекать текст из PDF-файлов. В реальном мире документы могут поступать в различных форматах (например, PDF-файлы, документы Word и текстовые файлы). Убедитесь, что ваш конвейер извлечения данных может преобразовывать все форматы файлов, которые вы ожидаете получать.

3. **Распараллеливайте вызовы API к Claude:** Для длинных документов с большим количеством токенов Claude может потребоваться до минуты на создание резюме. Для больших коллекций документов вы можете отправлять вызовы API к Claude параллельно, чтобы резюме были готовы в разумные сроки. Обратитесь к [ограничениям скорости](https://platform.claude.com/docs/ru/api/rate-limits#rate-limits) Anthropic, чтобы определить максимальное количество вызовов API, которые можно выполнять параллельно.

***

## Повышение производительности

В сложных сценариях может быть полезно рассмотреть дополнительные стратегии повышения производительности помимо стандартных [техник инженерии подсказок](https://platform.claude.com/docs/ru/build-with-claude/prompt-engineering/overview). Вот несколько продвинутых стратегий:

### Выполняйте мета-резюмирование для резюмирования длинных документов

Резюмирование юридических документов часто предполагает работу с длинными документами или множеством связанных документов одновременно, так что вы превышаете «context window» (контекстное окно) Claude. Для этого сценария использования можно применить метод разбиения на фрагменты, известный как мета-резюмирование. Эта техника предполагает разбиение документов на более мелкие, удобные для обработки фрагменты и последующую обработку каждого фрагмента отдельно. Затем вы можете объединить резюме каждого фрагмента, чтобы создать мета-резюме всего документа.

Вот пример того, как выполнить мета-резюмирование:

<CodeGroup exclude="shell">
  <CodeGroupItem language="cURL">
    Этот рабочий процесс требует больше логики, чем одна команда оболочки. Используйте Claude SDK для его запуска.
  </CodeGroupItem>

  <CodeGroupItem language="CLI">
    Этот рабочий процесс требует больше логики, чем одна команда оболочки. Используйте Claude SDK для его запуска.
  </CodeGroupItem>

  ```python Python
  def chunk_text(text, chunk_size=20000):
      return [text[i : i + chunk_size] for i in range(0, len(text), chunk_size)]


  def summarize_long_document(
      text, details_to_extract, model="claude-opus-5-5", max_tokens=16000
  ):
      # Форматируем извлекаемые сведения для размещения в контексте подсказки
      details_to_extract_str = "\n".join(details_to_extract)

      # Перебираем фрагменты и кратко излагаем каждый
      chunk_summaries = [
          summarize_document(
              chunk, details_to_extract, model=model, max_tokens=max_tokens
          )
          for chunk in chunk_text(text)
      ]

      final_summary_prompt = f"""

      You are looking at the chunked summaries of multiple documents that are all related.
      Combine the following summaries of the document from different truthful sources into a coherent overall summary:

      <chunked_summaries>
      {"".join(chunk_summaries)}
      </chunked_summaries>

      Focus on these key aspects:
      {details_to_extract_str}

      Provide the summary in bullet points nested within the XML header for each section. For example:

      <parties involved>
      - Sublessor: [Name]
      // Add more details as needed
      </parties involved>

      If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.
      """

      response = client.messages.create(
          model=model,
          max_tokens=max_tokens,
          system="You are a legal expert that summarizes notes on one document.",
          messages=[
              {"role": "user", "content": final_summary_prompt},
          ],
      )

      return next(block.text for block in response.content if block.type == "text")


  long_summary = summarize_long_document(document_text, details_to_extract)
  print(long_summary)
  ```

  ```typescript TypeScript
  function chunkText(text: string, chunkSize = 20000): string[] {
    return Array.from({ length: Math.ceil(text.length / chunkSize) }, (_, index) =>
      text.slice(index * chunkSize, (index + 1) * chunkSize)
    );
  }

  async function summarizeLongDocument(
    text: string,
    detailsToExtract: string[],
    model: Anthropic.Model = "claude-opus-5-5",
    maxTokens = 16000
  ): Promise<string> {
    // Форматируем извлекаемые сведения для размещения в контексте подсказки
    const detailsToExtractStr = detailsToExtract.join("\n");

    // Перебираем фрагменты и кратко излагаем каждый
    const chunkSummaries: string[] = [];
    for (const chunk of chunkText(text)) {
      chunkSummaries.push(await summarizeDocument(chunk, detailsToExtract, model, maxTokens));
    }

    const finalSummaryPrompt = `

      You are looking at the chunked summaries of multiple documents that are all related.
      Combine the following summaries of the document from different truthful sources into a coherent overall summary:

      <chunked_summaries>
      ${chunkSummaries.join("")}
      </chunked_summaries>

      Focus on these key aspects:
      ${detailsToExtractStr}

      Provide the summary in bullet points nested within the XML header for each section. For example:

      <parties involved>
      - Sublessor: [Name]
      // Add more details as needed
      </parties involved>

      If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.
      `;

    const response = await client.messages.create({
      model,
      max_tokens: maxTokens,
      system: "You are a legal expert that summarizes notes on one document.",
      messages: [{ role: "user", content: finalSummaryPrompt }]
    });

    const textBlock = response.content.find((block) => block.type === "text");
    if (!textBlock) {
      throw new Error("Expected a text block in the response");
    }
    return textBlock.text;
  }

  const longSummary = await summarizeLongDocument(documentText, detailsToExtract);
  console.log(longSummary);
  ```

  ```csharp C#
  IEnumerable<string> ChunkText(string text, int chunkSize = 20000) =>
      text.Chunk(chunkSize).Select(chars => new string(chars));

  async Task<string> SummarizeLongDocument(
      string text,
      IReadOnlyList<string> detailsToExtract,
      Model model = Model.ClaudeOpus5_5,
      long maxTokens = 16000
  )
  {
      // Форматируем извлекаемые сведения для размещения в контексте подсказки
      var detailsToExtractStr = string.Join("\n", detailsToExtract);

      // Перебираем фрагменты и кратко излагаем каждый
      List<string> chunkSummaries = [];
      foreach (var chunk in ChunkText(text))
      {
          chunkSummaries.Add(await SummarizeDocument(chunk, detailsToExtract, model, maxTokens));
      }

      var finalSummaryPrompt = $"""

              You are looking at the chunked summaries of multiple documents that are all related.
              Combine the following summaries of the document from different truthful sources into a coherent overall summary:

              <chunked_summaries>
              {string.Concat(chunkSummaries)}
              </chunked_summaries>

              Focus on these key aspects:
              {detailsToExtractStr}

              Provide the summary in bullet points nested within the XML header for each section. For example:

              <parties involved>
              - Sublessor: [Name]
              // Add more details as needed
              </parties involved>

              If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.
          """;

      var response = await client.Messages.Create(
          new()
          {
              Model = model,
              MaxTokens = maxTokens,
              System = "You are a legal expert that summarizes notes on one document.",
              Messages = [new() { Role = Role.User, Content = finalSummaryPrompt }],
          }
      );

      foreach (var block in response.Content)
      {
          if (block.TryPickText(out var textBlock))
          {
              return textBlock.Text;
          }
      }
      throw new InvalidOperationException("Expected a text block in the response.");
  }

  var longSummary = await SummarizeLongDocument(documentText, detailsToExtract);
  Console.WriteLine(longSummary);
  ```

  ```go Go
  func chunkText(text string, chunkSize int) []string {
  	var chunks []string
  	for chunk := range slices.Chunk([]rune(text), chunkSize) {
  		chunks = append(chunks, string(chunk))
  	}
  	return chunks
  }

  func summarizeLongDocument(text string, detailsToExtract []string, model anthropic.Model, maxTokens int64) string {
  	// Форматируем извлекаемые сведения для размещения в контексте подсказки
  	detailsToExtractStr := strings.Join(detailsToExtract, "\n")

  	// Перебираем фрагменты и кратко излагаем каждый
  	var chunkSummaries []string
  	for _, chunk := range chunkText(text, 20000) {
  		chunkSummaries = append(chunkSummaries, summarizeDocument(chunk, detailsToExtract, model, maxTokens))
  	}

  	finalSummaryPrompt := fmt.Sprintf(`

      You are looking at the chunked summaries of multiple documents that are all related.
      Combine the following summaries of the document from different truthful sources into a coherent overall summary:

      <chunked_summaries>
      %s
      </chunked_summaries>

      Focus on these key aspects:
      %s

      Provide the summary in bullet points nested within the XML header for each section. For example:

      <parties involved>
      - Sublessor: [Name]
      // Add more details as needed
      </parties involved>

      If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.
      `, strings.Join(chunkSummaries, ""), detailsToExtractStr)

  	response, err := client.Messages.New(context.Background(), anthropic.MessageNewParams{
  		Model:     model,
  		MaxTokens: maxTokens,
  		System: []anthropic.TextBlockParam{
  			{Text: "You are a legal expert that summarizes notes on one document."},
  		},
  		Messages: []anthropic.MessageParam{
  			anthropic.NewUserMessage(anthropic.NewTextBlock(finalSummaryPrompt)),
  		},
  	})
  	if err != nil {
  		log.Fatal(err)
  	}

  	for _, block := range response.Content {
  		if textBlock, ok := block.AsAny().(anthropic.TextBlock); ok {
  			return textBlock.Text
  		}
  	}
  	panic("expected a text block in the response")
  }

  // printLongSummary излагает договор субаренды по фрагментам и выводит объединённое резюме.
  func printLongSummary() {
  	longSummary := summarizeLongDocument(documentText, detailsToExtract, anthropic.ModelClaudeOpus5_5, 16000)
  	fmt.Println(longSummary)
  }
  ```

  ```java Java
  List<String> chunkText(String text, int chunkSize) {
      return IntStream.iterate(0, start -> start < text.length(), start -> start + chunkSize)
              .mapToObj(start -> text.substring(start, Math.min(start + chunkSize, text.length())))
              .toList();
  }

  String summarizeLongDocument(String text, List<String> detailsToExtract, Model model, long maxTokens) {
      // Форматируем извлекаемые сведения для размещения в контексте подсказки
      String detailsToExtractStr = String.join("\n", detailsToExtract);

      // Перебираем фрагменты и кратко излагаем каждый
      String chunkSummaries = chunkText(text, 20000).stream()
              .map(chunk -> summarizeDocument(chunk, detailsToExtract, model, maxTokens))
              .collect(Collectors.joining());

      String finalSummaryPrompt = """

                  You are looking at the chunked summaries of multiple documents that are all related.
                  Combine the following summaries of the document from different truthful sources into a coherent overall summary:

                  <chunked_summaries>
                  %s
                  </chunked_summaries>

                  Focus on these key aspects:
                  %s

                  Provide the summary in bullet points nested within the XML header for each section. For example:

                  <parties involved>
                  - Sublessor: [Name]
                  // Add more details as needed
                  </parties involved>

                  If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.
              """
              .formatted(chunkSummaries, detailsToExtractStr);

      Message response = client.messages().create(MessageCreateParams.builder()
              .model(model)
              .maxTokens(maxTokens)
              .system("You are a legal expert that summarizes notes on one document.")
              .addUserMessage(finalSummaryPrompt)
              .build());

      return response.content().stream()
              .flatMap(block -> block.text().stream())
              .findFirst()
              .orElseThrow()
              .text();
  }

  void printLongSummary() {
      String longSummary = summarizeLongDocument(
              documentText, detailsToExtract, Model.CLAUDE_OPUS_5_5, 16000);
      IO.println(longSummary);
  }
  ```

  ```php PHP
  $chunkText = fn (string $text, int $chunkSize = 20000): array => mb_str_split($text, $chunkSize);

  $summarizeLongDocument = function (
      string $text,
      array $detailsToExtract,
      Model $model = Model::CLAUDE_OPUS_5_5,
      int $maxTokens = 16000,
  ) use ($client, $chunkText, $summarizeDocument): string {
      // Форматируем извлекаемые сведения для размещения в контексте подсказки
      $detailsToExtractStr = implode("\n", $detailsToExtract);

      // Перебираем фрагменты и кратко излагаем каждый
      $chunkSummaries = array_map(
          fn (string $chunk) => $summarizeDocument($chunk, $detailsToExtract, $model, $maxTokens),
          $chunkText($text),
      );
      $chunkSummariesStr = implode('', $chunkSummaries);

      $finalSummaryPrompt = <<<PROMPT

              You are looking at the chunked summaries of multiple documents that are all related.
              Combine the following summaries of the document from different truthful sources into a coherent overall summary:

              <chunked_summaries>
              {$chunkSummariesStr}
              </chunked_summaries>

              Focus on these key aspects:
              {$detailsToExtractStr}

              Provide the summary in bullet points nested within the XML header for each section. For example:

              <parties involved>
              - Sublessor: [Name]
              // Add more details as needed
              </parties involved>

              If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.
          PROMPT;

      $response = $client->messages->create(
          model: $model,
          maxTokens: $maxTokens,
          system: 'You are a legal expert that summarizes notes on one document.',
          messages: [['role' => 'user', 'content' => $finalSummaryPrompt]],
      );

      $textBlock = array_find($response->content, fn ($block) => $block instanceof \Anthropic\Messages\TextBlock)
          ?? throw new \RuntimeException('Expected a text block in the response.');

      return $textBlock->text;
  };

  $longSummary = $summarizeLongDocument($documentText, $detailsToExtract);
  echo $longSummary . "\n";
  ```

  ```ruby Ruby
  def chunk_text(text, chunk_size: 20_000)
    text.chars.each_slice(chunk_size).map(&:join)
  end

  def summarize_long_document(text, details_to_extract, model: Anthropic::Model::CLAUDE_OPUS_5_5, max_tokens: 16_000)
    # Форматируем извлекаемые сведения для размещения в контексте подсказки
    details_to_extract_str = details_to_extract.join("\n")

    # Перебираем фрагменты и кратко излагаем каждый
    chunk_summaries = chunk_text(text).map do |chunk|
      summarize_document(chunk, details_to_extract, model:, max_tokens:)
    end

    final_summary_prompt = <<~PROMPT

          You are looking at the chunked summaries of multiple documents that are all related.
          Combine the following summaries of the document from different truthful sources into a coherent overall summary:

          <chunked_summaries>
          #{chunk_summaries.join}
          </chunked_summaries>

          Focus on these key aspects:
          #{details_to_extract_str}

          Provide the summary in bullet points nested within the XML header for each section. For example:

          <parties involved>
          - Sublessor: [Name]
          // Add more details as needed
          </parties involved>

          If any information is not explicitly stated in the document, note it as "Not specified". Do not preamble.
    PROMPT

    response = CLIENT.messages.create(
      model:,
      max_tokens:,
      system_: "You are a legal expert that summarizes notes on one document.",
      messages: [{role: :user, content: final_summary_prompt}]
    )

    response.content.find { |block| block.is_a?(Anthropic::Models::TextBlock) }.text
  end

  long_summary = summarize_long_document(document_text, details_to_extract)
  puts long_summary
  ```
</CodeGroup>

Функция `summarize_long_document` (typescript, go, java: `summarizeLongDocument`; php: `$summarizeLongDocument`; csharp: `SummarizeLongDocument`) развивает ранее описанную функцию `summarize_document` (typescript, go, java: `summarizeDocument`; php: `$summarizeDocument`; csharp: `SummarizeDocument`), разбивая документ на более мелкие фрагменты и резюмируя каждый фрагмент по отдельности.

Код достигает этого, применяя функцию `summarize_document` (typescript, go, java: `summarizeDocument`; php: `$summarizeDocument`; csharp: `SummarizeDocument`) к каждому фрагменту длиной 20 000 символов в исходном документе. Затем отдельные резюме объединяются, и из этих резюме фрагментов создаётся итоговое резюме.

Обратите внимание, что функция `summarize_long_document` (typescript, go, java: `summarizeLongDocument`; php: `$summarizeLongDocument`; csharp: `SummarizeLongDocument`) не является строго необходимой для примера PDF-файла, поскольку весь документ помещается в контекстное окно Claude. Однако она становится необходимой для документов, превышающих контекстное окно Claude, или при совместном резюмировании нескольких связанных документов. В любом случае эта техника мета-резюмирования часто позволяет включить в итоговое резюме дополнительные важные детали, которые были упущены при прежнем подходе с одним резюме.

### Используйте документы с индексацией по резюме для изучения большой коллекции документов

Поиск по коллекции документов с помощью LLM обычно предполагает «retrieval-augmented generation» (генерацию с дополнением извлечёнными данными), или RAG. Однако в сценариях с большими документами или когда точное извлечение информации имеет решающее значение, базового подхода RAG может быть недостаточно. Документы с индексацией по резюме — это продвинутый подход RAG, который обеспечивает более эффективный способ ранжирования документов для извлечения, используя меньше контекста, чем традиционные методы RAG. В этом подходе вы сначала используете Claude для создания краткого резюме каждого документа в вашем корпусе, а затем используете Claude для ранжирования релевантности каждого резюме по отношению к заданному запросу. Подробнее об этом подходе, включая пример с кодом, см. в разделе о документах с индексацией по резюме в [сборнике рецептов по резюмированию](https://platform.claude.com/cookbook/capabilities-summarization-guide).

### Дообучите Claude на вашем наборе данных

Ещё одна продвинутая техника для улучшения способности Claude создавать резюме — «fine-tuning» (дообучение). Дообучение предполагает обучение Claude на пользовательском наборе данных, который специально соответствует вашим потребностям в резюмировании юридических документов, обеспечивая адаптацию Claude к вашему сценарию использования. Вот обзор того, как выполнить дообучение:

1. **Выявите ошибки:** Начните со сбора случаев, когда резюме Claude не соответствуют требованиям — это может включать пропуск критически важных юридических деталей, неправильное понимание контекста или использование неподходящей юридической терминологии.

2. **Подготовьте набор данных:** После выявления этих проблем составьте набор данных из таких проблемных примеров. Этот набор данных должен включать исходные юридические документы вместе с вашими исправленными резюме, чтобы Claude усвоил желаемое поведение.

3. **Выполните дообучение:** Дообучение предполагает повторное обучение модели на подготовленном вами наборе данных для корректировки её весов и параметров. Такое повторное обучение помогает Claude лучше адаптироваться к специфическим требованиям вашей правовой области, улучшая его способность резюмировать документы в соответствии с вашими стандартами.

4. **Итеративное улучшение:** Дообучение — это не одноразовый процесс. По мере того как Claude продолжает создавать резюме, вы можете итеративно добавлять новые примеры, в которых он показал недостаточные результаты, дополнительно совершенствуя его возможности. Со временем этот непрерывный цикл обратной связи приведёт к созданию модели, высоко специализированной для ваших задач резюмирования юридических документов.

<Tip>
  Дообучение в настоящее время доступно только через Amazon Bedrock. Дополнительные сведения доступны в 

  [блоге AWS о запуске](https://aws.amazon.com/blogs/machine-learning/fine-tune-anthropics-claude-3-haiku-in-amazon-bedrock-to-boost-model-accuracy-and-quality/)

  .
</Tip>

<CardGroup cols={2}>
  <Card title="Сборник рецептов по резюмированию" icon="link" href="https://platform.claude.com/cookbook/capabilities-summarization-guide">
    Посмотрите полностью реализованный пример с кодом, показывающий, как использовать Claude для резюмирования договоров.
  </Card>

  <Card title="Сборник рецептов по цитированию" icon="link" href="https://platform.claude.com/cookbook/misc-using-citations">
    Изучите рецепт из сборника по цитированию, чтобы получить рекомендации о том, как обеспечить точность и объяснимость информации.
  </Card>
</CardGroup>
