Deep Agents
AgentContextOrchestratorRetrievalText2SQLToolbox

Fragments

Understand context fragments - the building blocks of structured LLM prompts

Context fragments are the atomic units of context in the deepagents system. In practice, you create them with helpers instead of constructing raw fragment objects yourself.

Core Idea

Fragments let you describe context structurally:

  • instructions through role()
  • guidance through hint()
  • terminology through term()
  • user state through user fragments like identity() and preference()
  • conversation turns through user(), assistantText(), and assistant()
  • grouping through fragment()

That gives you reusable context that can be rendered into different prompt formats without manually concatenating strings.

Common Fragment Helpers

role(content)

Creates a system role instruction:

import { role } from '@deepagents/context';

role('You are a helpful assistant.');

hint(text)

Creates a guidance hint:

import { hint } from '@deepagents/context';

hint('Keep responses under 100 words.');

user(content, ...reminders)

Creates a user message fragment. It is classified as a message fragment and is persisted by context.save().

import { user } from '@deepagents/context';

user('What is TypeScript?');

user({
  id: 'msg-001',
  role: 'user',
  parts: [{ type: 'text', text: 'Hello' }],
});

assistant(message)

Wraps an existing assistant UIMessage as a message fragment:

import { assistant } from '@deepagents/context';

assistant({
  id: 'resp-001',
  role: 'assistant',
  parts: [{ type: 'text', text: 'TypeScript is a typed superset of JavaScript.' }],
});

assistantText(content, options?)

Creates an assistant text message and wraps it as a message fragment:

import { assistantText } from '@deepagents/context';

assistantText('TypeScript is a typed superset of JavaScript.');
assistantText('Done', { id: 'resp-001' });

fragment(name, ...children)

Creates a wrapper fragment for grouping related context:

import { fragment, hint } from '@deepagents/context';

fragment(
  'sql_guidelines',
  hint('Use CTEs for complex queries'),
  hint('Always include LIMIT clause'),
  hint('Prefer explicit JOINs over implicit'),
);

Message vs Regular Fragments

Fragments are categorized into two types:

TypeCreated ByBehavior
Regularrole(), hint(), fragment() and other non-message buildersRendered into systemPrompt
Messageuser(), assistantText(), assistant(), message()Returned as messages[]

During resolve(), these are automatically separated:

const context = new ContextEngine({ store }).set(
  role('You are helpful.'),
  hint('Be concise.'),
  user('Hello!'),
  assistantText('Hi there!'),
  user('How are you?'),
);

const { systemPrompt, messages } = await context.resolve({
  renderer: new XmlRenderer(),
});

The result is:

  • systemPrompt: rendered from regular fragments
  • messages: AI SDK UIMessage[] built from message fragments

Persistence

Message fragments are saved when you call context.save():

context.set(user('Hello'));
context.set(assistantText('Hi!'));
context.set(hint('Be helpful'));

await context.save();

In that example:

  • user('Hello') is saved
  • assistantText('Hi!') is saved
  • hint('Be helpful') stays in memory and contributes to the system prompt

Non-message fragments are not written into the conversation graph by context.save().

Storing Non-Message Fragments

If you want to persist non-message fragments in your own database, use the serialization helpers:

import { fromFragment, term, toFragment } from '@deepagents/context';

const stored = fromFragment(term('MRR', 'monthly recurring revenue'));
await db.fragments.create({ payload: stored });

const loaded = await db.fragments.findFirstOrThrow();
context.set(toFragment(loaded.payload));

See Fragment Serialization for the supported serialized fragment types and round-trip examples.

Nesting Fragments

Fragments can nest arbitrarily deep:

fragment(
  'domain_knowledge',
  fragment(
    'terminology',
    hint('LTV = Lifetime Value'),
    hint('MRR = Monthly Recurring Revenue'),
  ),
  fragment(
    'rules',
    hint('Never expose PII'),
    hint('Limit query results to 1000 rows'),
  ),
);

Rendered as XML:

<domain_knowledge>
  <terminology>
    <hint>LTV = Lifetime Value</hint>
    <hint>MRR = Monthly Recurring Revenue</hint>
  </terminology>
  <rules>
    <hint>Never expose PII</hint>
    <hint>Limit query results to 1000 rows</hint>
  </rules>
</domain_knowledge>

Type Guards

The package exports type guards for runtime checking:

import {
  isFragment,
  isFragmentObject,
  isMessageFragment,
} from '@deepagents/context';

isFragment(role('Be concise.')); // true
isFragment({ name: 'user', codec: { encode() {}, decode() {} } }); // true
isFragment('just a string'); // false

isMessageFragment(user('Hello')); // true
isMessageFragment(hint('Be helpful')); // false

isFragmentObject({ key: 'value' }); // true
isFragmentObject([1, 2, 3]); // false

Best Practices

  1. Use helper builders instead of constructing raw fragments manually.
  2. Group related context with fragment(...) when you want stronger structure.
  3. Use message helpers for conversation turns and regular helpers for system context.
  4. Use fromFragment(...) and toFragment(...) when you need to store non-message fragments outside the engine.

Next Steps