Stop Wrestling AI Prompts! Build Agents Visually with Rivet
What if I told you that the most painful part of building AI applications isn't the models—it's the chaos of prompt engineering? You've been there: staring at a 500-line Python script, debugging why your GPT-4 agent suddenly hallucinated, tracing through a maze of if-else statements that chain prompts together like fragile dominoes. One wrong temperature setting, one misplaced context window, and your entire AI pipeline crumbles.
Here's the dirty secret that OpenAI won't tell you: prompt chaining is the new spaghetti code. Developers are duct-taping LLM calls together with string concatenation, praying that context limits hold, and manually managing state like it's 1995. The result? Unmaintainable AI applications that even their creators fear to touch.
But what if you could see your entire AI agent's brain? What if complex prompt chains, conditional logic, and multi-model orchestration became as intuitive as dragging nodes on a canvas? Enter Rivet—the open-source visual AI programming environment that's making traditional prompt engineering look like carving stone tablets. Built by the team at Ironclad and battle-tested in production, Rivet is the secret weapon that top AI developers are using to build sophisticated agents in hours, not weeks.
Ready to stop debugging prompts and start designing intelligence? Let's dive in.
What is Rivet?
Rivet is an open-source visual IDE and TypeScript library for creating complex AI agents, prompt chaining workflows, and embedding them directly into your applications. Born from the engineering team at Ironclad—a company that knows a thing or two about complex document automation—Rivet represents a fundamental shift in how developers approach AI application architecture.
At its core, Rivet solves a deceptively simple problem: LLM-based applications are inherently graph-shaped, but we're forced to write them as linear code. When you call GPT-4, branch based on its output, query a vector database, feed those results to Claude, then conditionally call another API—you're not writing a script. You're building a graph. Rivet makes that graph visible, editable, and executable.
The project has exploded in popularity because it arrives at a critical inflection point. As of 2024, developers are hitting the wall with simple "chat with your PDF" demos. The next generation of AI applications demands multi-step reasoning, tool use, memory management, and fault tolerance—complexity that collapses under imperative code but thrives in Rivet's visual paradigm.
Rivet consists of two powerful components working in harmony:
- Rivet Application: A desktop IDE where you design, test, and iterate on AI agent graphs visually
- Rivet Core: A TypeScript library (
@ironclad/rivet-core) that executes these graphs in production, with a Node.js runtime (@ironclad/rivet-node) for server-side deployment
This dual architecture means you never face the dreaded "works in prototype, rewrite for production" cliff. Your visual designs are your production code.
Key Features That Separate Rivet from the Pack
Rivet isn't just another low-code toy. It's a professional-grade AI engineering platform with technical depth that serious developers demand.
Multi-Model Orchestration Without the Headaches
Rivet speaks fluent LLM across the entire modern landscape. Native support includes OpenAI's GPT-3.5 and GPT-4, Anthropic's Claude family (Instant, Claude 2, and the latest Claude 3 Haiku/Sonnet/Opus models), plus AssemblyAI's LeMUR framework for voice data processing. This isn't just API wrapping—Rivet handles model-specific quirks, token counting, and context window management so you don't have to.
Visual Graph Execution Engine
The heart of Rivet is its node-based execution graph. Each node represents an operation—LLM calls, data transformations, conditional branching, loops, API requests. Edges define data flow. The visual paradigm makes complex state machines immediately comprehensible. Debug by watching data flow through your graph in real-time, not by sprinkling console.log through nested async functions.
Production-Ready TypeScript Runtime
Here's where Rivet exposes its engineering pedigree. Graphs designed in the IDE serialize to a format that Rivet Core executes deterministically. The @ironclad/rivet-core package provides the full execution engine, while @ironclad/rivet-node offers Node.js-specific integrations. Your application calls into Rivet graphs; Rivet graphs call back into your application code. Bidirectional integration is first-class, not an afterthought.
Vector Database & Embedding Integration
Modern RAG (Retrieval-Augmented Generation) applications need more than LLM calls. Rivet integrates OpenAI Embeddings and Pinecone vector database operations directly into the visual graph. Chunk documents, generate embeddings, query similarity, and inject retrieved context into prompts—all without leaving the canvas.
Speech-to-Text Pipeline Support
Through the AssemblyAI integration, Rivet handles voice-to-intelligence pipelines. Transcribe audio, process with LeMUR for understanding, then route through your standard graph logic. This opens entirely new application categories that most AI frameworks ignore.
Four Battle-Tested Use Cases Where Rivet Dominates
1. Intelligent Document Processing Pipelines
Legal tech, insurance claims, healthcare records—these domains need multi-stage document intelligence. A Rivet graph might: extract text with OCR, chunk and embed into Pinecone, retrieve relevant sections based on a query, summarize with Claude 3 Opus, then conditionally escalate to human review if confidence scores dip. The visual graph makes this 12-step pipeline maintainable by teams, not just the solo developer who wrote it.
2. Conversational AI Agents with Tool Use
Build agents that don't just chat—they act. A customer support agent in Rivet can: classify intent with a small fast model (Haiku), route to specialized subgraphs, query your CRM via API nodes, calculate return eligibility with code nodes, then generate personalized responses with GPT-4. When business logic changes, update the graph visually instead of refactoring nested switch statements.
3. Multi-Modal Content Generation Workflows
Modern content pipelines combine text, image generation, and voice. Rivet orchestrates these heterogenous operations: generate a script with Claude, convert to speech with your TTS provider, generate thumbnail prompts for DALL-E, parallelize API calls, then assemble final assets. The graph structure naturally expresses parallel execution paths that would tangle in imperative code.
4. Research & Analysis Agents with Memory
Financial analysis, market research, academic literature review—these require persistent memory and iterative refinement. Rivet graphs maintain state across executions, store intermediate findings in vector databases, and implement feedback loops where the agent critiques its own output and revises. The visual debugger lets you watch reasoning chains form in real-time.
Step-by-Step Installation & Setup Guide
Getting Rivet running takes minutes, not hours. The project provides prebuilt binaries for all major platforms plus full source build instructions.
Download Prebuilt Binaries
The fastest path to productivity:
# macOS users - download the DMG directly
curl -L -o Rivet.dmg https://github.com/Ironclad/rivet/releases/latest/download/Rivet.dmg
# Linux users - AppImage for portable execution
curl -L -o Rivet.AppImage https://github.com/Ironclad/rivet/releases/latest/download/Rivet.AppImage
chmod +x Rivet.AppImage
./Rivet.AppImage
# Windows users - standard installer
curl -L -o Rivet-Setup.exe https://github.com/Ironclad/rivet/releases/latest/download/Rivet-Setup.exe
# Run the executable to install
For all releases including beta channels, visit the releases page.
Install Rivet Core for Application Integration
When you're ready to embed Rivet graphs in your application:
# Core execution engine - works in any JavaScript environment
npm install @ironclad/rivet-core
# Node.js-specific runtime with file system and network integrations
npm install @ironclad/rivet-node
Running from Source (Contributors & Customizers)
For those who want to hack on Rivet itself or need bleeding-edge features:
# Clone the repository
git clone https://github.com/Ironclad/rivet.git
cd rivet
# Follow the detailed build instructions in CONTRIBUTING.md
cat CONTRIBUTING.md
The build process is documented for contributors, with setup instructions for the development environment. The project welcomes all contribution types—code, documentation, bug reports, UX feedback, and feature suggestions.
Initial Configuration
After launching Rivet:
- Add your API keys in the settings panel—OpenAI, Anthropic, AssemblyAI, and Pinecone credentials are configured independently
- Create your first project and select a template or start from blank canvas
- Test connectivity with the built-in model health checks before building complex graphs
REAL Code Examples: From Visual Design to Production Execution
Rivet's power shines when you bridge the visual IDE with programmatic control. Here are practical patterns using the actual Rivet Core API.
Example 1: Loading and Executing a Saved Graph
This pattern shows how to take a graph designed in the Rivet IDE and execute it within your application:
import { loadProjectFromFile, createProcessor } from '@ironclad/rivet-core';
import * as RivetNode from '@ironclad/rivet-node';
// Load a project file exported from the Rivet IDE
const project = await loadProjectFromFile('./my-agent.rivet-project');
// Extract a specific graph by its ID from the project
const graph = project.graphs['my-intelligent-agent'];
// Create an execution processor with Node.js integrations
const processor = createProcessor(project, {
graph,
// RivetNode provides native Node.js capabilities
...RivetNode.getNodeSpec(),
// Inject your application's custom functions into the graph
context: {
// Custom functions callable from graph nodes
getUserData: async (userId: string) => {
return await myDatabase.users.findById(userId);
},
sendNotification: async (message: string, channel: string) => {
await myNotificationService.send(channel, message);
}
}
});
// Execute the graph with initial inputs
const outputs = await processor.process({
inputs: {
userQuery: "What's the status of my recent order?",
userId: "user_12345"
}
});
// Handle the structured outputs
console.log(outputs.response); // LLM-generated response
console.log(outputs.confidence); // Routing confidence score
console.log(outputs.requiresEscalation); // Boolean decision node output
This example demonstrates bidirectional integration: your application loads the graph, provides runtime dependencies, feeds inputs, and receives structured outputs. The graph designed visually becomes a pure function in your architecture.
Example 2: Streaming Execution for Real-Time Responses
For conversational interfaces, you need streaming, not batch execution:
import { loadProjectFromFile, createProcessor } from '@ironclad/rivet-core';
import * as RivetNode from '@ironclad/rivet-node';
async function* streamAgentResponse(userMessage: string) {
const project = await loadProjectFromFile('./chat-agent.rivet-project');
const graph = project.graphs['streaming-chat-handler'];
const processor = createProcessor(project, {
graph,
...RivetNode.getNodeSpec(),
});
// Stream events as the graph executes
for await (const event of processor.processGenerator({
inputs: { message: userMessage }
})) {
// Yield partial outputs for real-time display
if (event.type === 'partialOutput' && event.node.type === 'chat') {
yield {
type: 'token',
content: event.outputs.response.value
};
}
// Yield tool use events for UI rendering
if (event.type === 'nodeStart' && event.node.type === 'call-api') {
yield {
type: 'tool_call',
tool: event.node.data.endpoint
};
}
}
}
// Express.js SSE endpoint example
app.post('/chat', async (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
for await (const chunk of streamAgentResponse(req.body.message)) {
res.write(`data: ${JSON.stringify(chunk)}\n\n`);
}
res.end();
});
The processGenerator API exposes fine-grained execution events, letting you build responsive UIs that show thinking steps, tool invocations, and streaming tokens.
Example 3: Dynamic Graph Assembly for Runtime Flexibility
Sometimes you need to construct or modify graphs programmatically:
import {
GraphBuilder,
createProcessor,
ChatNode,
IfNode,
ArrayNode
} from '@ironclad/rivet-core';
// Build a graph dynamically based on runtime configuration
function buildAdaptiveAgent(availableTools: string[]) {
const builder = new GraphBuilder();
// Input node receives user query
const inputNode = builder.addNode('input', {
id: 'user-input',
data: { message: '' }
});
// Router LLM decides which tool to use
const routerNode = builder.addNode('chat', {
id: 'tool-router',
data: {
prompt: `Given user query, select tool: ${availableTools.join(', ')}`,
model: 'claude-3-haiku-20240307' // Fast, cheap routing
}
});
// Create conditional branches for each available tool
const toolResults: string[] = [];
for (const tool of availableTools) {
const conditionNode = builder.addNode('if', {
id: `check-${tool}`,
data: { condition: `{{router.output}} === '${tool}'` }
});
const toolNode = builder.addNode('custom', {
id: `execute-${tool}`,
data: {
// References your registered custom functions
functionName: tool
}
});
// Wire the conditional flow
builder.addEdge(routerNode, conditionNode);
builder.addEdge(conditionNode, toolNode, 'true');
toolResults.push(toolNode.id);
}
// Merge results through a synthesis LLM call
const synthesizerNode = builder.addNode('chat', {
id: 'response-synthesizer',
data: {
model: 'claude-3-opus-20240229', // Best quality for final output
prompt: 'Synthesize tool results into coherent response'
}
});
// Connect all tool outputs to synthesizer
for (const resultId of toolResults) {
builder.addEdge(builder.getNode(resultId), synthesizerNode);
}
return builder.build();
}
// Execute the dynamically constructed graph
const adaptiveGraph = buildAdaptiveAgent(['search-kb', 'query-database', 'calculate-metrics']);
const processor = createProcessor(adaptiveGraph);
const result = await processor.process({ inputs: { query: 'Q3 revenue trends' } });
This pattern enables meta-programming with AI graphs—systems that reconfigure their own reasoning structures based on context, user permissions, or available capabilities.
Advanced Usage & Best Practices
Version Control Your Graphs
Rivet project files are JSON-based—commit them to git, diff changes in PRs, and review agent logic with the same rigor as code. Tag stable graph versions and load them by version in production for reproducible deployments.
Implement Graceful Degradation
Design fallback chains in your graphs: try GPT-4, fall back to GPT-3.5-turbo on rate limits, escalate to Claude if both fail. Rivet's conditional nodes make this visually explicit and maintainable.
Monitor Token Economics
Use the fastest sufficient model at each decision point. Route simple classification to Haiku, complex reasoning to Opus, with cost-tracking nodes that log spend per execution path. The visual debugger shows token usage per node—optimize where it matters.
Cache Embedding Operations
Vector database queries and embedding generations are expensive. Add cache nodes after embedding operations, keyed by content hash. Rivet's graph structure makes cache invalidation strategies obvious.
Secure Your Context Windows
Implement PII detection nodes before any external API call. Use Rivet's data transformation nodes to redact, hash, or tokenize sensitive information. The visual flow ensures no data leaks through overlooked code paths.
Rivet vs. The Competition: Why Make the Switch?
| Feature | Rivet | LangChain | LlamaIndex | Custom Code |
|---|---|---|---|---|
| Visual Design | ✅ Native node editor | ❌ Code only | ❌ Code only | ❌ N/A |
| Production Runtime | ✅ Same graph, no rewrite | ⚠️ Separate optimization needed | ⚠️ Separate optimization needed | ❌ Complete rewrite typical |
| Multi-Model Support | ✅ OpenAI, Anthropic, AssemblyAI | ✅ Extensive | ⚠️ Primarily OpenAI | ❌ Manual integration |
| TypeScript-First | ✅ Core library | ⚠️ Python primary | ⚠️ Python primary | ⚠️ Your responsibility |
| Debugging Visibility | ✅ Real-time graph execution | ❌ Log tracing | ❌ Log tracing | ❌ Custom instrumentation |
| Embedding/RAG Integration | ✅ Built-in Pinecone, OpenAI | ⚠️ Requires setup | ✅ Native strength | ❌ Build from scratch |
| Voice Pipeline Support | ✅ AssemblyAI LeMUR | ❌ Not native | ❌ Not native | ❌ Manual integration |
| Open Source | ✅ Apache 2.0 | ✅ MIT | ✅ MIT | N/A |
The verdict: LangChain and LlamaIndex excel as Python libraries for research and prototyping. Rivet dominates where visual design, team collaboration, and production deployment converge. If your AI application will evolve beyond a Jupyter notebook, Rivet's architecture pays dividends.
Frequently Asked Questions
Q: Is Rivet only for non-coders? A: Absolutely not. Rivet is engineered for developers who are tired of debugging prompt spaghetti. The visual layer accelerates design; the TypeScript runtime provides full programmatic control. You'll write less boilerplate, more business logic.
Q: Can I use my own fine-tuned models? A: Yes. Rivet's architecture supports custom model endpoints through its extensible node system. Integrate any OpenAI-compatible API or build custom nodes for proprietary model deployments.
Q: How does Rivet handle errors in long chains? A: Each node has configurable retry logic, timeout handling, and fallback paths. The graph structure makes error propagation visible—you design recovery flows, not catch blocks scattered through callbacks.
Q: Is my data sent to Ironclad's servers? A: No. Rivet runs entirely on your infrastructure. API calls go directly from your machine to OpenAI, Anthropic, or your chosen providers. The open-source nature means you can audit every network request.
Q: What's the performance overhead of visual execution? A: Negligible for most applications. Rivet Core compiles graphs to an efficient execution plan. The visual design-time overhead doesn't translate to runtime cost—benchmarks show comparable performance to hand-rolled orchestration.
Q: Can multiple developers collaborate on the same agent? A: Yes. Rivet project files merge cleanly in git. The visual format makes code reviews intuitive—reviewers see the logic flow, not just diff lines. Teams report faster onboarding for new developers.
Q: What's the migration path from existing LangChain apps?
A: Gradual. Use Rivet for new agent components while keeping existing LangChain code. The @ironclad/rivet-node package integrates with Express, Next.js, or any Node.js framework alongside your current stack.
Conclusion: The Future of AI Development is Visual
We've reached an inflection point in AI engineering. The demo era—single prompts wrapped in React components—is ending. The production era demands orchestrated intelligence: multi-model systems with memory, tools, and fault tolerance. Writing these systems as imperative code is fighting the problem's natural geometry.
Rivet embraces the graph nature of AI applications. It gives you visual clarity without sacrificing engineering rigor, rapid iteration without production rewrite, and team collaboration without knowledge silos. The open-source community around Rivet is growing precisely because it solves real problems that developers face daily.
My take? In two years, visual AI programming won't be novel—it'll be expected. Rivet is establishing the patterns that will define this category. The teams adopting it now are building institutional knowledge that compounds.
Your move. Stop wrestling with prompt strings. Start designing intelligence.
👉 Star Rivet on GitHub and download the IDE today. Join the Discord community if you need help—the core team and contributors are actively supporting newcomers. Your first production AI agent is closer than you think.