MyPrivateClaw logo
MyPrivateClaw
Private AI Directory
Guides 45 min readMar 30· Updated Apr 11, 2026✓ Verified Mar 30, 2026

Private AI Agents: Zero to Hero (2026 Complete Guide)

Build, run, and secure your own AI agents from scratch — no cloud APIs, no data leaks, full control

tailscale ollama crewai langgraph n8n rag qdrant privacy

By the end of this guide you will have a fully private AI agent stack running on your own hardware. No data leaves your machine. No API keys billed per token. No vendor lock-in. You will understand what agents actually are, choose the right framework for your use case, connect it to a local LLM via Ollama, give your agent tools to use, add persistent RAG memory with Qdrant, build a multi-agent pipeline, and lock the whole thing down with Tailscale and Vault.

What you need to start: A machine with at least 16 GB RAM (Mac mini M4 Pro, a PC with an RTX 4060 Ti or better, or a RunPod GPU instance). Ollama installed. Python 3.11+. Docker.

THE EDGE — WEEKLY DIGEST

Get more guides like this in your inbox

No spam. Unsubscribe anytime.

Part 1 — What Is an AI Agent (Actually)?

An AI agent is a loop. It receives a goal, uses an LLM to decide what to do next, executes a tool or action, observes the result, and repeats until the goal is reached or it gives up. That is the entire architecture. Everything else — memory, multi-agent coordination, RAG, guardrails — is scaffolding around that loop.

Every agent has four components: an LLM that decides what to do next (e.g. Ollama running Qwen3.5-27B), tools that are actions the agent can take (web search, file read, code execution), memory for context across turns (Qdrant vector store), and an orchestrator that manages the loop (CrewAI, LangGraph, n8n).

The privacy case for local agents: every tool call, every intermediate reasoning step, every document you feed into RAG goes through the LLM. If that LLM is OpenAI or Anthropic, your data is in their systems. For anything involving customer data, internal documents, medical records, or legal files, local agents are the only responsible choice.

Part 2 — Install Ollama and Choose Your Model

Ollama is the runtime that serves local LLMs with an OpenAI-compatible API. Every agent framework in this guide connects to it the same way. Install it, pull a model that supports function calling (tool use), and verify it is running before proceeding.

# Install via Homebrew brew install ollama # Pull the best all-round agent model (27B, needs 20GB RAM) ollama pull qwen3.5:27b # Fastest option for Mac mini M4 Pro 24GB ollama pull qwen3.5:9b # Budget option — works on 16GB RAM ollama pull llama3.2:latest # Verify Ollama is running ollama serve # starts on http://localhost:11434 curl http://localhost:11434/api/tags
TIPIf your agent framework runs in Docker, use http://host.docker.internal:11434 instead of localhost:11434. On Linux without Docker Desktop, add extra_hosts: ["host.docker.internal:host-gateway"] to your compose file.

Part 3 — Framework Comparison: Which One Should You Use?

There are four serious frameworks for private local agents in 2026. n8n is best for non-coders and workflow automation — it has a visual drag-and-drop editor, native Ollama integration, and 400+ tool integrations. CrewAI is best for role-based multi-agent pipelines in Python. AG2 (AutoGen, github.com/ag2ai/ag2) is best for research and dynamic multi-agent conversations. LangGraph is best for custom stateful workflows and production systems.

Decision guide: if you don't write code, use n8n. If you want role-based agents (researcher + writer + reviewer), use CrewAI. If you want maximum control over agent conversation flow, use LangGraph. If you need agents that can spawn sub-agents dynamically, use AG2.

Part 4 — n8n: Visual Agent Workflows (No Code Required)

n8n is the fastest way to build a working agent. Install it with Docker Compose, connect it to Ollama, and use the visual editor to wire up a Chat Trigger → AI Agent → Memory → Tools pipeline. The AI Agent node handles the LLM loop, tool dispatch, and memory automatically.

bash
mkdir n8n-agent && cd n8n-agent
cat > compose.yaml << 'EOF'
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n:stable
    restart: always
    ports:
      - "5678:5678"
    environment:
      - N8N_RUNNERS_ENABLED=true
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
      - GENERIC_TIMEZONE=America/New_York
    extra_hosts:
      - "host.docker.internal:host-gateway"
    volumes:
      - n8n_data:/home/node/.n8n
volumes:
  n8n_data:
EOF
docker compose up -d
# Open http://localhost:5678
NOTEConnect n8n to Ollama: go to Credentials → New Credential → Ollama, set Base URL to http://host.docker.internal:11434. No API key needed. Then build your workflow: Chat Trigger → AI Agent (Ollama model) → Window Buffer Memory + Calculator + Wikipedia tools.

