Content Action Steps
For common fields, string substitutions, metadata filters, caching, and execution order, see the Agent Steps Overview.
Retrieval Step
Searches a knowledge base using semantic similarity (vector search) to find the most relevant content for a given query. This is the foundation of RAG (Retrieval-Augmented Generation) workflows.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
knowledge_base_id | UUID | Yes | — | The knowledge base to search |
query | string | No | null | The search query. Supports substitutions. If not set, the step's input is used as the query. |
top_n | integer | No | 20 | Number of results to return (1–100) |
reranker_model | enum | No | null | Reranker model to apply after initial retrieval (see below) |
top_k | integer | No | null | Number of results to keep after reranking (1–100). Only used with a reranker model. |
content_type | enum | No | application/json | Output format: application/json or text/plain |
filter | object | No | null | Metadata filter to narrow results (MongoDB-style query, see Metadata Filters) |
added_after | string | No | null | Only return content added after this date/time. Supports substitutions. |
added_before | string | No | null | Only return content added before this date/time. Supports substitutions. |
extended_caching_days | integer | No | null | Number of days to cache results (must be > 0) |
cache_all_minutes | integer | No | null | Cache all identical requests for N minutes (1–60) |
include_attachments | boolean | No | true | When enabled, indexed content attachments are included in retrieval results alongside the main content body. Disable to limit results to original content only. |
Reranker Models
Rerankers improve result quality by re-scoring the initial retrieval results using a cross-encoder model. The retrieval first fetches top_n results, then the reranker re-scores them and returns the top top_k.
| Model | Description |
|---|---|
| Amazon Rerank v1 | AWS Bedrock-hosted reranker |
| Cohere Reranker v3.5 | High-quality reranker from Cohere |
Output Format
When content_type is application/json (default), the output is a JSON object with a matches array of matching documents. Each object in matches contains:
| Field | Type | Description |
|---|---|---|
content_title | string | Title of the matched content |
source_type | string | Source type (e.g. rss_feed, website, custom_index) |
source | string | Name of the source connection |
content_url | string | Absolute URL to the content viewer in the Seclai app |
external_url | string (optional) | Original source URL for website and RSS feed content. Omitted for content stores and other source types where not present. |
content | string | The matched text chunk |
chunk_start | integer | Character offset where the chunk starts in the full content |
chunk_end | integer | Character offset where the chunk ends in the full content |
content_publish_date | string | null | Original publish date of the content, if available |
Example JSON output:
{
"matches": [
{
"content_title": "Getting Started Guide",
"source_type": "website",
"source": "Documentation Site",
"content_url": "https://app.seclai.com/app/abc123/contents/def456?start=0&end=1200",
"external_url": "https://docs.example.com/getting-started",
"content": "Welcome to the getting started guide...",
"chunk_start": 0,
"chunk_end": 1200,
"content_publish_date": "2026-01-15T10:30:00Z"
}
]
}
external_url is only present for website and rss_feed source types. For custom_index and other source types, the field is omitted.
When content_type is text/plain, the output is the concatenated text of matching documents, suitable for direct use in prompts.
Use Case Examples
Basic semantic search:
- Knowledge base: Product documentation
- Query:
{{agent.input}} - Top N: 10
- Content type:
text/plain
The step searches for content semantically similar to the user's input and returns the top 10 matches as plain text.
Filtered retrieval with reranking:
- Knowledge base: News articles
- Query:
{{agent.input}} - Filter:
{"category": {"$eq": "{{metadata.category}}"}} - Top N: 50
- Reranker: Cohere v3.5
- Top K: 10
- Added after:
{{metadata.start_date}}
First retrieves 50 candidates matching the category filter added after the start date, then reranks them to select the 10 most relevant.
Time-bounded retrieval:
- Knowledge base: RSS feed content
- Query:
Latest news about AI - Added after:
2026-02-10 - Added before:
2026-02-17 - Top N: 20
Retrieves only content added within the specified date range.
AI Assistant
The retrieval step includes an AI assistant that can generate a complete configuration from a natural-language description. Click the AI Assistant button to open the assistant modal.
The assistant can set all retrieval fields:
- Knowledge base — selects the most appropriate knowledge base when none is chosen, or suggests switching when another KB better matches the request
- Query — writes query templates using substitution variables like
{{input}}and{{step.<id>.output}} - Top N / Top K — sets retrieval and reranking counts based on use case
- Reranker model — recommends a reranker when high relevance or multilingual content is needed
- Time range — sets
added_after/added_beforefilters using date templates - Metadata filter — builds MongoDB-style filter objects using known metadata fields from the knowledge base
- Content type — selects the output format (JSON, plain text, HTML, XML)
The assistant is aware of the available knowledge bases (their names, descriptions, source counts, and detected metadata fields), the available reranker models, and the full agent workflow context. When no knowledge base is selected, the assistant will recommend one based on your request.
Write Metadata Step
Writes a value to the content's metadata by key. This enables agents to persist structured information — such as AI-generated classifications, tags, or scores — directly on the content record so that it can be used for retrieval filtering and gate conditions in future agent runs. For larger information like summaries, consider using Write Content Attachment and Read Content Attachment steps instead.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
metadata_key | string | Yes | — | The key under which the value will be stored in the content metadata. Supports substitutions. |
content | string | No | null | The value to write. If omitted, the step's input is used (equivalent to {{input}}). Supports substitutions. |
Behavior
- If the value is valid JSON, it is stored as a parsed JSON value (object, array, number, boolean, or null). Otherwise it is stored as a plain string.
- The total serialized metadata payload must not exceed 10 KB. Performance may degrade with payloads above 2 KB.
- Metadata written by this step is merged with content version metadata when content is retrieved. The content metadata takes precedence over content version metadata for duplicate keys.
- The step requires a
source_connection_content_version_idin the run metadata — this is automatically provided when the agent is triggered by a content event (content_added,content_updated, orcontent_added_or_updated).
Use Case Examples
Persist an AI-generated category for retrieval filtering:
Step 1: Insight — Classify the content into a category
Step 2: Write Metadata (metadata_key: "category")
A subsequent retrieval step can filter by {"category": {"$eq": "technology"}} to narrow results.
Store a sentiment score for gate conditions:
Step 1: Prompt Call — "Rate the sentiment of this content as positive, negative, or neutral"
Step 2: Write Metadata (metadata_key: "sentiment")
A gate step in a later agent can use metadata.sentiment with $eq to route content conditionally.
Write a JSON summary object:
Step 1: Insight — Extract key topics and summary as JSON
Step 2: Write Metadata (metadata_key: "analysis", content: "{{step.extract-insight.output}}")
The JSON object is stored as structured metadata, and individual fields can be accessed in filters.
Write Content Attachment Step
Writes an attachment to content. The step input (or explicit content) is stored as a file-backed attachment under a specified key. This is ideal for persisting large outputs — such as full translations, analysis reports, or transformed content — that are too large for metadata but should be associated with the content record.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
attachment_key | string | Yes | — | A short identifier for the attachment (e.g. summary, translation). Must be unique per content version. Supports substitutions. |
content_type | enum | No | text/plain | The MIME type of the attachment: text/plain, text/html, application/json, or application/xml. |
content | string | No | null | The content to write. If omitted, the step's input is used (equivalent to {{input}}). Supports substitutions. |
indexed | boolean | No | false | When enabled, the attachment text is indexed so that it appears in retrieval search results alongside the main content body. |
Behavior
- Attachments are stored in file storage and linked to the content version.
- Unlike metadata (which has a 10 KB limit), attachments can store large content.
- When
indexedis enabled, the attachment's text is chunked and embedded into the knowledge base's vector store, making it searchable via retrieval steps. The retrieval step'sinclude_attachmentsfield controls whether indexed attachments appear in results. - The step requires a
source_connection_content_version_idin the run metadata.
Use Case Examples
Store a full translation alongside original content:
Step 1: Prompt Call — Translate the content to Spanish
Step 2: Write Content Attachment (attachment_key: "translation_es", content_type: text/plain)
Persist an indexed analysis that's searchable:
Step 1: Insight — Generate a detailed analysis report
Step 2: Write Content Attachment (attachment_key: "analysis", indexed: true)
The analysis is now searchable via retrieval, appearing alongside the original content in results.
Store structured data as a JSON attachment:
Step 1: Insight — Extract entities and relationships as JSON
Step 2: Write Content Attachment (attachment_key: "entities", content_type: application/json)
Load Content Step
Loads the full text body of a source document (content version) and returns it as the step output. For content-triggered agents, the triggering content is used automatically unless an explicit content version is selected.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
content_version_id | string | No | — | The ID of the content version to load. If omitted, the triggering content version is used automatically. |
Behavior
- Returns the full text body of the content version as the step output.
- For content-triggered agents, the triggering content version is used when
content_version_idis not specified. - When an explicit
content_version_idis provided, that content version is loaded regardless of trigger context. - The step requires a
source_connection_content_version_idin the run metadata (provided automatically for content-triggered agents).
Use Case Examples
Load and summarize article content:
Step 1: Load Content
Step 2: Prompt Call — Summarize the following article: {{input}}
Load content for multi-step analysis:
Step 1: Load Content
Step 2: Insight — Analyze the content for key themes and sentiment
Step 3: Extract JSON — Parse the structured analysis
Load Content Attachment Step
Loads a previously written attachment from content by key and returns its text content as the step output. Use this to recall persisted content — such as a previous analysis, translation, or extracted data — for use in subsequent processing steps.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
attachment_key | string | Yes | — | The key of the attachment to load. Supports substitutions. |
Behavior
- Returns the text content of the attachment as the step output.
- If the attachment does not exist for the given key, the step output is empty.
- The step requires a
source_connection_content_version_idin the run metadata.
Use Case Examples
Load a previous translation for comparison:
Step 1: Load Content Attachment (attachment_key: "translation_es")
Step 2: Prompt Call — Compare this translation with the original content
Build on a previous analysis:
Step 1: Load Content Attachment (attachment_key: "analysis")
Step 2: Insight — Using the previous analysis, identify any changes
Load Content Step vs Load Content Attachment vs Prompt-Call Tools
These three approaches all load document content, but serve different purposes:
| Approach | What it loads | When to use it |
|---|---|---|
| Load Content step | The full text body of a source document | You need the entire document as a deterministic pipeline step — e.g. to feed it into a Prompt Call or Insight step for summarization or analysis. |
| Load Content Attachment step | A previously written attachment (by key) | You need to recall data that was persisted by a prior agent run — e.g. a cached translation, extracted entities, or a previous analysis. |
load_content prompt-call tool | The full text of a source document, invoked by the AI model | You want the model to decide at runtime whether and which document to load. The model autonomously calls this tool during a Prompt Call step when it determines it needs document content. |
The key distinction: the Load Content step runs unconditionally as part of the pipeline, while the load_content prompt-call tool is invoked by the AI model on demand during a Prompt Call step. If you always need the document, use the step. If the model should decide whether to fetch it, enable the tool.
Combining Metadata and Attachments
Metadata and attachments serve complementary purposes:
| Feature | Metadata (Write Metadata) | Attachments (Write/Load) |
|---|---|---|
| Size limit | 10 KB total | No practical limit |
| Filterable | Yes (retrieval filters, gates) | No (but can be indexed for search) |
| Searchable | No | Yes (when indexed: true) |
| Best for | Tags, scores, categories | Full text, reports, translations |
| Access method | {{metadata.<key>}} | Load Content Attachment step |
Example: Insight-driven content enrichment pipeline:
Step 1: Insight — Classify content and extract summary
Step 2: Extract JSON — Parse the JSON output
Step 3: Write Metadata (metadata_key: "category", content: "{{step.extract-json.output.category}}")
Step 4: Write Metadata (metadata_key: "sentiment", content: "{{step.extract-json.output.sentiment}}")
Step 5: Write Content Attachment (attachment_key: "detailed_summary", indexed: true)
This pipeline: classifies content (filterable via metadata), records sentiment (usable in gate conditions), and persists a searchable detailed summary (retrievable via attachment indexing).
Publish Content Step
Publishes content to a Content Store source connection. The content goes through the standard indexing pipeline and becomes searchable via retrieval. Use this to let agents create or update knowledge base content — for example, storing generated summaries, reports, or transformed data.
Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
source_connection_id | string | No | null | The ID of the target content store source. RSS feeds, websites, and other source types are not supported. For content-triggered agents, leave blank to publish back to the triggering content's source. Supports substitutions. |
content_identifier_mode | enum | No | auto | auto — creates new content each run. custom — uses a custom identifier so the same item is updated on subsequent runs. |
content_identifier | string | No | null | A custom content identifier (only used when mode is custom). Content with the same identifier is treated as the same item. Supports substitutions. |
if_exists | enum | No | new_version | What to do when content with the same identifier already exists: new_version (update) or skip (leave unchanged). |
content_type | enum | No | text/plain | The MIME type of the content: text/plain, text/html, application/json, or application/xml. |
title | string | No | null | An optional title for the published content. Supports substitutions. |
content | string | No | null | The content to publish. If omitted, defaults to the step input. Supports substitutions. |
metadata | object | No | null | Optional key-value metadata to attach to the published content. String values that look like substitution placeholders are resolved. |
suppress_triggers | boolean | No | true | When enabled, the published content will not fire downstream content triggers. Enabled by default to prevent infinite loops. |
Behavior
- Only Content Store sources are supported as targets. Other source types (RSS feeds, websites) will be rejected.
- In
automode, every run creates a new content item with a unique identifier. - In
custommode, publishing with the same identifier updates the existing item (creating a new version) or skips it, depending on theif_existssetting. - The
suppress_triggersflag defaults totrueto prevent infinite loops when a content-triggered agent publishes back to a monitored source. Only disable this if you are certain the target is not monitored by content triggers. - Works with any agent type. For content-triggered agents, the source connection and content version can be inherited from the trigger context.
Use Case Examples
Generate and store article summaries:
Step 1: Load Content
Step 2: Prompt Call — Summarize the article
Step 3: Publish Content (source_connection_id: "<custom-index-id>", title: "Summary: {{metadata.title}}")
Overwrite a daily report:
Step 1: Retrieval — Search for today's data
Step 2: Prompt Call — Generate daily report
Step 3: Publish Content (content_identifier_mode: custom, content_identifier: "daily-report", if_exists: new_version)
Content-triggered enrichment (publish back to same source):
Step 1: Load Content
Step 2: Insight — Analyze and enrich the content
Step 3: Publish Content (suppress_triggers: true)
Related pages:
- Content Sources — Configure the sources that feed your knowledge bases
- Contents — Inspect, replace, and delete indexed content items via API
- Knowledge Bases — Organize sources into searchable collections