DocumentationGetting StartedYour First Agent

Your First Agent

Build a complete agent step by step.

What We’ll Build

A research assistant that:

  1. Searches for information
  2. Analyzes findings
  3. Generates a report

Step 1: Create the Prompts and Modules

from ainalyn import ModuleBuilder, PromptBuilder
 
# Module for search
search_module = (
    ModuleBuilder("search-module")
    .description("Searches for relevant information")
    .input_schema({
        "type": "object",
        "properties": {"query": {"type": "string"}},
        "required": ["query"]
    })
    .output_schema({
        "type": "object",
        "properties": {"results": {"type": "array"}},
    })
    .build()
)
 
# Prompt for analysis
analyze_prompt = (
    PromptBuilder("analyze-prompt")
    .description("Analyzes collected information")
    .template("Analyze the following information: {{search_results}}")
    .variables("search_results")
    .build()
)
 
# Prompt for report generation
report_prompt = (
    PromptBuilder("report-prompt")
    .description("Generates a structured research report")
    .template("Create a report based on: {{analysis}}")
    .variables("analysis")
    .build()
)

Step 2: Create the Nodes

from ainalyn import NodeBuilder
 
# Node 1: Search
search_node = (
    NodeBuilder("search-information")
    .description("Search and collect relevant information")
    .uses_module("search-module")
    .inputs("query")
    .outputs("search_results")
    .next_nodes("analyze-findings")
    .build()
)
 
# Node 2: Analyze (follows search)
analyze_node = (
    NodeBuilder("analyze-findings")
    .description("Analyze the collected information")
    .uses_prompt("analyze-prompt")
    .inputs("search_results")
    .outputs("analysis")
    .next_nodes("generate-report")
    .build()
)
 
# Node 3: Report (follows analyze)
report_node = (
    NodeBuilder("generate-report")
    .description("Create a structured research report")
    .uses_prompt("report-prompt")
    .inputs("analysis")
    .outputs("report")
    .build()
)

Flow: search → analyze → report

Step 3: Create the Workflow

from ainalyn import WorkflowBuilder
 
research_workflow = (
    WorkflowBuilder("conduct-research")
    .description("Research and reporting workflow")
    .add_node(search_node)
    .add_node(analyze_node)
    .add_node(report_node)
    .entry_node("search-information")
    .build()
)

Step 4: Create the Agent

from ainalyn import AgentBuilder
 
research_agent = (
    AgentBuilder("research-assistant")
    .description("Searches, analyzes, and reports on topics")
    .version("1.0.0")
    .add_module(search_module)
    .add_prompt(analyze_prompt)
    .add_prompt(report_prompt)
    .add_workflow(research_workflow)
    .build()
)

Step 5: Validate and Export

from ainalyn.api import validate, export_yaml
 
# Validate
result = validate(research_agent)
if result.is_valid:
    print("Valid!")
else:
    for error in result.errors:
        print(f"Error: {error.message}")
 
# Export
yaml_output = export_yaml(research_agent)
 
# Save to file
with open("research_assistant.yaml", "w", encoding="utf-8") as f:
    f.write(yaml_output)

Complete Code

research_agent.py:

from ainalyn import (
    AgentBuilder,
    WorkflowBuilder,
    NodeBuilder,
    ModuleBuilder,
    PromptBuilder,
)
from ainalyn.api import validate, export_yaml
 
# Create resources
search_module = (
    ModuleBuilder("search-module")
    .description("Searches for relevant information")
    .input_schema({
        "type": "object",
        "properties": {"query": {"type": "string"}},
        "required": ["query"]
    })
    .output_schema({
        "type": "object",
        "properties": {"results": {"type": "array"}},
    })
    .build()
)
 
analyze_prompt = (
    PromptBuilder("analyze-prompt")
    .description("Analyzes collected information")
    .template("Analyze the following information: {{search_results}}")
    .variables("search_results")
    .build()
)
 
report_prompt = (
    PromptBuilder("report-prompt")
    .description("Generates a structured research report")
    .template("Create a report based on: {{analysis}}")
    .variables("analysis")
    .build()
)
 
# Create nodes
search_node = (
    NodeBuilder("search-information")
    .description("Search and collect relevant information")
    .uses_module("search-module")
    .inputs("query")
    .outputs("search_results")
    .next_nodes("analyze-findings")
    .build()
)
 
