Back to Documentation

Tutorials

Step-by-step tutorials to build real-world AI applications with RANA. From beginner to advanced, learn by building.

Build a ChatGPT Clone

Beginner15 min

Create a full-featured chat interface with streaming, conversation history, and multiple models

// 1. Create the chat API route
// app/api/chat/route.ts
import { Agent } from '@rana/core';
import { streamResponse } from '@rana/helpers';

const agent = new Agent({
  name: 'ChatBot',
  model: 'claude-sonnet-4-20250514',
  systemPrompt: 'You are a helpful assistant.'
});

export async function POST(req: Request) {
  const { messages } = await req.json();

  const stream = agent.stream(messages);
  return streamResponse(stream);
}

// 2. Create the chat component
// components/Chat.tsx
'use client';
import { useChat } from '@rana/react';

export function Chat() {
  const { messages, input, setInput, send, isLoading } = useChat({
    api: '/api/chat'
  });

  return (
    <div className="flex flex-col h-screen">
      <div className="flex-1 overflow-auto p-4">
        {messages.map((m) => (
          <div key={m.id} className={m.role === 'user' ? 'text-right' : ''}>
            <div className="inline-block p-3 rounded-lg max-w-[80%]">
              {m.content}
            </div>
          </div>
        ))}
      </div>
      <form onSubmit={(e) => { e.preventDefault(); send(); }} className="p-4">
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Type a message..."
          disabled={isLoading}
          className="w-full p-3 border rounded-lg"
        />
      </form>
    </div>
  );
}

Document Q&A with RAG

Intermediate30 min

Build a system that answers questions from your documents using RAG

// 1. Index your documents
import { RAGPresets, SemanticChunker } from '@rana/rag';

const pipeline = RAGPresets.balanced();

// Load and chunk documents
const documents = await loadDocuments('./docs');
const chunker = new SemanticChunker({ maxTokens: 500 });

for (const doc of documents) {
  const chunks = await chunker.chunk(doc.content);
  await pipeline.index(chunks.map((chunk, i) => ({
    id: `${doc.id}-${i}`,
    content: chunk,
    metadata: { source: doc.name, page: i }
  })));
}

// 2. Create the Q&A endpoint
// app/api/ask/route.ts
import { pipeline } from '@/lib/rag';

export async function POST(req: Request) {
  const { question } = await req.json();

  const result = await pipeline.query({
    query: question,
    topK: 5,
    includeMetadata: true
  });

  return Response.json({
    answer: result.answer,
    sources: result.sources.map(s => ({
      content: s.content.slice(0, 200),
      source: s.metadata.source,
      page: s.metadata.page
    }))
  });
}

// 3. Create the UI
'use client';
import { useState } from 'react';

