Using records in flows

Integrate records into flows to provide context, personalize responses, and implement RAG (Retrieval Augmented Generation) patterns.

Common patterns

RAG: Question answering with context

Retrieve relevant documents and include them in AI prompts:

  1. Vector Search: Find docs matching user question (semantic search)
  2. Run Code: Extract and format retrieved content
  3. Run Task: Generate answer using retrieved context

Example prompt:

Answer this question using only the provided context.
Question: {{question}}
Context:
{{searchResults[0].metadata.content}}
{{searchResults[1].metadata.content}}
If the context doesn't contain relevant information, say "I don't have enough information to answer that."
Answer:

Personalization with customer data

Retrieve customer profile and use it for personalized responses:

  1. Get Record: Get customer by ID, name, or type
  2. Run Task: Generate response referencing customer data

Example:

Customer message: {{message}}
Customer info:
- Name: {{customerData.metadata.name}}
- Tier: {{customerData.metadata.tier}}
- Order history: {{customerData.metadata.orderCount}} orders
Provide a personalized, helpful response appropriate for their tier level.

Caching API results

Save expensive API calls in records:

  1. Get Record: Check if a cached result exists
  2. Conditional Logic: If cache miss, call external API
  3. Upsert Record: Save API response for future use

The output of the final step is the cached or fresh result.

Conversation history

Store chat logs for context in future interactions:

  1. Get Record: Get conversation history by user ID
  2. Run Task: Generate response with conversation context
  3. Upsert Record: Update conversation history with new exchange

Record lookups

Fetch a single record by ID or by type and name with Get Record:

Step: Get Record
Record ID: {{customerId}}
Output variable: customerLookup

Use in conditionals to check if a record exists:

Conditional Logic: {{customerLookup}} != null
If true: Use existing customer data
Else: Create new customer record

Or fetch every match with List Records:

Step: List Records
Record type: customers
Record filter: { "type": "customers", "where": { ... } }
Output variable: customerMatches

List Records always returns an array, so check its length instead of comparing to null:

Conditional Logic: {{customerMatches.length}} > 0
If true: Use existing customer data
Else: Create new customer record

Multi-record retrieval

Use a List Records step or a Vector Search step to get multiple results:

  1. Vector Search: Find matching products by semantic similarity
  2. Run Code: Extract and format results
  3. Run Task: Process or summarize the matches

Updating records from flows

Flows can create or update records using the Upsert Record step. The step identifies records by type and name, and stores the contents of a source variable as metadata:

Step: Upsert Record
Record type: analytics
Record name: {{eventId}}
Source variable: analysisResult
Output variable: upsertedRecord

There is also an Update Record step for modifying specific metadata fields on an existing record without replacing the entire metadata object.

Use Vector Search for unstructured queries (“How do I…?”), Get Record for a single structured lookup (“Get customer with ID 12345”), and List Records for structured lookups that may return several matches (“Get all open tickets for this customer”).

Optimizing record usage

  • Limit search results: Only retrieve what you need
  • Cache retrieved data: Store in variables, don’t retrieve multiple times
  • Use specific types: Searching within a type is faster than all records
  • Filter before semantic search: Narrow scope for better performance

Error handling

Handle a missing record from Get Record gracefully:

Conditional Logic: {{recordLookup}} == null
If true: handle the missing record (for example, send a "Customer not found" reply)
Else: continue processing with the record data

List Records returns an empty array rather than null when nothing matches, so check .length instead:

Conditional Logic: {{recordMatches.length}} == 0
If true: handle the missing records
Else: continue processing with the matches

Best practices

  • Keep record metadata concise: Only store fields you’ll query or use in prompts
  • Use meaningful record types: Organize records logically
  • Test search relevance: Verify semantic search returns appropriate results
  • Monitor record count: Large record sets need indexed fields
  • Version control: Don’t delete old records; mark them inactive instead

Example: Full RAG flow

1. Vector Search
Record type: documentation
Query: {{userQuestion}}
Limit: 3
Output variable: searchResults
2. Run Code
// Format context from top 3 results
const context = searchResults
.map(r => r.metadata.content)
.join('\n\n');
return { context };
// Output variable: formatContext
3. Run Task
Answer the question using this context:
Context: {{formatContext.context}}
Question: {{userQuestion}}
Answer:
// Output variable: answerQuestion

The answer lives in the final step’s output variable (answerQuestion above), which is returned as the flow result.

Next steps