Tutorials

Hands-on, step-by-step tutorials to get productive with Sagewai. Each tutorial is self-contained with complete, copy-paste code.

Tutorial 1: Your First Agent (5 min)

Prerequisites

  • Python 3.10+
  • One API key (OpenAI, Anthropic, or Google)

Steps

Install Sagewai:

pip install sagewai

Set your API key:

export OPENAI_API_KEY=sk-...

Create my_agent.py:

import asyncio
from sagewai import UniversalAgent

agent = UniversalAgent(
    name="my-first-agent",
    model="gpt-4o",
    system_prompt="You are a helpful assistant. Be concise.",
)

async def main():
    response = await agent.chat("What are the three laws of robotics?")
    print(response)

asyncio.run(main())

Run it:

python my_agent.py

Add a Tool

import asyncio
from sagewai import UniversalAgent, tool

@tool
async def calculate(expression: str) -> str:
    """Evaluate a math expression."""
    return str(eval(expression))

agent = UniversalAgent(
    name="math-agent",
    model="gpt-4o",
    system_prompt="You are a math assistant. Use the calculate tool for any math.",
    tools=[calculate],
)

async def main():
    response = await agent.chat("What is 2^10 + 3^7?")
    print(response)

asyncio.run(main())

The agent will automatically call the calculate tool when it encounters math.


Tutorial 2: Multi-Model Agent (10 min)

Same agent, different models. Sagewai makes switching models a one-line change.

Cloud Models

from sagewai import UniversalAgent, providers

# OpenAI
agent = UniversalAgent(name="bot", **providers.openai("gpt-4o"))

# Anthropic
agent = UniversalAgent(name="bot", **providers.anthropic("claude-sonnet-4-20250514"))

# Google
agent = UniversalAgent(name="bot", **providers.gemini("gemini/gemini-2.5-flash"))

# Groq (fast inference)
agent = UniversalAgent(name="bot", **providers.groq("groq/llama-3.1-70b-versatile"))

Local Models (No API Key)

# Install and start Ollama
curl -fsSL https://ollama.ai/install.sh | sh
ollama pull llama3.1:8b
from sagewai import UniversalAgent, providers

agent = UniversalAgent(
    name="local-bot",
    system_prompt="You are a helpful assistant.",
    **providers.ollama("llama3.1:8b"),
)

response = await agent.chat("Explain quantum entanglement simply")

Compare Models

import asyncio
from sagewai import UniversalAgent, providers

models = [
    ("GPT-4o", providers.openai("gpt-4o")),
    ("Claude Sonnet", providers.anthropic("claude-sonnet-4-20250514")),
    ("Llama 3.1 (local)", providers.ollama("llama3.1:8b")),
]

async def compare():
    question = "What is the meaning of life in one sentence?"
    for name, config in models:
        agent = UniversalAgent(name=name, **config)
        response = await agent.chat(question)
        print(f"\n{name}: {response}")

asyncio.run(compare())

Tutorial 3: Agent with Memory (15 min)

Create an agent that remembers facts across conversations.

Prerequisites

pip install sagewai

Build It

import asyncio
from sagewai import UniversalAgent
from sagewai.memory import GraphMemory

memory = GraphMemory()

agent = UniversalAgent(
    name="memory-agent",
    model="gpt-4o",
    system_prompt="You are a helpful assistant with a good memory. Use what you remember about the user.",
    memory=memory,
)

async def main():
    # First conversation
    await agent.chat("My name is Alex and I work at Acme Corp")
    await agent.chat("I'm building a recommendation engine in Python")

    # The agent remembers
    response = await agent.chat("What project am I working on?")
    print(response)  # Will mention the recommendation engine

    # Check what was stored
    entities = await memory.list_entities()
    print(f"\nStored entities: {entities}")

asyncio.run(main())

Query Memory with Directives

agent = UniversalAgent(
    name="directive-agent",
    model="gpt-4o",
    system_prompt="""You are a helpful assistant.

    Here's what you remember about the user:
    @memory('user preferences and context')
    """,
    memory=memory,
    directives=True,
)

The @memory directive is resolved before the prompt reaches the LLM, injecting relevant facts from the knowledge graph.


Tutorial 4: RAG Pipeline with Context Engine (20 min)

Build an agent that answers questions from your documents.

Prerequisites

pip install "sagewai[memory]"

Ingest a Document

import asyncio
from sagewai.context.engine import ContextEngine

engine = ContextEngine()

async def ingest():
    await engine.ingest_file(
        path="quarterly_report.pdf",
        scope="project",
        tags=["finance", "Q4-2025"],
    )
    print("Document ingested!")

asyncio.run(ingest())

Query with an Agent

import asyncio
from sagewai import UniversalAgent
from sagewai.context.engine import ContextEngine

engine = ContextEngine()

agent = UniversalAgent(
    name="research-agent",
    model="gpt-4o",
    system_prompt="""You answer questions using the provided context.
    Always cite the source document.

    @context('{{user_query}}', scope='project', tags='finance')
    """,
    directives=True,
    context_engine=engine,
)

async def main():
    response = await agent.chat("What was our Q4 revenue?")
    print(response)

asyncio.run(main())

What Happens Under the Hood

  1. User asks "What was our Q4 revenue?"
  2. The @context directive resolves — searches vectors + BM25 + graph
  3. Matching chunks from quarterly_report.pdf are injected into the prompt
  4. The LLM answers using the retrieved context
  5. The response cites the source document

Tutorial 5: Multi-Agent Workflow (20 min)

Build a content pipeline with three specialized agents.

import asyncio
from sagewai import UniversalAgent, SequentialAgent