export function DocumentQA() {
  const [question, setQuestion] = useState('');
  const [result, setResult] = useState(null);

  const ask = async () => {
    const res = await fetch('/api/ask', {
      method: 'POST',
      body: JSON.stringify({ question })
    });
    setResult(await res.json());
  };

  return (
    <div>
      <input
        value={question}
        onChange={(e) => setQuestion(e.target.value)}
        placeholder="Ask a question about your documents..."
      />
      <button onClick={ask}>Ask</button>

      {result && (
        <div>
          <h3>Answer</h3>
          <p>{result.answer}</p>
          <h4>Sources</h4>
          {result.sources.map((s, i) => (
            <div key={i}>
              <strong>{s.source}</strong> (Page {s.page})
              <p>{s.content}...</p>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

AI Agent with Tools

Intermediate25 min

Create an agent that can search the web, read files, and execute code

import { Agent, Tool } from '@rana/core';

// Define tools
const webSearchTool = new Tool({
  name: 'web_search',
  description: 'Search the web for current information',
  parameters: {
    query: { type: 'string', description: 'Search query' }
  },
  handler: async ({ query }) => {
    const results = await fetch(
      `https://api.search.com?q=${encodeURIComponent(query)}`
    );
    return await results.json();
  }
});

const calculatorTool = new Tool({
  name: 'calculator',
  description: 'Perform mathematical calculations',
  parameters: {
    expression: { type: 'string', description: 'Math expression to evaluate' }
  },
  handler: async ({ expression }) => {
    // Safe evaluation
    const result = new Function(`return ${expression}`)();
    return { result };
  }
});

const weatherTool = new Tool({
  name: 'weather',
  description: 'Get current weather for a location',
  parameters: {
    location: { type: 'string', description: 'City name' }
  },
  handler: async ({ location }) => {
    const res = await fetch(
      `https://api.weather.com/current?city=${location}`
    );
    return await res.json();
  }
});

// Create agent with tools
const agent = new Agent({
  name: 'ResearchAssistant',
  model: 'claude-sonnet-4-20250514',
  systemPrompt: `You are a helpful research assistant.
    Use tools when needed to find accurate, current information.
    Always cite your sources.`,
  tools: [webSearchTool, calculatorTool, weatherTool]
});

// Run the agent
const result = await agent.run(
  'What is the weather in Tokyo and what is 15% of 234?'
);

console.log(result);
// "The weather in Tokyo is currently 22°C and sunny.
//  15% of 234 is 35.1"

Email Processing Pipeline

Advanced45 min

Automatically classify, summarize, and respond to emails

import { Workflow, Step, Branch } from '@rana/core';
import { classify, summarize, generate } from '@rana/helpers';

const emailWorkflow = new Workflow({ name: 'email-processor' });

// Step 1: Classify the email
emailWorkflow.addStep(new Step({
  name: 'classify',
  handler: async (input) => {
    const category = await classify(input.email.body, [
      'support', 'sales', 'partnership', 'spam', 'other'
    ]);
    return { category, email: input.email };
  }
}));

// Step 2: Summarize (except spam)
emailWorkflow.addStep(new Step({
  name: 'summarize',
  dependsOn: ['classify'],
  condition: (ctx) => ctx.getOutput('classify').category !== 'spam',
  handler: async (_, ctx) => {
    const { email } = ctx.getOutput('classify');
    const summary = await summarize(email.body, { style: 'brief' });
    return { summary };
  }
}));

// Step 3: Branch based on category
emailWorkflow.addBranch(new Branch({
  name: 'route',
  dependsOn: ['classify', 'summarize'],
  conditions: [
    {
      when: (ctx) => ctx.getOutput('classify').category === 'support',
      then: 'support-response'
    },
    {
      when: (ctx) => ctx.getOutput('classify').category === 'sales',
      then: 'sales-response'
    }
  ],
  default: 'generic-response'
}));

// Support response
emailWorkflow.addStep(new Step({
  name: 'support-response',
  handler: async (_, ctx) => {
    const { email } = ctx.getOutput('classify');
    const response = await generate(`
      Write a helpful support response to this email:

      Subject: ${email.subject}
      Body: ${email.body}

      Be empathetic, professional, and offer specific solutions.
    `);
    return { response, action: 'send' };
  }
}));

// Sales response
emailWorkflow.addStep(new Step({
  name: 'sales-response',
  handler: async (_, ctx) => {
    const { email } = ctx.getOutput('classify');
    const response = await generate(`
      Write a sales follow-up to this inquiry:

      Subject: ${email.subject}
      Body: ${email.body}

      Be professional, highlight our value proposition.
    `);
    return { response, action: 'draft' }; // Don't auto-send sales
  }
}));

// Run workflow
const result = await emailWorkflow.run({
  email: {
    subject: 'Issue with my subscription',
    body: 'I was charged twice this month...',
    from: 'customer@example.com'
  }
});

Semantic Code Search

Advanced40 min

Build a code search engine that understands natural language queries

import { RAGPresets } from '@rana/rag';
import { glob } from 'glob';
import * as fs from 'fs/promises';

// 1. Create code-optimized pipeline
const pipeline = RAGPresets.code('typescript');

// 2. Index your codebase
async function indexCodebase(dir: string) {
  const files = await glob(`${dir}/**/*.{ts,tsx,js,jsx}`);

  for (const file of files) {
    const content = await fs.readFile(file, 'utf-8');

    // Extract functions, classes, and interfaces
    const chunks = extractCodeChunks(content);

    for (const chunk of chunks) {
      await pipeline.index([{
        id: `${file}:${chunk.line}`,
        content: chunk.content,
        metadata: {
          file,
          line: chunk.line,
          type: chunk.type,  // 'function' | 'class' | 'interface'
          name: chunk.name
        }
      }]);
    }
  }
}

// 3. Search with natural language
async function searchCode(query: string) {
  const result = await pipeline.query({
    query,
    topK: 10,
    synthesize: false  // Return raw results
  });

  return result.sources.map(s => ({
    file: s.metadata.file,
    line: s.metadata.line,
    type: s.metadata.type,
    name: s.metadata.name,
    code: s.content,
    score: s.score
  }));
}

// 4. Example usage
await indexCodebase('./src');

const results = await searchCode(
  'function that handles user authentication'
);

// Returns matches like:
// [
//   { file: 'src/auth/login.ts', line: 45, name: 'authenticateUser', ... },
//   { file: 'src/middleware/auth.ts', line: 12, name: 'verifyToken', ... }
// ]

Scheduled AI Reports

Intermediate20 min

Generate and send automated AI reports on a schedule

import { Agent } from '@rana/core';
import { CronJob } from 'cron';

// 1. Create report generator agent
const reportAgent = new Agent({
  name: 'ReportGenerator',
  model: 'claude-sonnet-4-20250514',
  systemPrompt: `You are a business analyst.
    Generate clear, actionable reports with insights.`
});

// 2. Define report generation function
async function generateDailyReport() {
  // Fetch data from your sources
  const salesData = await fetchSalesData();
  const userMetrics = await fetchUserMetrics();
  const systemHealth = await fetchSystemHealth();

  // Generate report with AI
  const report = await reportAgent.run(`
    Generate a daily business report based on this data:

    Sales: ${JSON.stringify(salesData)}
    User Metrics: ${JSON.stringify(userMetrics)}
    System Health: ${JSON.stringify(systemHealth)}

    Include:
    - Executive summary (3 bullet points)
    - Key metrics with trends
    - Notable insights
    - Recommended actions
  `);

  // Send report
  await sendEmail({
    to: 'team@company.com',
    subject: `Daily Report - ${new Date().toLocaleDateString()}`,
    body: report
  });

  await sendSlack({
    channel: '#daily-reports',
    text: report
  });

  console.log('Daily report sent!');
}

// 3. Schedule the report
const job = new CronJob(
  '0 8 * * *',  // Every day at 8 AM
  generateDailyReport,
  null,
  true,
  'America/New_York'
);

job.start();
console.log('Report scheduler started');

More Tutorials Coming Soon

We're adding new tutorials regularly. Have a request?

Request a Tutorial