analyze_node = (
    NodeBuilder("analyze-findings")
    .description("Analyze the collected information")
    .uses_prompt("analyze-prompt")
    .inputs("search_results")
    .outputs("analysis")
    .next_nodes("generate-report")
    .build()
)
 
report_node = (
    NodeBuilder("generate-report")
    .description("Create a structured research report")
    .uses_prompt("report-prompt")
    .inputs("analysis")
    .outputs("report")
    .build()
)
 
# Create workflow
research_workflow = (
    WorkflowBuilder("conduct-research")
    .description("Research and reporting workflow")
    .add_node(search_node)
    .add_node(analyze_node)
    .add_node(report_node)
    .entry_node("search-information")
    .build()
)
 
# Create agent
research_agent = (
    AgentBuilder("research-assistant")
    .description("Searches, analyzes, and reports on topics")
    .version("1.0.0")
    .add_module(search_module)
    .add_prompt(analyze_prompt)
    .add_prompt(report_prompt)
    .add_workflow(research_workflow)
    .build()
)
 
# Validate and export
result = validate(research_agent)
if result.is_valid:
    yaml_output = export_yaml(research_agent)
    with open("research_assistant.yaml", "w", encoding="utf-8") as f:
        f.write(yaml_output)
    print("Agent created and saved!")
else:
    for error in result.errors:
        print(f"Error: {error.message}")

Run It

python research_agent.py

The Generated YAML

name: research-assistant
version: 1.0.0
description: Searches, analyzes, and reports on topics
workflows:
- name: conduct-research
  description: Research and reporting workflow
  entry_node: search-information
  nodes:
  - name: search-information
    description: Search and collect relevant information
    type: module
    reference: search-module
    next_nodes:
    - analyze-findings
    inputs:
    - query
    outputs:
    - search_results
  - name: analyze-findings
    description: Analyze the collected information
    type: prompt
    reference: analyze-prompt
    next_nodes:
    - generate-report
    inputs:
    - search_results
    outputs:
    - analysis
  - name: generate-report
    description: Create a structured research report
    type: prompt
    reference: report-prompt
    inputs:
    - analysis
    outputs:
    - report
modules:
- name: search-module
  description: Searches for relevant information
  input_schema:
    type: object
    properties:
      query:
        type: string
    required:
    - query
  output_schema:
    type: object
    properties:
      results:
        type: array
prompts:
- name: analyze-prompt
  description: Analyzes collected information
  template: 'Analyze the following information: {{search_results}}'
  variables:
  - search_results
- name: report-prompt
  description: Generates a structured research report
  template: 'Create a report based on: {{analysis}}'
  variables:
  - analysis

Key Concepts

Workflow Flow

  • Use .next_nodes() to define the next steps in the flow
  • Set .entry_node() on the workflow to specify where it starts
  • Nodes reference resources (modules, prompts, tools) via .uses_*()

Builder Pattern

  • Always call .build() at the end
  • Methods return self for chaining
  • Immutable entities created on .build()

Bottom-Up Construction

  1. Build resources first (modules, prompts, tools)
  2. Build nodes that reference those resources
  3. Add nodes to workflow with entry_node
  4. Add resources and workflows to agent

Common Mistakes

Forgetting .build()

# Wrong
node = NodeBuilder("task").description("Do something")
 
# Correct
node = NodeBuilder("task").description("Do something").uses_prompt("task-prompt").build()

Circular flow

# Wrong (A points to B, B points to A)
node_a = NodeBuilder("a").description("A").uses_prompt("prompt-a").next_nodes("b").build()
node_b = NodeBuilder("b").description("B").uses_prompt("prompt-b").next_nodes("a").build()

Not setting entry_node

# Wrong
workflow = WorkflowBuilder("main").add_node(node).build()
 
# Correct
workflow = WorkflowBuilder("main").add_node(node).entry_node("node-name").build()

Invalid names

# Wrong
AgentBuilder("My Agent")   # No spaces
AgentBuilder("MyAgent")    # Must start with lowercase
 
# Correct (use lowercase with hyphens)
AgentBuilder("my-agent")
AgentBuilder("research-assistant")

Next Steps

Need Help?