researcher = UniversalAgent(
    name="researcher",
    model="gpt-4o",
    system_prompt="""You are a research specialist.
    Given a topic, provide comprehensive research findings
    with key facts, statistics, and expert opinions.""",
)

analyst = UniversalAgent(
    name="analyst",
    model="gpt-4o",
    system_prompt="""You are a data analyst.
    Take research findings and identify:
    - Key trends and patterns
    - Actionable insights
    - Risks and opportunities""",
)

writer = UniversalAgent(
    name="writer",
    model="gpt-4o",
    system_prompt="""You are a professional writer.
    Take analysis results and write a clear, engaging article.
    Use headers, bullet points, and a compelling conclusion.""",
)

pipeline = SequentialAgent(
    name="content-pipeline",
    agents=[researcher, analyst, writer],
)

async def main():
    result = await pipeline.chat(
        "Write an article about the impact of AI on healthcare in 2025"
    )
    print(result)

asyncio.run(main())

Monitor in the Admin Panel

pip install "sagewai[fastapi]"
sagewai admin serve

Open http://localhost:8000 to see agents, runs, and execution flow in the dashboard.


Tutorial 6: Connect from Any Language (10 min)

Start the harness proxy and connect from TypeScript, Go, and Rust.

Start the Harness

sagewai harness start --port 8100

Connect from TypeScript

import { SagewaiClient } from "sagewai";

const client = new SagewaiClient({
  baseUrl: "http://localhost:8100",
  apiKey: "sk-harness-...",
});

const response = await client.chat({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello from TypeScript!" }],
});
console.log(response.content);

Connect from Go

package main

import (
    "context"
    "fmt"
    sagewai "github.com/sagewai/sagewai-go"
)

func main() {
    client := sagewai.NewClient(
        sagewai.WithBaseURL("http://localhost:8100"),
        sagewai.WithAPIKey("sk-harness-..."),
    )

    resp, _ := client.Chat(context.Background(), &sagewai.ChatRequest{
        Model:    "gpt-4o",
        Messages: []sagewai.Message{{Role: "user", Content: "Hello from Go!"}},
    })
    fmt.Println(resp.Content)
}

Connect from Rust

use sagewai::SagewaiClient;

#[tokio::main]
async fn main() -> Result<(), sagewai::Error> {
    let client = SagewaiClient::builder()
        .base_url("http://localhost:8100")
        .api_key("sk-harness-...")
        .build()?;

    let response = client
        .chat("gpt-4o")
        .message("user", "Hello from Rust!")
        .send()
        .await?;

    println!("{}", response.content);
    Ok(())
}

All three connect to the same harness, use the same agents, and their costs are tracked in the Observatory.


Tutorial 7: Deploy Server + Workers (25 min)

Set up a production-like server with distributed workers.

Start the Server

# Start infrastructure
make infra-core   # PostgreSQL + Redis
make db-upgrade   # Apply migrations

# Start the admin backend (includes fleet gateway)
sagewai admin serve --port 8000

Create an Enrollment Key

sagewai fleet create-key \
  --org mycompany \
  --name worker-onboarding \
  --max-uses 5

Save the returned key — it's shown only once.

Start Workers

Worker 1 — CPU (cloud models):

sagewai fleet register \
  --gateway http://localhost:8000 \
  --enrollment-key sk-fleet-... \
  --pool cpu \
  --models gpt-4o,claude-sonnet-4

Worker 2 — GPU (local Ollama):

# On a machine with GPU + Ollama running
sagewai fleet register \
  --gateway http://localhost:8000 \
  --enrollment-key sk-fleet-... \
  --pool gpu \
  --models ollama/llama3.1:70b \
  --labels region=us-east

Submit a Workflow

import asyncio
from sagewai import UniversalAgent, DurableWorkflow
from sagewai.models.worker import RoutingConstraints

agent = UniversalAgent(
    name="analyst",
    model="gpt-4o",
    system_prompt="You analyze data thoroughly.",
)

workflow = DurableWorkflow(
    name="analysis-job",
    steps=[agent],
    routing=RoutingConstraints(worker_pool="cpu"),
)

async def main():
    result = await workflow.submit("Analyze Q4 sales trends")
    print(f"Run ID: {result.run_id}")

asyncio.run(main())

Check Fleet Status

sagewai fleet list-workers --org mycompany

Tutorial 8: CI/CD Agent Pipeline (15 min)

Add AI agents to your GitHub Actions workflow.

Add the PR Summary Action

Create .github/workflows/pr-summary.yml:

name: PR Summary
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  summarize:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: sagewai/actions/run-agent@v1
        with:
          agent: summarizer
          input: |
            Summarize this PR:
            Title: ${{ github.event.pull_request.title }}
            Body: ${{ github.event.pull_request.body }}
          fleet-gateway: ${{ secrets.SAGEWAI_GATEWAY_URL }}
          api-key: ${{ secrets.SAGEWAI_API_KEY }}
          post-as-comment: 'true'

Add the Eval Quality Gate

Create .github/workflows/eval-gate.yml:

name: Agent Quality Gate
on:
  push:
    branches: [main]

jobs:
  evaluate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: sagewai/actions/run-evals@v1
        with:
          eval-suite: evals/core-suite.yaml
          threshold: '0.8'
          api-key: ${{ secrets.SAGEWAI_API_KEY }}

Set Up Secrets

In your GitHub repo settings, add:

  • SAGEWAI_GATEWAY_URL — your fleet gateway endpoint
  • SAGEWAI_API_KEY — your API authentication key

Now every PR gets an automatic summary, and agent quality is continuously monitored.


What's Next