# Fragment responses

A fragment response contains only the elements the agent changed. Change one heading in a long manual, and the response holds that heading, not the manual. You pay for fewer tokens and wait less time.

A standard LLM call returns the whole document, because the model rewrites everything around the change to keep the HTML valid. CKEditor AI returns a fragment instead: the elements the agent edited, added, or removed, and a comment in place of everything else.

This page describes what a fragment contains and how to apply one to your document.

<a id="what-is-a-fragment">

## What is a fragment?

A fragment is one block of HTML and HTML comments that describes the changes to a document. Each element appears in one of these forms:

* **Edited element:** the element’s HTML with its new content and the `data-id` it already had.
* **Added element:** the element’s HTML with `data-id="new-element"`.
* **Removed element:** the comment `<!-- removed data-id="the-id" -->`.
* **Unchanged content:** the comment `<!-- existing document -->`. One comment stands for one group of elements that did not change, whether that group is one element or fifty. `<!-- existing content -->` means the same thing, and both forms arrive.

<a id="element-identifiers">

## Element identifiers

Add a unique `data-id` attribute to every element before you send the document. Without it, the fragment cannot tell you which element changed.

Every element in the fragment has a `data-id` attribute. For an edited or removed element, the `data-id` is the one the element has in the document you sent. Use it to find the element in your copy and apply the change.

The ids can take any form as long as they are unique. Short ones, such as four random letters, cost fewer tokens. They have to stay stable for the life of the request, and the copy you merge into has to be the snapshot you sent. A fragment never names an id the document did not have. After you apply one, give every element a unique id again, so the next request can address the new ones.

Reviews use the same convention. Each suggestion names the element it applies to. See [How results are anchored](reviews.md#how-results-are-anchored).

<a id="merge-rules">

## Merge rules

Walk the fragment in document order and apply each part to your copy:

* **Replace:** an element that carries a `data-id` from your document replaces that element. A change inside it, such as a new link or a bolded word, arrives as the whole element.
* **Insert:** an element with `data-id="new-element"` is new. Put it where it sits among the elements the fragment names around it, or at the top of the document when it comes first.
* **Remove:** `<!-- removed data-id="p2" -->` deletes that element and everything inside it.
* **Move:** a move arrives as a removal in one place and a `new-element` insertion in another.
* **Reorder:** reordered elements arrive either as their whole parent with the children in the new order and their ids kept, or as a removal and a `new-element` insertion per moved element, the same as a move.
* **Any depth:** an element in the fragment can sit at any depth in your document, not only at the top level. Match on `data-id` wherever the element is, or a nested change lands as an insertion and duplicates the content.

<a id="examples">

## Examples

These fragments all describe changes to the same document:

```html
<h2 data-id="h1">Handheld emperor</h2>
<p data-id="p1">Nintendo started as a card manufacturer in 1889.</p>
<h3 data-id="h2">Handheld gaming</h3>
<p data-id="p2">The Game Boy changed everything.</p>
<ul data-id="l1">
	<li data-id="i1">LCD screen</li>
	<li data-id="i2">Button cells</li>
</ul>
<p data-id="p3">Nintendo keeps redefining portable gaming.</p>
```

<a id="rewriting-one-paragraph">

### Rewriting one paragraph

“Rewrite the second paragraph and say how many Game Boys were sold” comes back as the rewritten element between two runs of unchanged content:

```html
<!-- existing document -->

<p data-id="p2">The Game Boy sold 118 million units.</p>

<!-- existing document -->
```

Applied, only `p2` differs from the document above.

<a id="removing-a-section">

### Removing a section

“Remove the second heading, the paragraph, and the list behind it” names each element it removes:

```html
<!-- existing document -->

<!-- removed data-id="h2" -->
<!-- removed data-id="p2" -->
<!-- removed data-id="l1" -->

<!-- existing document -->
```

The list items `i1` and `i2` go with `l1`. What is left is:

```html
<h2 data-id="h1">Handheld emperor</h2>
<p data-id="p1">Nintendo started as a card manufacturer in 1889.</p>
<p data-id="p3">Nintendo keeps redefining portable gaming.</p>
```

<a id="adding-a-section">

### Adding a section

“Add a Game & Watch era section after the second paragraph” names the elements on either side of the new ones, so you know where they go:

```html
<!-- existing document -->

<p data-id="p2">The Game Boy changed everything.</p>

<h3 data-id="new-element">Game & Watch era</h3>
<p data-id="new-element">Nintendo's first portable line.</p>

<ul data-id="l1">
	<li data-id="i1">LCD screen</li>
	<li data-id="i2">Button cells</li>
</ul>

<!-- existing document -->
```

In your copy, the heading and the paragraph sit between `p2` and `l1`, and you give each of them an id of your own.

<a id="splitting-a-paragraph">

### Splitting a paragraph

“Split the first paragraph into two” keeps the id on the first part. The second part is a new element, and the fragment names `h2` so you know it goes before the heading:

```html
<!-- existing document -->

<p data-id="p1">Nintendo started as a card manufacturer.</p>
<p data-id="new-element">The company was founded in 1889.</p>

<h3 data-id="h2">Handheld gaming</h3>

<!-- existing document -->
```

Applied, `p1` holds the shorter sentence and a new paragraph follows it.

<a id="wrapping-an-element">

### Wrapping an element

“Wrap the last paragraph in a blockquote” arrives as a new wrapper with a new paragraph inside, followed by the removal of the original:

```html
<!-- existing document -->

<ul data-id="l1">
	<li data-id="i1">LCD screen</li>
	<li data-id="i2">Button cells</li>
</ul>

<blockquote data-id="new-element">
	<p data-id="new-element">Nintendo keeps redefining portable gaming.</p>
</blockquote>

<!-- removed data-id="p3" -->
```

The text is unchanged, but `p3` is gone. Any state you keep against that id, such as a comment thread, needs a new anchor.

<a id="applying-a-fragment">

## Applying a fragment

In CKEditor 5, the CKEditor AI plugin does the merge for you. See [What comes back in the response](how-it-works.md#what-comes-back-in-the-response).

To apply a fragment yourself, keep the document you sent and read the fragment in order. Apply each edit, addition, and removal to the element with the matching `data-id`, following the [merge rules](#merge-rules) above. Two cases need care. A parent and its child can both appear in the fragment, and a user can edit the document while the request runs.

To ask for fragments, set `responseFormat` to `arf`. See [Response format](document-processing.md#response-format) for the request field, and the [Document Processing reference](https://ai.cke-cs.com/v1/docs#tag/Document-processing) for the response schema.

<a id="next-steps">

## Next steps

* **[Document Processing](document-processing.md)** covers the request and response for editing whole documents in one call.
* **[Streaming protocol](streaming-protocol.md)** lists the events that contain fragments on the streaming endpoints.

---

Full index of the Cloud Services documentation: [llms.txt](../../../llms.txt)