Part 5 — CrewAI: Role-Based Multi-Agent Pipelines

CrewAI models agents as a crew of specialists. Each agent has a role, a goal, and a backstory. Install with pip install 'crewai[litellm]' and connect to Ollama using LLM(model='ollama/qwen3.5:9b', base_url='http://localhost:11434').

python
from crewai import Agent, Task, Crew, LLM

llm = LLM(model="ollama/qwen3.5:9b", base_url="http://localhost:11434")

researcher = Agent(
    role="Privacy Technology Researcher",
    goal="Find accurate, up-to-date information on the given topic",
    backstory="Expert researcher specializing in privacy tech and open-source AI.",
    llm=llm, verbose=True
)

writer = Agent(
    role="Technical Writer",
    goal="Write clear, accurate technical content based on research",
    backstory="Writes detailed technical guides for privacy-conscious users.",
    llm=llm, verbose=True
)

research_task = Task(
    description="Research the current state of private AI agents in 2026.",
    expected_output="A detailed research brief with key findings and version numbers.",
    agent=researcher
)

write_task = Task(
    description="Using the research brief, write a 500-word introduction.",
    expected_output="A polished 500-word introduction with accurate technical details.",
    agent=writer,
    context=[research_task]
)

crew = Crew(agents=[researcher, writer], tasks=[research_task, write_task])
result = crew.kickoff()

Part 6 — AG2 (AutoGen): Dynamic Multi-Agent Conversations

AG2 (v0.11.5, github.com/ag2ai/ag2) supports dynamic agent conversations where agents can debate, self-correct, and spawn sub-agents. Install with pip install ag2[ollama]. It directly supports Ollama without LiteLLM.

python
from autogen import ConversableAgent

config = {
    "config_list": [{
        "model": "qwen3.5:9b",
        "api_type": "ollama",
        "client_host": "http://localhost:11434",
        "stream": False
    }],
    "temperature": 0.7
}

assistant = ConversableAgent(
    name="Assistant",
    system_message="You are a helpful AI assistant. Be concise and accurate.",
    llm_config=config, human_input_mode="NEVER"
)

critic = ConversableAgent(
    name="Critic",
    system_message="Point out flaws and missing information in responses.",
    llm_config=config, human_input_mode="NEVER"
)

result = assistant.initiate_chat(
    critic,
    message="Explain why local AI agents are better for privacy.",
    max_turns=3
)

Part 7 — LangGraph: Stateful Agent Workflows

LangGraph models agent workflows as directed graphs where every state change is explicit and auditable. Install with pip install langgraph langchain-ollama. Use create_react_agent for a quick start, or build a custom StateGraph for full control.

python
from langgraph.prebuilt import create_react_agent
from langchain_ollama import ChatOllama
from langchain_core.tools import tool

llm = ChatOllama(model="qwen3.5:9b", base_url="http://localhost:11434")

@tool
def get_file_contents(path: str) -> str:
    """Read the contents of a local file. Input: absolute file path."""
    try:
        return open(path).read()
    except Exception as e:
        return f"Error: {e}"

@tool
def list_directory(path: str) -> str:
    """List files in a directory. Input: absolute directory path."""
    import os
    try:
        return "\n".join(os.listdir(path))
    except Exception as e:
        return f"Error: {e}"

agent = create_react_agent(llm, tools=[get_file_contents, list_directory])
result = agent.invoke({
    "messages": [{"role": "user",
                  "content": "List files in /tmp and read the first .txt file."}]
})
print(result["messages"][-1].content)
TIPLangGraph's killer feature is persistence. Add SqliteSaver.from_conn_string('/data/state.db') as checkpointer to compile(), then use thread_id in config to resume any workflow from where it left off — even days later.

Part 8 — RAG Memory: Give Your Agent Long-Term Knowledge

RAG (Retrieval-Augmented Generation) lets your agent search a private knowledge base before answering. Start Qdrant with Docker, ingest your documents using a local embedding model (no API key needed), then expose search as an agent tool.

bash
# Start Qdrant
docker run -d -p 6333:6333 -p 6334:6334 \
  -v "$(pwd)/qdrant_storage:/qdrant/storage:z" \
  qdrant/qdrant
# Dashboard: http://localhost:6333/dashboard

# Install Python dependencies
pip install qdrant-client sentence-transformers

RAG — Ingest Documents and Query

Use nomic-ai/nomic-embed-text-v1.5 (137MB, runs locally) to embed your documents into Qdrant, then expose search as a CrewAI or LangGraph tool.

python
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
from sentence_transformers import SentenceTransformer
import uuid, glob

