---
read_when:
    - Вы изменяете форматирование Markdown или разбиение на фрагменты для исходящих каналов
    - Вы добавляете новый форматтер канала или сопоставление стилей
    - Вы отлаживаете регрессии форматирования в разных каналах
summary: Конвейер форматирования Markdown для исходящих каналов
title: Форматирование Markdown
x-i18n:
    generated_at: "2026-06-28T22:50:11Z"
    model: gpt-5.5
    postprocess_version: locale-links-v1
    provider: openai
    source_hash: 8db92aaf1063ebcbd8630dfcb8ca0a4e9eeb1c64f5b8868bf11c836777180515
    source_path: concepts/markdown-formatting.md
    workflow: 16
---

OpenClaw форматирует исходящий Markdown, преобразуя его в общее промежуточное
представление (IR) перед рендерингом вывода для конкретного канала. IR сохраняет
исходный текст без изменений, одновременно передавая диапазоны стилей/ссылок, чтобы разбиение на фрагменты и рендеринг
оставались согласованными между каналами.

## Цели

- **Согласованность:** один этап разбора, несколько рендереров.
- **Безопасное разбиение:** разделение текста перед рендерингом, чтобы встроенное форматирование никогда
  не разрывалось между фрагментами.
- **Соответствие каналу:** сопоставление одного и того же IR с Slack mrkdwn, Telegram HTML и диапазонами
  стилей Signal без повторного разбора Markdown.

## Конвейер

1. **Разбор Markdown -> IR**
   - IR — это обычный текст плюс диапазоны стилей (жирный/курсив/зачеркнутый/код/спойлер) и диапазоны ссылок.
   - Смещения указаны в кодовых единицах UTF-16, чтобы диапазоны стилей Signal совпадали с его API.
   - Таблицы разбираются только тогда, когда канал включает преобразование таблиц.
2. **Разбиение IR (сначала форматирование)**
   - Разбиение выполняется по тексту IR перед рендерингом.
   - Встроенное форматирование не разделяется между фрагментами; диапазоны нарезаются для каждого фрагмента.
3. **Рендеринг для каждого канала**
   - **Slack:** токены mrkdwn (жирный/курсив/зачеркнутый/код), ссылки как `<url|label>`.
   - **Telegram:** HTML-теги (`<b>`, `<i>`, `<s>`, `<code>`, `<pre><code>`, `<a href>`).
   - **Signal:** обычный текст + диапазоны `text-style`; ссылки становятся `label (url)`, когда метка отличается.

## Пример IR

Входной Markdown:

```markdown
Hello **world** - see [docs](https://docs.openclaw.ai).
```

IR (схематично):

```json
{
  "text": "Hello world - see docs.",
  "styles": [{ "start": 6, "end": 11, "style": "bold" }],
  "links": [{ "start": 19, "end": 23, "href": "https://docs.openclaw.ai" }]
}
```

## Где это используется

- Исходящие адаптеры Slack, Telegram и Signal выполняют рендеринг из IR.
- Другие каналы (WhatsApp, iMessage, Microsoft Teams, Discord) по-прежнему используют обычный текст или
  собственные правила форматирования, с преобразованием таблиц Markdown перед
  разбиением, когда оно включено.

## Обработка таблиц

Таблицы Markdown поддерживаются клиентами чатов неодинаково. Используйте
`markdown.tables`, чтобы управлять преобразованием для каждого канала (и для каждой учетной записи).

- `code`: рендерить таблицы как блоки кода (по умолчанию для большинства каналов).
- `bullets`: преобразовывать каждую строку в пункты маркированного списка (по умолчанию для Matrix, Signal и WhatsApp).
- `off`: отключить разбор и преобразование таблиц; исходный текст таблицы передается дальше.

Ключи конфигурации:

```yaml
channels:
  discord:
    markdown:
      tables: code
    accounts:
      work:
        markdown:
          tables: off
```

## Правила разбиения

- Лимиты фрагментов берутся из адаптеров/конфигурации каналов и применяются к тексту IR.
- Блоки кода сохраняются как единый блок с завершающим переводом строки, чтобы каналы
  корректно их рендерили.
- Префиксы списков и цитат являются частью текста IR, поэтому разбиение
  не происходит внутри префикса.
- Встроенные стили (жирный/курсив/зачеркнутый/встроенный код/спойлер) никогда не разделяются между
  фрагментами; рендерер заново открывает стили внутри каждого фрагмента.

Если вам нужно больше информации о поведении разбиения между каналами, см.
[Потоковая передача + разбиение](/ru/concepts/streaming).

## Политика ссылок

- **Slack:** `[label](url)` -> `<url|label>`; голые URL остаются голыми. Автоссылки
  отключены во время разбора, чтобы избежать двойного связывания.
- **Telegram:** `[label](url)` -> `<a href="url">label</a>` (режим разбора HTML).
- **Signal:** `[label](url)` -> `label (url)`, если метка не совпадает с URL.

## Спойлеры

Маркеры спойлеров (`||spoiler||`) разбираются только для Signal, где они сопоставляются с
диапазонами стиля SPOILER. Другие каналы обрабатывают их как обычный текст.

## Как добавить или обновить форматтер канала

1. **Разобрать один раз:** используйте общий помощник `markdownToIR(...)` с подходящими для канала
   параметрами (автоссылки, стиль заголовков, префикс цитаты).
2. **Отрендерить:** реализуйте рендерер с `renderMarkdownWithMarkers(...)` и
   картой маркеров стилей (или диапазонами стилей Signal).
3. **Разбить:** вызовите `chunkMarkdownIR(...)` перед рендерингом; отрендерьте каждый фрагмент.
4. **Подключить адаптер:** обновите исходящий адаптер канала, чтобы он использовал новый разделитель
   и рендерер.
5. **Протестировать:** добавьте или обновите тесты форматирования и тест исходящей доставки, если
   канал использует разбиение.

## Частые подводные камни

- Токены Slack в угловых скобках (`<@U123>`, `<#C123>`, `<https://...>`) должны
  сохраняться; безопасно экранируйте необработанный HTML.
- Telegram HTML требует экранирования текста вне тегов, чтобы избежать поврежденной разметки.
- Диапазоны стилей Signal зависят от смещений UTF-16; не используйте смещения по кодовым точкам.
- Сохраняйте завершающие переводы строк для огражденных блоков кода, чтобы закрывающие маркеры попадали на
  отдельную строку.

## Связанные материалы

<CardGroup cols={2}>
  <Card title="Streaming and chunking" href="/ru/concepts/streaming" icon="bars-staggered">
    Поведение исходящей потоковой передачи, границы фрагментов и доставка с учетом особенностей канала.
  </Card>
  <Card title="System prompt" href="/ru/concepts/system-prompt" icon="message-lines">
    Что модель видит перед разговором, включая внедренные файлы рабочей области.
  </Card>
</CardGroup>
