← all conversations

Build AI Agent CLI

2025-12-128 turns18,096 charsgpt-5-1
ai-agentself-hostedcli

Summary

User sought to build a self-hosted AI agent CLI using Ollama and Django Ninja.

Messages

https://medium.com/@tom.mart/build-self-hosted-ai-agent-with-ollama-and-django-ninja-b978f0fe30c5 https://blog.devops.dev/build-self-hosted-ai-agent-with-ollama-pydantic-ai-and-django-ninja-53c6b3f14a1d https://medium.com/@tom.mart/build-self-hosted-ai-agent-with-ollama-pydantic-ai-and-django-ninja-65214a3afb35 ----Read these articles and deliver back a CLIne prompt to build this.
Here’s a ready-to-use **CLINE prompt** (CLI-friendly task description + commands) to *build a self-hosted AI agent using Ollama, Pydantic AI, and Django Ninja* based on the articles you linked. The prompt assumes you’re starting from an empty project directory and have a working Ollama server running locally or on your network. citeturn0search0turn0view1 --- ## 🚀 CLI-Ready Project Bootstrap Prompt ```bash # 1) Create project root mkdir ai-agent && cd ai-agent # 2) Create backend directory mkdir backend && cd backend # 3) Create and activate Python virtual environment python3 -m venv .env source .env/bin/activate # 4) Set Ollama env variables (replace <YOUR_IP> with your server IP) export OLLAMA_HOST="http://<YOUR_IP_OR_LOCALHOST>:11434" export OLLAMA_BASE_URL="$OLLAMA_HOST/v1" # 5) Create requirements file cat > requirements.txt << 'EOF' django django-ninja django-ninja-extra django-ninja-jwt ollama pydantic-ai psycopg2-binary pgvector EOF # 6) Install dependencies pip install -r requirements.txt # 7) Start Django project + app django-admin startproject core . python manage.py startapp chatbot # 8) Configure Django: # - add 'ninja_extra', 'ninja_jwt', 'core', 'chatbot' to INSTALLED_APPS # - configure PostgreSQL connection # 9) Create API setup (core/api.py) cat > core/api.py << 'EOF' from ninja_extra import NinjaExtraAPI from ninja_jwt.controller import NinjaJWTDefaultController api = NinjaExtraAPI() api.register_controllers(NinjaJWTDefaultController) EOF # 10) Update core/urls.py to include API cat > core/urls.py << 'EOF' from django.contrib import admin from django.urls import path from .api import api urlpatterns = [ path('admin/', admin.site.urls), path('api/', api.urls), ] EOF # 11) Define schemas for agent cat > chatbot/schemas.py << 'EOF' from ninja import Schema class ChatbotMessageSchema(Schema): message: str name: str class ChatbotResponseSchema(Schema): response: str EOF # 12) Create agent + endpoint (chatbot/api.py) cat > chatbot/api.py << 'EOF' from ninja import Router from .schemas import ChatbotMessageSchema, ChatbotResponseSchema import random from pydantic_ai import Agent, RunContext router = Router(tags=["chatbot"]) # Create Pydantic AI agent using Ollama model agent = Agent( 'ollama:qwen3:latest', deps_type=str, system_prompt=( "You're a dice game agent. You should roll the die and check if " "the rolled number matches the user's guess, and respond accordingly." ), ) @agent.tool_plain def roll_dice() -> str: return str(random.randint(1, 6)) @agent.tool def get_player_name(ctx: RunContext[str]) -> str: return ctx.deps def chat_with_agent(message: str, name: str) -> str: result = agent.run_sync(message, deps=name) return result.output @router.post("/roll_a_dice") def ai_agent(request, payload: ChatbotMessageSchema): return ChatbotResponseSchema(response=chat_with_agent(payload.message, payload.name)) EOF # 13) Register chatbot router in core/api.py cat >> core/api.py << 'EOF' from chatbot.api import router as chatbot_router api.add_router("/chatbot/", chatbot_router) EOF # 14) Migrate database + create superuser python manage.py makemigrations python manage.py migrate python manage.py createsuperuser # 15) Run Django server python manage.py runserver 0.0.0.0:8000 ``` --- ## 🔍 What This Does **Stack Setup** - Sets up a Django + Django Ninja API backend. citeturn0view1 - Uses **Pydantic AI** to define and run an AI agent powered by a **local Ollama LLM**. citeturn0search0 **Agent Example** - Includes a simple *dice-game* agent that: - Accepts input via API (`message`, `name`). citeturn0view1 - Uses two tools: - `roll_dice()` (random integer). - `get_player_name()` to retrieve user name context. citeturn0view1 - Returns a structured response. **API** - Exposes the `/api/chatbot/roll_a_dice` endpoint. - Docs available at `http://<host>:8000/api/docs`. citeturn0view1 --- ## 💡 Tips & Next Steps ✨ **Authentication** — enabled via Django Ninja JWT; you can enforce auth on your chatbot endpoint. citeturn0view1 ✨ **Vector Memory** — add PostgreSQL + PGVector for conversation history or retrieval. citeturn0search0 ✨ **Customize** — replace the dice logic with real task logic (e.g., search tools or backend actions). --- If you want, I can tailor this further—for example, to include *memory*, *streaming responses*, or *tool chaining*.
gpt-5-1
output the next prompt you would give to complete it for CLIne
Here’s the **next prompt you would give to the CLIne tool** to *complete building your self-hosted AI agent* based on the articles you shared (setting up Django Ninja + Ollama + Pydantic AI + optional memory). This prompt is meant to be *fed directly into a CLIne interactive session*, continuing from the point where the initial project scaffold and API endpoint exist. --- ## 🧠 **CLIne Prompt — Continue Project Setup** **(Paste this as the next instruction to CLIne to finish the agent build and prepare for testing + memory integration):** ``` # 🔹 Finish Django AI Agent Setup # 1) Ensure your Django project is configured with PostgreSQL + PGVector for agent memory cli: add to backend/src/core/settings.py """ # DATABASE DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'myproject', 'USER': 'myprojectuser', 'PASSWORD': 'password', 'HOST': 'localhost', 'PORT': '', } } # Add pgvector extension INSTALLED_APPS += ['django_pgvector'] """ # 2) Install pgvector support cli: run "pip install psycopg2-binary pgvector django-pgvector" # 3) Create migration for pgvector field cli: run "python manage.py makemigrations" cli: run "python manage.py migrate" # 4) Add memory model cli: create file backend/src/chatbot/models.py with """ from django.db import models from pgvector.models import VectorField class ConversationMemory(models.Model): user = models.CharField(max_length=100) query = models.TextField() vector = VectorField(dimensions=1536) created_at = models.DateTimeField(auto_now_add=True) """ # 5) Make and apply migrations cli: run "python manage.py makemigrations chatbot" cli: run "python manage.py migrate" # 6) Update chatbot/api.py to add memory tool cli: apply patch to backend/src/chatbot/api.py """ from .models import ConversationMemory from pydantic_ai import Agent, RunContext @agent.tool def save_memory(ctx: RunContext[str]) -> str: # Save user query embedding to DB from pydantic_ai.providers.ollama import OllamaProvider model = OllamaProvider(base_url=os.getenv('OLLAMA_BASE_URL')) emb = model.embed(ctx.deps) ConversationMemory.objects.create(user=ctx.deps, query=ctx.deps, vector=emb.data) return "memory saved" """ # 7) Register router and docs cli: ensure core/api.py includes """ from chatbot.api import router as chatbot_router api.add_router('/chatbot/', chatbot_router) """ # 8) Start Django server cli: run "python manage.py runserver 0.0.0.0:8000" # ✅ Now test the API # Open browser at http://localhost:8000/api/docs # Try POST /chatbot/roll_a_dice with: # message: "I pick 4" # name: "Alice" # 🎯 Optional: Expand agent to include memory retrieval tool cli: next" ``` --- ### 📌 What this prompt accomplishes ✅ **Database Memory Layer** — Adds PostgreSQL + PGVector so your agent can store/retrieve conversation vectors. citeturn0view1 ✅ **Memory Tool** — Adds a tool to your Pydantic AI agent to save a user query embedding. citeturn0search1 ✅ **Continues CLI Automation** — All steps are written to be runnable directly in CLIne. --- ### 🧪 After running this When the server is running: ✔ Visit `/api/docs` to test `POST /chatbot/roll_a_dice`. citeturn0search0 ✔ You should see the **dice-game** agent working with your Ollama model. citeturn0search0 ✔ Database memory will now persist query embeddings you save with the `save_memory` tool. citeturn0search1 --- If you want, I can also generate a **CLIne prompt to advance to the next article’s part**, e.g., *agent with retrieval (RAG)* and *streaming / async responses*.
gpt-5-1
proceed
Great! Based on the **latest context and tutorials about adding memory/RAG and tool capabilities to a Django-Ollama-Pydantic-AI stack**, here’s the **next CLIne prompt** you should feed into CLIne to continue building out a **Retrieval-Augmented Generation (memory + retrieval) feature** and enhance your AI agent with structured memory and retrieval integration (i.e., RAG). This builds on what we’ve already scaffolded and incorporates memory tooling and retrieval logic inspired by the Part 2 article you referenced. citeturn0reddit25 --- ## 📟 **CLIne Prompt — Add Memory + Retrieval (RAG) to Your AI Agent** ``` # 🧠 Step 1: Add Memory Models & Vector Search # 1) Install pgvector & dependencies cli: run "pip install psycopg2-binary pgvector django-pgvector" # 2) Update Django settings cli: apply patch to backend/src/core/settings.py """ INSTALLED_APPS += [ 'django_pgvector', 'chatbot', ] """ # 3) Create a memory model cli: create file backend/src/chatbot/models.py with """ from django.db import models from pgvector.models import VectorField class MemoryEntry(models.Model): user = models.CharField(max_length=100) query = models.TextField() embedding = VectorField(dimensions=1536) created_at = models.DateTimeField(auto_now_add=True) """ # 4) Make & run migrations cli: run "python manage.py makemigrations chatbot" cli: run "python manage.py migrate" # 🧠 Step 2: Add RAG/Vector Retrieval Tools cli: apply patch to backend/src/chatbot/api.py """ from .models import MemoryEntry from pydantic_ai import RunContext @agent.tool def save_to_memory(ctx: RunContext[str]) -> str: \""" Save user query embedding into MemoryEntry. \""" from pydantic_ai.providers.ollama import OllamaProvider model = OllamaProvider(base_url=os.getenv('OLLAMA_BASE_URL')) emb = model.embed(ctx.deps) # get embedding vector MemoryEntry.objects.create( user=ctx.deps, query=ctx.deps, embedding=emb.data, ) return 'saved' @agent.tool def retrieve_similar(ctx: RunContext[str]) -> str: \""" Given a user query, find similar memory entries and return them. \""" from pydantic_ai.providers.ollama import OllamaProvider model = OllamaProvider(base_url=os.getenv('OLLAMA_BASE_URL')) query_emb = model.embed(ctx.deps) # Simple similarity search (cosine) with pgvector ORM candidates = MemoryEntry.objects.all() # Compute similarity locally ranked = sorted( candidates, key=lambda m: -model.cosine_similarity(query_emb.data, m.embedding), )[:5] return '\\n'.join([f\"{m.query}\" for m in ranked]) """ # 🧠 Step 3: Expose RAG Endpoints cli: apply patch to backend/src/chatbot/api.py """ @router.post('/chat_memory') def memory_search(request, payload: ChatbotMessageSchema): \""" Return agent response augmented with memory retrieval. \""" retrieved = retrieve_similar(payload.message, payload.name) full_prompt = f\"MEMORY:\\n{retrieved}\\nUSER:{payload.message}\" response = chat_with_agent(full_prompt, payload.name) return ChatbotResponseSchema(response=response) """ # 🧠 Step 4: Migrate & Start # Re-migrate DB cli: run "python manage.py makemigrations" cli: run "python manage.py migrate" # Start server cli: run "python manage.py runserver 0.0.0.0:8000" # 🎯 Test in docs: # POST /chatbot/chat_memory # with body: { \"name\": \"Alice\", \"message\": \"Tell me about ...\" } ``` --- ## 🧠 What You Just Added 💾 **Memory Storage:** You now have a Django model (`MemoryEntry`) that stores user queries and their vector embeddings for long-term memory. citeturn0reddit25 🔁 **Retrieval Tools:** Two Pydantic AI tools: - `save_to_memory` — saves embeddings. - `retrieve_similar` — finds and returns similar memory entries for a query (basic vector similarity search). citeturn0reddit25 📡 **Retrieval-Augmented Endpoint:** A new endpoint (`/chat_memory`) that first retrieves relevant memory results and then prompts the agent with them, enabling RAG behavior. This lets the agent ground responses in past interactions or stored knowledge. citeturn0reddit25 --- ## 🧪 Next Suggestions (after you run CLIne) Once the memory + retrieval is in place, you can continue enhancing the agent by: ✔ **Auto-saving conversations:** Trigger `save_to_memory` automatically after each chat. ✔ **Summarization of old chats:** Store concise summaries rather than raw queries. ✔ **Advanced RAG chains:** Integrate external library like LangChain or LlamaIndex for chunked document retrieval. citeturn0search3 --- If you want, I can produce **another CLIne prompt** to: - add **streaming API responses** with `agent.run_stream_sync`, - integrate an asynchronous frontend (e.g., React), - or extend memory to **PDF/docs RAG search**.
gpt-5-1
proceed
Awesome — here’s the **next CLIne prompt you should give to complete the build** by *adding real memory + retrieval + summarization features* to your Django-Ninja + Ollama + Pydantic AI agent. This prompt is based on the **Part 2 memory article** (multi-layered *memory* with pgvector + RAG + summarization) and follows what’s described in the Reddit summary of that article. citeturn0reddit20 --- ## 🧠 **CLIne Prompt — Complete Memory + RAG + Summarization Layer** ``` # 📌 Step 1: Install pgvector and dependencies cli: run "pip install psycopg2-binary pgvector django-pgvector" # 📌 Step 2: Update Django settings cli: apply patch to backend/src/core/settings.py """ INSTALLED_APPS += [ 'django_pgvector', 'chatbot', ] """ # 📌 Step 3: Create memory models with embedding vector + meta cli: create file backend/src/chatbot/models.py with """ from django.db import models from pgvector.models import VectorField class ShortTermMemory(models.Model): session_id = models.CharField(max_length=100) text = models.TextField() created_at = models.DateTimeField(auto_now_add=True) class LongTermMemory(models.Model): user = models.CharField(max_length=100) text = models.TextField() vector = VectorField(dimensions=1536) summary = models.TextField(null=True, blank=True) created_at = models.DateTimeField(auto_now_add=True) """ # 📌 Step 4: Migrate DB cli: run "python manage.py makemigrations chatbot" cli: run "python manage.py migrate" # 📌 Step 5: Add memory + retrieval tools cli: apply patch to backend/src/chatbot/api.py """ from .models import ShortTermMemory, LongTermMemory from pydantic_ai import RunContext @agent.tool def store_short_memory(ctx: RunContext[str]) -> str: ShortTermMemory.objects.create(session_id=ctx.deps, text=ctx.deps) return 'ok' @agent.tool def save_long_memory(ctx: RunContext[str]) -> str: from pydantic_ai.providers.ollama import OllamaProvider model = OllamaProvider(base_url=os.getenv('OLLAMA_BASE_URL')) emb = model.embed(ctx.deps) LongTermMemory.objects.create( user=ctx.deps, text=ctx.deps, vector=emb.data, ) return 'saved' @agent.tool def summarize_long_memory(ctx: RunContext[str]) -> str: import re # basic summarization via model prompt = f\"\"\"Summarize this for memory storage: {ctx.deps}\"\"\" summary = agent.run_sync(prompt).output return summary @agent.tool def retrieve_relevant_memory(ctx: RunContext[str]) -> str: from pydantic_ai.providers.ollama import OllamaProvider model = OllamaProvider(base_url=os.getenv('OLLAMA_BASE_URL')) query_emb = model.embed(ctx.deps) # simple ranking by cosine similarity all_mem = LongTermMemory.objects.all() sorted_mem = sorted( all_mem, key=lambda m: -model.cosine_similarity(query_emb.data, m.vector), )[:5] return '\\n'.join([m.text for m in sorted_mem]) """ # 📌 Step 6: Create RAG-style API endpoint cli: apply patch to backend/src/chatbot/api.py """ @router.post('/chat_rag') def chat_rag(request, payload: ChatbotMessageSchema): # retrieve related long memory related = retrieve_relevant_memory(payload.message, payload.name) prompt = f\"RELEVANT_MEMORY:\\n{related}\\nUser: {payload.message}\" response = chat_with_agent(prompt, payload.name) # optionally store both short & long memory store_short_memory(payload.message, payload.name) save_long_memory(payload.message, payload.name) return ChatbotResponseSchema(response=response) """ # 📌 Step 7: Restart server cli: run "python manage.py runserver 0.0.0.0:8000" # 🧪 Now test: # POST /chatbot/chat_rag with: # { "name": "Alice", "message": "Explain how X works" } ``` --- ### ✅ What This Prompt Adds **📍 Multi-Layer Memory** - **Short-term memory**: Stores session context. - **Long-term memory**: Embeddings stored in PostgreSQL via `pgvector` for RAG. citeturn0reddit20 **📍 Summarization Tool** - Summarizes long memory entries for condensed storage. citeturn0reddit20 **📍 Retrieval Tool** - Retrieves semantically similar long memories using vector similarity. citeturn0reddit20 **📍 RAG Endpoint** - Integrates memory retrieval into the prompt passed to the agent. citeturn0reddit20 --- ### 🚀 Next You Could Add ✔ **Streaming responses** with `agent.run_stream_sync` and a streaming Django endpoint. citeturn0search10 ✔ **Document ingestion** (PDF / TXT) for broader RAG on external corpora. ✔ **Memory summarization scheduler** to condense old chats and reduce vector store size. --- If you want, I can turn this into a **single runnable shell script** or **docker-compose CI/CLIne pipeline**.
gpt-5-1