embedder = SentenceTransformer("nomic-ai/nomic-embed-text-v1.5", trust_remote_code=True)
client = QdrantClient(url="http://localhost:6333")

client.create_collection(
    collection_name="private_docs",
    vectors_config=VectorParams(size=768, distance=Distance.COSINE)
)

# Ingest all markdown files
points = []
for filepath in glob.glob("/docs/**/*.md", recursive=True):
    content = open(filepath).read()
    words = content.split()
    chunks = [" ".join(words[i:i+500]) for i in range(0, len(words), 500)]
    for chunk in chunks:
        points.append(PointStruct(
            id=str(uuid.uuid4()),
            vector=embedder.encode(chunk).tolist(),
            payload={"text": chunk, "source": filepath}
        ))
client.upsert(collection_name="private_docs", points=points)

# Search function (use as agent tool)
def rag_search(query: str) -> str:
    results = client.query_points(
        collection_name="private_docs",
        query=embedder.encode(query).tolist(),
        limit=5
    ).points
    return "\n\n---\n\n".join([r.payload["text"] for r in results])

Part 9 — Multi-Agent Orchestration Patterns

Three patterns cover most use cases. Sequential pipeline: each agent hands off to the next (CrewAI default, best for research → draft → review). Hierarchical: a manager agent delegates to specialists (use Process.hierarchical in CrewAI, set allow_delegation=True on the manager). Debate and consensus: two agents argue, a third judges (AG2's conversation model, best for fact-checking and avoiding hallucination).

Avoiding common failures: always set max_turns or max_iterations (agents get stuck in loops), pass summaries between agents not full transcripts (context overflow), limit tools per agent to 3-5 (more tools confuses smaller models), use Pydantic schemas to validate handoffs.

Part 10 — Securing Your Agent Stack

A local agent with internet access, file system access, and code execution is a significant attack surface. These controls are non-negotiable.

bash
# 1. Isolate agents in Docker with restricted capabilities
docker run --rm \
  --network=none \
  --read-only \
  --tmpfs /tmp \
  --cap-drop=ALL \
  --security-opt=no-new-privileges \
  my-agent-image

# 2. Store secrets in HashiCorp Vault (never hardcode)
docker run -d --name vault -p 8200:8200 \
  -e VAULT_DEV_ROOT_TOKEN_ID=myroot hashicorp/vault:latest
vault kv put secret/agent/tools serper_api_key=your_key_here

# 3. Use Tailscale for remote access (never expose ports directly)
curl -fsSL https://tailscale.com/install.sh | sh && sudo tailscale up
WARNINGSanitize all tool outputs before passing back to the LLM. Prompt injection via tool results is a real attack vector — strip patterns like 'ignore previous instructions' and truncate outputs to 4000 chars max.

Part 11 — Complete Stack Reference

The full private agent stack: Ollama 0.18+ (LLM runtime), Qwen3.5 27B Q4 (agent model), n8n 2.14+ (orchestrator), Qdrant 1.13+ (vector DB), nomic-embed-text-v1.5 (embeddings), HashiCorp Vault (secrets), Tailscale (remote access), Open WebUI 0.8+ (chat interface). Hardware: Mac mini M4 Pro 48GB (~$1,799) or PC with RTX 4090 (~$1,800) for the full stack. Mac mini M4 Pro 24GB (~$1,299) for a lighter setup.

yaml
# Full compose.yaml — complete private agent stack
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n:stable
    ports: ["5678:5678"]
    environment:
      - N8N_RUNNERS_ENABLED=true
      - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
    extra_hosts: ["host.docker.internal:host-gateway"]
    volumes: [n8n_data:/home/node/.n8n]

  qdrant:
    image: qdrant/qdrant:latest
    ports: ["6333:6333", "6334:6334"]
    volumes: [qdrant_storage:/qdrant/storage]

  open-webui:
    image: ghcr.io/open-webui/open-webui:main
    ports: ["3000:8080"]
    environment:
      - OLLAMA_BASE_URL=http://host.docker.internal:11434
    extra_hosts: ["host.docker.internal:host-gateway"]
    volumes: [open_webui:/app/backend/data]

volumes:
  n8n_data:
  qdrant_storage:
  open_webui:
NOTEWhat to build next: Email agent (n8n + Gmail trigger → AI Agent → draft reply → human approval), Document Q&A (Qdrant RAG + Open WebUI), Code review crew (CrewAI with Reviewer + Security Auditor + Fixer), Monitoring agent (scheduled n8n workflow that checks servers and alerts on anomalies). The entire stack costs $0/month on your own hardware.
Read next

RELATED GUIDES