Skip to content

Using the Architect

The Workflow Architect generates valid, executable Graph definitions from natural language descriptions using an LLM. Instead of hand-writing nodes and edges, you describe what you want and the Architect produces the graph structure.

Generated graphs are never executed automatically — they’re returned for review before you run or publish them.

The generateWorkflow() function takes a prompt and returns a validated Graph:

import { generateWorkflow } from '@cycgraph/orchestrator';
const { graph, warnings } = await generateWorkflow({
prompt: 'Monitor Hacker News for AI news, summarize daily, post to Slack',
});
  1. Your prompt is sent to an LLM with a system prompt that understands the graph schema
  2. A generated graph JSON is returned via Output.object
  3. The output is validated with validateGraph() (checks referential integrity, reachability, etc.)
  4. If validation fails, the errors are fed back to the LLM for self-correction (up to 2 retries by default)
  5. The valid graph is returned for your review
Option Type Default Description
prompt string required Natural language description of the desired workflow.
currentGraph Graph Existing graph to modify (enables iterative refinement).
architectAgentId string 'architect-agent' Agent ID whose model config to use for generation.
maxRetries number 2 Max self-correction attempts on validation failure.
Field Type Description
graph Graph The generated, validated graph — ready to run or publish.
raw LLMGraph Raw LLM output before conversion (useful for debugging).
attempts number Number of generation attempts (1 = first try, 2+ = self-corrected).
warnings string[] Non-fatal warnings from graph validation.
is_modification boolean Whether this was a modification of an existing graph.

Pass an existing graph alongside a follow-up prompt to modify it. The Architect preserves unmodified nodes and edges while applying your structural changes:

const { graph: updatedGraph } = await generateWorkflow({
prompt: 'Add a Slack notification step after the summarizer',
currentGraph: existingGraph,
});

This is useful for incrementally building up complex workflows through conversation, or for adjusting a generated graph without starting from scratch.

Once you have a graph, use it like any other — create state and run:

import { GraphRunner, createWorkflowState } from '@cycgraph/orchestrator';
const state = createWorkflowState({
workflowId: graph.id,
goal: 'Summarize today\'s top AI news from Hacker News',
});
const runner = new GraphRunner(graph, state);
const result = await runner.run();

Instead of calling generateWorkflow() directly, you can give the Architect’s built-in tools to an agent. This lets the agent design, modify, and publish workflows autonomously as part of a larger workflow or chat interaction.

The publish and get tools need to save/load graphs from your storage backend. Call initArchitectTools() once at application startup with saveGraph and loadGraph callbacks. Any persistence implementation works — in-memory for development, Drizzle/Postgres for production:

import { InMemoryPersistenceProvider, initArchitectTools } from '@cycgraph/orchestrator';
const persistence = new InMemoryPersistenceProvider();
initArchitectTools({
saveGraph: async (graph) => persistence.saveGraph(graph),
loadGraph: async (id) => persistence.loadGraph(id),
});

For production, swap in DrizzlePersistenceProvider from @cycgraph/orchestrator-postgres — the callback signatures are identical.

architect_publish_workflow always validates the graph (GraphSchema.parse + validateGraph) before it reaches saveGraph, so an agent cannot publish a malformed or unsafe graph. For agent-driven publishing you should also gate it: provide a canPublish callback that returns true to allow, or a string reason to deny (e.g. require human approval or check a privileged credential).

initArchitectTools({
saveGraph: async (graph) => persistence.saveGraph(graph),
loadGraph: async (id) => persistence.loadGraph(id),
canPublish: async (graph) =>
(await isApprovedByHuman(graph.id)) || 'human approval required',
});

Step 2: Register an agent with Architect tools

Section titled “Step 2: Register an agent with Architect tools”
import { InMemoryAgentRegistry } from '@cycgraph/orchestrator';
const registry = new InMemoryAgentRegistry();
const ARCHITECT_AGENT_ID = registry.register({
name: 'Workflow Designer',
model: 'claude-sonnet-4-6',
provider: 'anthropic',
systemPrompt:
'You design and manage automation workflows. ' +
'Use architect_draft_workflow to create or modify graphs, ' +
'architect_publish_workflow to save them, ' +
'and architect_get_workflow to inspect existing ones.',
tools: [
{ type: 'builtin', name: 'architect_draft_workflow' },
{ type: 'builtin', name: 'architect_publish_workflow' },
{ type: 'builtin', name: 'architect_get_workflow' },
],
permissions: { readKeys: ['*'], writeKeys: ['*'] },
});

Step 3: The agent manages the full lifecycle

Section titled “Step 3: The agent manages the full lifecycle”

The agent can now handle the Draft → Review → Publish loop autonomously:

You: "We need a workflow that scrapes competitors' pricing pages and sends a Slack summary"
Agent: [calls architect_draft_workflow] → generates graph
Agent: "Here's what I designed: 3 nodes (scraper → analyzer → notifier)..."
You: "Add error retries to the scraper node"
Agent: [calls architect_draft_workflow with currentGraph] → refined graph
Agent: "Updated. Want me to publish it?"
You: "Yes"
Agent: [calls architect_publish_workflow] → saved to registry
Tool Needs initArchitectTools()? Description
architect_draft_workflow No Generate a graph from a prompt, or modify an existing graph. Returns the graph for review.
architect_publish_workflow Yes Save a graph to the persistent registry. Set overwrite: true to update an existing graph.
architect_get_workflow Yes Load a published graph by ID.
  • Graphs — the graph format the Architect generates
  • Nodes — the full node type reference
  • Supervisor — combine the Architect with supervisor routing