Chains
Build complex multi-step AI workflows with conditional logic, data transformation, and parallel execution.
What is a Chain?
A Chain is a powerful workflow engine that orchestrates multiple steps in sequence or parallel. Each step can be a prompt execution, API call, conditional branch, or data transformation.
Chains enable you to:
- Compose Workflows - Combine multiple prompts and operations
- Pass Data - Output from one step becomes input for the next
- Conditional Logic - Branch execution based on step results
- Transform Data - Manipulate data between steps
- Handle Errors - Graceful error handling and fallbacks
- Track Execution - Monitor performance and costs per step
Chain Structure
Basic Components
Chain Metadata
Name, description, active status, and intent tags for routing
Required Inputs
JSON Schema defining what data the chain needs to execute
Chain Steps
Ordered list of operations to perform (prompts, API calls, conditions, etc.)
Intent Tags
Keywords for intelligent routing (e.g., "portfolio", "tax", "risk analysis")
Step Types
| Parameter | Type | Description |
|---|---|---|
PROMPT | StepType | Execute an AI prompt with dynamic inputs |
API_CALL | StepType | Call an external API endpoint |
CONDITION | StepType | Branch execution based on a condition |
TRANSFORM | StepType | Transform or manipulate data |
Creating Chains
Via Web Interface
Navigate to Chains
Click "New Chain" from the Chains page
Configure Metadata
Set name, description, and mark as active
Define Required Inputs
Specify what data the chain needs (JSON Schema format)
Add Steps
Click "Add Step" to add prompts, API calls, or conditional logic
Configure Data Mapping
Map outputs from previous steps to inputs of new steps
Add Intent Tags
Add keywords for intelligent routing (optional)
Test Execution
Use the built-in tester with sample inputs
Via GraphQL API
mutation CreateChain {
createChain(input: {
name: "customer-support-analyzer"
description: "Analyzes customer support messages and generates appropriate responses"
isActive: true
requiredInputs: {
type: "object"
properties: {
message: {
type: "string"
description: "Customer support message"
}
}
required: ["message"]
}
intentTags: ["support", "customer-service", "help"]
}) {
id
name
}
}Chain Steps
Step Configuration
Each step in a chain has the following properties:
| Parameter | Type | Description |
|---|---|---|
orderrequired | number | Execution order (0-indexed) |
typerequired | StepType | PROMPT, API_CALL, CONDITION, or TRANSFORM |
config | JSON | Step-specific configuration (model params, API endpoint, etc.) |
inputMapping | JSON | How to map previous outputs to this step's inputs |
outputKey | string | Key to store this step's output for later steps |
Prompt Steps
Execute a prompt as part of the chain workflow:
{
"order": 0,
"type": "PROMPT",
"promptId": "cm1234567890",
"inputMapping": {
"text": "{{message}}"
},
"outputKey": "sentiment_analysis",
"config": {}
}inputMapping uses {{key}} syntax to reference the chain's input or previous step outputs.API Call Steps
Call external APIs as part of your workflow:
{
"order": 1,
"type": "API_CALL",
"config": {
"url": "https://api.example.com/tickets",
"method": "POST",
"headers": {
"Authorization": "Bearer {{apiKey}}"
},
"body": {
"message": "{{message}}",
"sentiment": "{{sentiment_analysis.sentiment}}"
}
},
"outputKey": "ticket_response"
}Conditional Steps
Branch execution based on previous step results:
{
"order": 2,
"type": "CONDITION",
"config": {
"condition": "{{sentiment_analysis.sentiment}} == 'Negative'",
"trueTag": "escalate",
"falseTag": "standard"
}
}Steps with matching tags will only execute when that condition path is taken.
Data Flow
Input Mapping
Data flows through a chain using a context object that accumulates results:
// Initial chain input
{
"message": "I'm very unhappy with my order"
}
// After step 0 (sentiment analysis)
{
"message": "I'm very unhappy with my order",
"sentiment_analysis": {
"sentiment": "Negative",
"confidence": 0.92
}
}
// After step 1 (generate response)
{
"message": "I'm very unhappy with my order",
"sentiment_analysis": { ... },
"generated_response": "I sincerely apologize for the inconvenience..."
}Accessing Data
Use dot notation to access nested data:
{
"inputMapping": {
"customer_message": "{{message}}",
"sentiment": "{{sentiment_analysis.sentiment}}",
"confidence": "{{sentiment_analysis.confidence}}"
}
}Executing Chains
mutation ExecuteChain {
executeChain(
chainId: "cm9876543210"
input: {
message: "I need help with my recent order"
}
) {
output
steps {
order
type
output
latency
cost
}
totalLatency
totalCost
}
}Response Structure
{
"data": {
"executeChain": {
"output": "I'd be happy to help you with your order. Could you please provide your order number?",
"steps": [
{
"order": 0,
"type": "PROMPT",
"output": "{\"sentiment\": \"Neutral\", \"confidence\": 0.75}",
"latency": 1200,
"cost": 0.0015
},
{
"order": 1,
"type": "PROMPT",
"output": "I'd be happy to help you with your order...",
"latency": 1450,
"cost": 0.0018
}
],
"totalLatency": 2650,
"totalCost": 0.0033
}
}
}Intent Routing
Intent tags enable automatic routing of user messages to the appropriate chain:
{
"name": "portfolio-analysis",
"intentTags": ["portfolio", "investment", "stocks", "holdings"]
}
{
"name": "tax-calculator",
"intentTags": ["tax", "capital gains", "deductions"]
}
{
"name": "risk-assessment",
"intentTags": ["risk", "volatility", "exposure"]
}When a user message contains these keywords, Prompt Forge can automatically route to the matching chain.
Learn more about Intent Routing →