Showing posts with label AI. Show all posts
Showing posts with label AI. Show all posts

Saturday, February 21, 2026

MySQL + Neo4j for AI Workloads: Why Relational Databases Still Matter

So I figured it was about time I documented how to build persistent memory for AI agents using the databases you already know. Not vector databases - MySQL and Neo4j.

This isn't theoretical. I use this architecture daily, handling AI agent memory across multiple projects. Here's the schema and query patterns that actually work.

The Architecture

AI agents need two types of memory:

  • Structured memory - What happened, when, why (MySQL)
  • Pattern memory - What connects to what (Neo4j)

Vector databases are for similarity search. They're not for tracking workflow state or decision history. For that, you need ACID transactions and proper relationships.

The MySQL Schema

Here's the actual schema for AI agent persistent memory:

-- Architecture decisions the AI made
CREATE TABLE architecture_decisions (
    id INT AUTO_INCREMENT PRIMARY KEY,
    project_id INT NOT NULL,
    title VARCHAR(255) NOT NULL,
    decision TEXT NOT NULL,
    rationale TEXT,
    alternatives_considered TEXT,
    status ENUM('accepted', 'rejected', 'pending') DEFAULT 'accepted',
    decided_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    tags JSON,
    INDEX idx_project_date (project_id, decided_at),
    INDEX idx_status (status)
) ENGINE=InnoDB;

-- Code patterns the AI learned
CREATE TABLE code_patterns (
    id INT AUTO_INCREMENT PRIMARY KEY,
    project_id INT NOT NULL,
    category VARCHAR(50) NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    code_example TEXT,
    language VARCHAR(50),
    confidence_score FLOAT DEFAULT 0.5,
    usage_count INT DEFAULT 0,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_project_category (project_id, category),
    INDEX idx_confidence (confidence_score)
) ENGINE=InnoDB;

-- Work session tracking
CREATE TABLE work_sessions (
    id INT AUTO_INCREMENT PRIMARY KEY,
    session_id VARCHAR(255) UNIQUE NOT NULL,
    project_id INT NOT NULL,
    started_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    ended_at DATETIME,
    summary TEXT,
    context JSON,
    INDEX idx_project_session (project_id, started_at)
) ENGINE=InnoDB;

-- Pitfalls to avoid (learned from mistakes)
CREATE TABLE pitfalls (
    id INT AUTO_INCREMENT PRIMARY KEY,
    project_id INT NOT NULL,
    category VARCHAR(50),
    title VARCHAR(255) NOT NULL,
    description TEXT,
    how_to_avoid TEXT,
    severity ENUM('critical', 'high', 'medium', 'low'),
    encountered_count INT DEFAULT 1,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_project_severity (project_id, severity)
) ENGINE=InnoDB;

Foreign keys. Check constraints. Proper indexing. This is what relational databases are good at.

Query Patterns

Here's how you actually query this for AI agent memory:

-- Get recent decisions for context
SELECT title, decision, rationale, decided_at
FROM architecture_decisions
WHERE project_id = ?
  AND decided_at > DATE_SUB(NOW(), INTERVAL 30 DAY)
ORDER BY decided_at DESC
LIMIT 10;

-- Find high-confidence patterns
SELECT category, name, description, code_example
FROM code_patterns
WHERE project_id = ?
  AND confidence_score >= 0.80
ORDER BY usage_count DESC, confidence_score DESC
LIMIT 20;

-- Check for known pitfalls before implementing
SELECT title, description, how_to_avoid
FROM pitfalls
WHERE project_id = ?
  AND category = ?
  AND severity IN ('critical', 'high')
ORDER BY encountered_count DESC;

-- Track session context across interactions
SELECT context
FROM work_sessions
WHERE session_id = ?
ORDER BY started_at DESC
LIMIT 1;

These are straightforward SQL queries. EXPLAIN shows index usage exactly where expected. No surprises.

The Neo4j Layer

MySQL handles the structured data. Neo4j handles the relationships:

// Create nodes for decisions
CREATE (d:Decision {
  id: 'dec_123',
  title: 'Use FastAPI',
  project_id: 1,
  embedding: [0.23, -0.45, ...]  // Vector for similarity
})

// Create relationships
CREATE (d1:Decision {id: 'dec_123', title: 'Use FastAPI'})
CREATE (d2:Decision {id: 'dec_45', title: 'Used Flask before'})
CREATE (d1)-[:SIMILAR_TO {score: 0.85}]->(d2)
CREATE (d1)-[:CONTRADICTS]->(d3:Decision {title: 'Avoid frameworks'})

// Query: Find similar past decisions
MATCH (current:Decision {id: $decision_id})
MATCH (current)-[r:SIMILAR_TO]-(similar:Decision)
WHERE r.score > 0.80
RETURN similar.title, r.score
ORDER BY r.score DESC

// Query: What outcomes followed this pattern?
MATCH (d:Decision)-[:LEADS_TO]->(o:Outcome)
WHERE d.title CONTAINS 'Redis'
RETURN d.title, o.type, o.success_rate

How They Work Together

The flow looks like this:

  1. AI agent generates content or makes a decision
  2. Store structured data in MySQL (what, when, why, full context)
  3. Generate embedding, store in Neo4j with relationships to similar items
  4. Next session: Neo4j finds relevant similar decisions
  5. MySQL provides the full details of those decisions

MySQL is the source of truth. Neo4j is the pattern finder.

Why Not Just Vector Databases?

I've seen teams try to build AI agent memory with just Pinecone or Weaviate. It doesn't work well because:

Vector DBs are good for:

  • Finding documents similar to a query
  • Semantic search (RAG)
  • "Things like this"

Vector DBs are bad for:

  • "What did we decide on March 15th?"
  • "Show me decisions that led to outages"
  • "What's the current status of this workflow?"
  • "Which patterns have confidence > 0.8 AND usage_count > 10?"

Those queries need structured filtering, joins, and transactions. That's relational database territory.

MCP and the Future

The Model Context Protocol (MCP) is standardizing how AI systems handle context. Early MCP implementations are discovering what we already knew: you need both structured storage and graph relationships.

MySQL handles the MCP "resources" and "tools" catalog. Neo4j handles the "relationships" between context items. Vector embeddings are just one piece of the puzzle.

Production Notes

Current system running this architecture:

  • MySQL 8.0, 48 tables, ~2GB data
  • Neo4j Community, ~50k nodes, ~200k relationships
  • Query latency: MySQL <10ms, Neo4j <50ms
  • Backup: Standard mysqldump + neo4j-admin dump
  • Monitoring: Same Percona tools I've used for years

The operational complexity is low because these are mature databases with well-understood operational patterns.

Too Much Work? Let AI Build It For You

Look, I get it. This is a lot of schema to set up, a lot of queries to write, a lot of moving parts.

Here's the thing: you don't have to type it all yourself. Copy the schema above, paste it into Claude Code or Kimi CLI, and tell it what you want to build. The AI will generate the Python code, the connection handling, the query patterns - all of it.

If you want to understand what's happening under the hood, start here:

Building a Simple MCP Server in Python

Then let your AI tool do the heavy lifting. That's literally what I did. The schema is mine, the architecture decisions are mine, but the implementation? Claude wrote most of it while I watched and corrected.

Use the tools. That's what they're for.

When to Use What

Use CaseDatabase
Workflow state, decisions, audit trailMySQL/PostgreSQL
Pattern detection, similarity, relationshipsNeo4j
Semantic document search (RAG)Vector DB (optional)

Start with MySQL for state. Add Neo4j when you need pattern recognition. Only add vector DBs if you're actually doing semantic document retrieval.

Summary

AI agents need persistent memory. Not just embeddings in a vector database - structured, relational, temporal memory with pattern recognition.

MySQL handles the structured state. Neo4j handles the graph relationships. Together they provide what vector databases alone cannot.

Don't abandon relational databases for AI workloads. Use the right tool for each job, which is using both together.

For more on the AI agent perspective on this architecture, see the companion post on 3k1o.

Tuesday, December 2, 2025

Open Source AI Models Building a Development Team

The Question We're Finally Asking

For years we've debated: Can AI replace software engineers? The question was always a bit theatrical. The real question—the one that actually matters—is a different one entirely: Can AI augment the engineering process in ways that make better code happen faster?

I think we're closer to a practical answer than we realize.

There's a concept that's been brewing in the open source and commercial AI spaces, one that mirrors something we've known in software engineering for decades: diverse perspectives catch what homogeneous ones miss. Single engineers make mistakes. Teams catch them. The question becomes: can we build a team out of AI models, each with distinct expertise, and orchestrate them to produce better outcomes?

I've been working on a proof of concept with this team-based approach. I started back in Aug 2025 and picked it up again recently. It's a component of my broader ApocryiaAI framework (apocryia.com will be the public facing frontend). For this POC, what I've built is a set of Python scripts that integrate with our private backend infrastructure and Percona database, orchestrating local open source models to work as a unified team. They collaborate to solve whatever task is requested, each bringing specialized perspective and expertise. All of this team communication is visible in real-time via a private IRC server—allowing me to observe the interactions, understand their reasoning process, and even interject during the workflow when needed. What I'm describing here is specifically that IRC-based autonomous development team. It's running, it's working, and the results are worth thinking about. Yes, it's still a proof of concept, and I'm the first to admit that. But this concept supports what I try to do for my team and myself: work smarter, not harder. This isn't AI replacing developers. It's AI working alongside developers, providing diverse opinions across different points of view and models.

The Architecture: A Team, Not a Model

The architecture is deceptively simple but conceptually important. Instead of throwing a single large language model at a development task and hoping it produces good code, we've created four specialized roles:

  1. ProjectManager (qwen2.5-coder) - Creates detailed implementation plans
  2. Developer (deepseek-coder-v2) - Generates complete, runnable code
  3. Reviewer (apocryiaai-unified - A private model I trained with MIT business and computer science grad-level data) - Evaluates code for correctness and business logic
  4. Lucifer (mistral) - Challenges everything, finds edge cases and flaws

Each model is chosen specifically for that role. The ProjectManager isn't trying to write code—it's thinking about requirements, dependencies, and success criteria. The Developer is optimized for code generation. The Reviewer has business-level understanding. And Lucifer's job is to be difficult.

This is not novel in human teams. It's basic team dynamics. What's novel is making it work with open source models that fit in a local machine.


The Workflow: Iteration With Purpose

Here's where it gets interesting. The workflow doesn't end with code generation. It's iterative:

Cycle 1:

  • Developer writes initial code
  • Reviewer evaluates it (rating it 1-10)
  • Lucifer challenges the code with critical analysis

Decision Logic:

  • If Reviewer gives it 8+/10 AND Lucifer says it's acceptable → Approve
  • If either agent rejects it → Trigger refinement

Cycle 2 (if needed):

  • Developer refines code based on specific feedback from both agents
  • Reviewer re-evaluates the refined code
  • Lucifer reviews the improvements

Real Example: Hello World Task

I tested this with a specific task: "Create a Python script that prints 'Hello World' a configurable number of times based on passed input (like: hello_world.py -X 3 would print it 3 times)."


Cycle 1 - Initial Development:

The Developer generated:

 import sys


def hello(times):

    for i in range(times):

        print("Hello World")


if __name__ == "__main__":

    if len(sys.argv) > 1:

        try:

            times = int(sys.argv[1])

            hello(times)

        except ValueError:

            print("Please enter a valid integer.")

    else:

        print("Usage: python hello_world.py <number of times>")

The Reviewer evaluated it: Rating: 7/10 with feedback:

"The code works but is missing proper argument handling. It uses positional arguments instead of flags. Should support -X or --number flag format. Error handling could be more robust."


The Lucifer agent challenged it:

"This implementation is naive. What happens if someone passes -5 or 1000000? No bounds checking. The positional argument approach is error-prone. Consider using argparse for professional flag handling."


Decision: Not approved. 7/10 < 8/10 threshold. Trigger refinement.


Cycle 2 - Code Refinement:


Based on both feedbacks, the Developer refined the code:

import sys

import argparse


def hello(times):

    if times <= 0:

        print("Error: Number must be positive")

        return False

    if times > 1000:

        print("Error: Maximum 1000 iterations allowed")

        return False


    for i in range(times):

        print("Hello World")

    return True


if __name__ == "__main__":

    parser = argparse.ArgumentParser(description='Print Hello World N times')

    parser.add_argument('-X', '--number', type=int, required=True,

                       help='Number of times to print (1-1000)')


    try:

        args = parser.parse_args()

        success = hello(args.number)

        sys.exit(0 if success else 1)

    except SystemExit:

        raise

    except Exception as e:

        print(f"Error: {e}")

        sys.exit(1)

The Reviewer re-evaluated: Rating: 9/10

"Significant improvement. Now uses proper argparse, validates inputs, has bounds checking, explicit error messages. Professional argument handling. Only minor suggestion: consider logging instead of print for errors."


The Lucifer agent reviewed: Approved

"Much better. Edge cases are handled. Bounds checking prevents abuse. Error messages are clear. No issues with this implementation."

Decision: Approved. Both agents agree. Deploy.


Real iteration. Real improvement. From 7→9 rating. Visible in the logs.


Another Example: "Why is the Sky Blue?"

This example shows the system handling non-coding tasks—explanatory content rather than utility code.

Task: "Write a 50 word sentence about why the sky is blue"


Cycle 1 - Initial Generation:

The Developer generated:

def explain_sky_blue():

    """

    Returns an explanation of why the sky appears blue.

    """

    return "The sky appears blue because of a phenomenon called Rayleigh scattering..."


if __name__ == "__main__":

    print(explain_sky_blue())

The Reviewer evaluated: Rating: 10/10

"Well-structured code with clear documentation and correct scientific explanation. Excellent."


The Lucifer agent challenged:

"As Lucifer, here are my findings: While functionally correct, the explanation lacks depth about wavelength specifics. The code structure is good but could benefit from type hints for better Python practices."

Decision: Despite Reviewer's perfect score, Lucifer insisted on refinement. System triggered improvement.


Cycle 2 - Code Refinement:

Based on Lucifer's feedback, Developer improved:

def why_is_the_sky_blue() -> str:

    """

    Explain the reason behind the sky appearing blue due to Rayleigh scattering and

    other related phenomena.


    Returns:

        str: A detailed explanation of why the sky appears blue, including information

             about Rayleigh scattering and its role in color dispersion.

    """

    return (

        "The sky appears blue because of a phenomenon called Rayleigh scattering. "

        "When sunlight enters Earth's atmosphere, shorter wavelength (blue) light is "

        "scattered more by air molecules than longer wavelength (red/yellow) light. "

        "This causes the blue color we see in the sky."

    )


if __name__ == "__main__":

    print(why_is_the_sky_blue())

The Reviewer re-evaluated: Rating: 8/10

"Improved significantly. Type hints added, docstring is comprehensive, explanation is clear and scientifically accurate."


The Lucifer agent approved:

"Much better. The technical details about wavelength are now clear. Code follows Python best practices. This is a solid implementation."


Decision: Both agents approve. Task completed.

Verified Output:

The sky appears blue because of a phenomenon called Rayleigh scattering. When sunlight

enters Earth's atmosphere, shorter wavelength (blue) light is scattered more by air

molecules than longer wavelength (red/yellow) light. This causes the blue color we see

in the sky.

What This Example Shows:

  • The system handles diverse task types (not just utilities)
  • Even a "perfect" 10/10 from Reviewer doesn't bypass the approval gate
  • Lucifer's critical eye catches improvements that pure quality metrics miss
  • Type hints, docstrings, and clarity matter to the team
  • Code goes through refinement even when it works, pushing toward excellence

Why This Matters: The Approval Problem

Here's something most AI code generation tools gloss over: How do you know when code is actually ready?

Most systems have a single decision gate: "Is this acceptable yes/no?" That's the wrong question. The better question is: "Have multiple perspectives—operating from different priorities and expertise—agreed this is good?"

The approval logic in ApocryiaAI requires both the Reviewer and Lucifer to explicitly approve. Not a loose "looks fine" but explicit agreement:

  • Reviewer must give it a rating of 8/10 or higher, OR explicitly say "approved/looks good"
  • Lucifer must explicitly say "no issues/acceptable/approved"

This creates a natural tension. The Reviewer wants the code to work correctly and follow best practices. Lucifer wants to find what's wrong. Code that satisfies both perspectives has genuinely passed multiple tests.


Why Explicit Approval Matters: A Cautionary Tale

This is harder than you'd think. We initially had a system that used loose keyword matching for approval. Words like "looks good" would trigger approval even when the model was just introducing its analysis. Here's an example of what went wrong:


Initial (Broken) System:

Lucifer: "In order to provide a comprehensive review, I'll delve deeper into

the edge cases. The input validation looks good in principle..."

System detected: "looks good" → APPROVED ✅ (WRONG!)

Lucifer was about to identify critical issues, but the system approved the code prematurely because it detected the phrase "looks good" mid-sentence as the model was introducing its analysis.


Fixed System: Now we require explicit approval phrases only when they appear as standalone conclusions:

Lucifer: "After thorough analysis, no issues found. This implementation

is acceptable and ready for deployment."

System detected: "no issues found" + "acceptable" → APPROVED ✅ (CORRECT!)

The difference? We distinguish between:

  • Positive mentions in analysis: "This approach looks good, but..." (not approval)
  • Explicit approval conclusions: "No issues. This is approved." (approval)

This seemingly small change prevents false positives where models talk about good code while actually criticizing it.


The Practical Side: GPU Memory and Open Source Realities

Here's something I haven't seen discussed enough: Open source models sitting in GPU memory between tasks is wasteful.

We added model unloading via Ollama API calls. After each agent completes its task, we explicitly unload its model from GPU memory. This keeps the system usable on real hardware, not just theoretical deployments.

This is a small detail but reveals something important: we're not building a research project. We're trying to make something that actually runs on machines people have.


Model Selection: Why Each Role Gets Its Specific Model

The models we're using:

ProjectManager: qwen2.5-coder:7b

  • Lightweight (7B parameters) so planning doesn't bottleneck the workflow
  • Excels at breaking tasks into structured plans with dependencies
  • When asked to plan the "Hello World" task, it produced:
  • Clear understanding of requirements (handle variable counts, validate input)
  • Step-by-step plan (arg parsing → validation → output loop)
  • Potential issues (negative numbers, bounds checking)
  • Success criteria (clean exit codes, proper error messages)
  • Not wasted generating code—just strategic thinking.

Developer: deepseek-coder-v2:latest

  • Largest and most specialized for code generation in our lineup
  • Produces complete, runnable code blocks on first pass
  • Handles complex scaffolding (argparse setup, error handling, proper exit codes)
  • When asked to refine based on feedback, actually understands what "add bounds checking" means and implements it correctly

Reviewer: apocryiaai-unified:latest

  • Rare combination: technical correctness evaluation + business logic understanding
  • Doesn't just say "this code works" but thinks about use cases and edge cases
  • Example feedback on our script: "Professional argument handling. Only minor suggestion: consider logging instead of print for errors."
  • That's not just technical critique—that's production thinking

Lucifer: mistral:latest

  • Sharp critical analysis without being a code expert
  • Asks hard questions: "What happens if someone passes -5 or 1000000?"
  • Thinks about failure modes and abuse cases
  • Doesn't get lost in syntax—focuses on fundamental flaws

All open source. All fit on consumer hardware. None require cloud APIs.


Why This Mix Works Better Than a Single Model

A single large model trying all four roles would either:

  1. Excel at one role, mediocre at others
  2. Produce bloated, slow responses trying to cover everything
  3. Approve its own code (alignment problem—it defends its earlier decisions)

With specialized models:

  • Planning is fast and focused
  • Code generation leverages the best tool available
  • Review is genuinely independent critique
  • Lucifer isn't trying to write code—just finding problems

What Works. What Doesn't. Honest Assessment.

What Actually Works:

  • The iterative refinement genuinely improves code. 7→9 isn't a coincidence.
  • Diverse perspectives catch real issues. When Lucifer finds edge cases, they're usually valid.
  • The approval mechanism creates a quality gate that's harder to game than single-model evaluation.
  • Locally-run models mean no API costs, no privacy concerns, no rate limiting.

What's Still Hard:

  • Computational cost: 4+ LLM calls per task. For trivial tasks, this is overkill.
  • Model reliability: The system depends on models actually being critical and honest. If a model learns to approve things to move forward, the whole thing breaks.
  • Specification problems remain. If the initial requirement is fundamentally wrong, refinement helps but doesn't fix it.
  • Scaling: One successful task doesn't prove it scales across diverse problem types.

What Needs More Data:

  • Does 2 cycles converge on actually better code, or is that specific to this task?
  • What's the failure rate on production deployments?
  • At what complexity level does the overhead justify the quality improvement?
  • How do these systems perform on different categories of problems (utility scripts, system programming, web backends)?

The Bigger Question: What's This For?

If you're thinking "this seems like a lot of machinery for hello_world.py," you're right.

The value emerges at scale and complexity. Consider:

  1. Team Augmentation - Your actual team has a senior engineer, a junior, and a critical reviewer. Adding an automated adversarial agent (Lucifer) that catches what you'd miss? That scales.
  2. Knowledge Preservation - When the critical feedback is logged, you can learn why code was rejected. Over time, you understand the approval patterns. That's institutional knowledge.
  3. Specification Evolution - The PM learning mechanism captures when critical issues would have been caught by better specifications. Feed that back to requirements.
  4. Local Autonomy - No cloud dependency. No API costs. You control your development pipeline.

The right comparison isn't "can this replace engineers" but "can this augment the engineering process in ways that produce better outcomes per unit of human effort?"

On that question, the early data looks promising.


The Open Source Angle

Here's why open source models matter for this:

You're not dependent on a commercial company's moods about pricing, availability, or model changes. You're not sending your code to external APIs. You're not at risk of waking up to a terms-of-service change that affects your workflow.

The community around Ollama, the models themselves (qwen, deepseek, mistral), and the frameworks we're using are all genuinely open. You can inspect them. You can run them on your hardware. You can contribute back.

That's different from cloud-based AI. It's also different from the single-model approach most people take. It's team-based thinking applied to open source infrastructure.


Where This Goes

The next phase is validation. More diverse tasks. Different problem types. Real production code, not just examples.

We need to understand:

  • Does the approval mechanism hold up when models encounter truly novel situations?
  • How does cost-per-task scale as complexity increases?
  • Can the PM learning feedback actually improve specification quality over time?
  • What happens when the team disagrees and can't converge?
  • I have hypotheses on these. But hypotheses aren't evidence. Evidence comes from running it.

What I like the most about this: 

YOU can do it also. You can apply the same concepts to whatever architecture and infrastructure you want. Don't want an IRC server, ok, no problem, I wanted insights into what the team was doing, but you don't have to. Do you want more team members, ok sure... The concept is based on you using AI to help you work smarter, not harder. 

The Philosophy

What we're experimenting with here is: building development automation with tools you control, from models you understand, running on hardware you own.

That matters more than people realize.

My AI team concept isn't trying to replace developers or even me. It's trying to be the kind of colleague that works with me and who catches bugs, asks hard questions, and pushes back on mediocre code. That colleague exists in every good team. Automation is making it possible to have that colleague always present.

Whether this specific approach is the right one, I'm not sure yet. But the direction—toward distributed expertise, adversarial review, and local autonomy—that direction feels right.

The code is working. The team is functional. The quality improvements are measurable.

Now we find out if it scales, the real work now begins....


Thursday, July 3, 2025

MySQL Analysis: With an AI-Powered CLI Tool

MySQL Analysis: With an AI-Powered CLI Tool

As DBAs with MySQL we often live on a Linux terminal window. We also enjoy free options when available. This post shows an approach that allows us to stay on our terminal window and still use an AI-powered tool. You can update to use other direct AI providers but I set this example up to use aimlapi.com as it brings multiple AI models to your terminal for free with limited use or very low cost for more testing.

Note: I'm not a paid spokesperson for AIMLAPI or anything - this is just an easy example to highlight the idea.

The Problem

You're looking at a legacy database with hundreds of tables, each with complex relationships and questionable design decisions made years ago. The usual process involves:

  • Manual schema inspection
  • Cross-referencing documentation (if it exists)
  • Running multiple EXPLAIN queries
  • Consulting best practice guides
  • Seeking second opinions from colleagues

This takes time and you often miss things.

A CLI-Based Approach

We can take advantage of AI directly from our CLI and do numerous things. Helping with MySQL analysis is just one example of how this approach can work with our daily database tasks. By combining MySQL's native capabilities with AI models, all accessible through a simple command-line interface, we can get insights without leaving our terminal. AIMLAPI provides free access to over 100 AI models with limited use, making this approach accessible. For heavier testing, the costs remain very reasonable.

The Tool: AIMLAPI CLI

So here's a bash script that provides access to 100+ AI models through a single interface:

#!/bin/bash
# AIMLAPI CLI tool with access to 100+ AI models
# File: ~/.local/bin/aiml

# Configuration
DEFAULT_MODEL=${AIMLAPI_DEFAULT_MODEL:-"gpt-4o"}
MAX_TOKENS=${AIMLAPI_MAX_TOKENS:-2000}
TEMPERATURE=${AIMLAPI_TEMPERATURE:-0.7}
BASE_URL="https://api.aimlapi.com"
ENDPOINT="v1/chat/completions"

# Color codes for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# Function to print colored output
print_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
print_error() { echo -e "${RED}[ERROR]${NC} $1"; }
print_model() { echo -e "${PURPLE}[MODEL]${NC} $1"; }

# Popular model shortcuts
declare -A MODEL_SHORTCUTS=(
    # OpenAI Models
    ["gpt4"]="gpt-4o"
    ["gpt4o"]="gpt-4o"
    ["gpt4mini"]="gpt-4o-mini"
    ["o1"]="o1-preview"
    ["o3"]="openai/o3-2025-04-16"
    
    # Claude Models  
    ["claude"]="claude-3-5-sonnet-20241022"
    ["claude4"]="anthropic/claude-sonnet-4"
    ["opus"]="claude-3-opus-20240229"
    ["haiku"]="claude-3-5-haiku-20241022"
    ["sonnet"]="claude-3-5-sonnet-20241022"
    
    # DeepSeek Models
    ["deepseek"]="deepseek-chat"
    ["deepseek-r1"]="deepseek/deepseek-r1"
    ["reasoner"]="deepseek-reasoner"
    
    # Google Models
    ["gemini"]="gemini-2.0-flash"
    ["gemini2"]="gemini-2.0-flash"
    ["gemini15"]="gemini-1.5-pro"
    
    # Meta Llama Models
    ["llama"]="meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo"
    ["llama405b"]="meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo"
    
    # Qwen Models
    ["qwen"]="qwen-max"
    ["qwq"]="Qwen/QwQ-32B"
    
    # Grok Models
    ["grok"]="x-ai/grok-beta"
    ["grok3"]="x-ai/grok-3-beta"
    
    # Specialized Models
    ["coder"]="Qwen/Qwen2.5-Coder-32B-Instruct"
)

# Function to resolve model shortcuts
resolve_model() {
    local model="$1"
    if [[ -n "${MODEL_SHORTCUTS[$model]}" ]]; then
        echo "${MODEL_SHORTCUTS[$model]}"
    else
        echo "$model"
    fi
}

# Function to create JSON payload using jq for proper escaping
create_json_payload() {
    local model="$1"
    local prompt="$2"
    local system_prompt="$3"
    
    local temp_file=$(mktemp)
    echo "$prompt" > "$temp_file"
    
    if [ -n "$system_prompt" ]; then
        jq -n --arg model "$model" \
              --rawfile prompt "$temp_file" \
              --arg system "$system_prompt" \
              --argjson max_tokens "$MAX_TOKENS" \
              --argjson temperature "$TEMPERATURE" \
              '{
                model: $model,
                messages: [{role: "system", content: $system}, {role: "user", content: $prompt}],
                max_tokens: $max_tokens,
                temperature: $temperature
              }'
    else
        jq -n --arg model "$model" \
              --rawfile prompt "$temp_file" \
              --argjson max_tokens "$MAX_TOKENS" \
              --argjson temperature "$TEMPERATURE" \
              '{
                model: $model,
                messages: [{role: "user", content: $prompt}],
                max_tokens: $max_tokens,
                temperature: $temperature
              }'
    fi
    
    rm -f "$temp_file"
}

# Function to call AIMLAPI
call_aimlapi() {
    local prompt="$1"
    local model="$2"
    local system_prompt="$3"
    
    if [ -z "$AIMLAPI_API_KEY" ]; then
        print_error "AIMLAPI_API_KEY not set"
        return 1
    fi
    
    model=$(resolve_model "$model")
    
    local json_file=$(mktemp)
    create_json_payload "$model" "$prompt" "$system_prompt" > "$json_file"
    
    local response_file=$(mktemp)
    local http_code=$(curl -s -w "%{http_code}" -X POST "${BASE_URL}/${ENDPOINT}" \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer $AIMLAPI_API_KEY" \
        --data-binary @"$json_file" \
        -o "$response_file")
    
    if [ "$http_code" -ne 200 ] && [ "$http_code" -ne 201 ]; then
        print_error "HTTP Error $http_code"
        cat "$response_file" >&2
        rm -f "$json_file" "$response_file"
        return 1
    fi
    
    local content=$(jq -r '.choices[0].message.content // empty' "$response_file" 2>/dev/null)
    
    if [ -z "$content" ]; then
        content=$(jq -r '.choices[0].text // .message.content // .content // empty' "$response_file" 2>/dev/null)
    fi
    
    if [ -z "$content" ]; then
        local error_msg=$(jq -r '.error.message // .error // empty' "$response_file" 2>/dev/null)
        if [ -n "$error_msg" ]; then
            echo "API Error: $error_msg"
        else
            echo "Error: Unable to parse response from API"
        fi
    else
        echo "$content"
    fi
    
    rm -f "$json_file" "$response_file"
}

# Main function with argument parsing
main() {
    local model="$DEFAULT_MODEL"
    local system_prompt=""
    local prompt=""
    local piped_input=""
    
    if [ -p /dev/stdin ]; then
        piped_input=$(cat)
    fi
    
    # Parse arguments
    while [[ $# -gt 0 ]]; do
        case $1 in
            -m|--model)
                model="$2"
                shift 2
                ;;
            -s|--system)
                system_prompt="$2"
                shift 2
                ;;
            *)
                prompt="$*"
                break
                ;;
        esac
    done
    
    # Handle input
    if [ -n "$piped_input" ] && [ -n "$prompt" ]; then
        prompt="$prompt

Here is the data to analyze:
$piped_input"
    elif [ -n "$piped_input" ]; then
        prompt="Please analyze this data:

$piped_input"
    elif [ -z "$prompt" ]; then
        echo "Usage: aiml [options] \"prompt\""
        echo "       command | aiml [options]"
        exit 1
    fi
    
    local resolved_model=$(resolve_model "$model")
    print_info "Querying $resolved_model..."
    
    local response=$(call_aimlapi "$prompt" "$model" "$system_prompt")
    
    echo ""
    print_model "Response from $resolved_model:"
    echo "----------------------------------------"
    echo "$response" 
    echo "----------------------------------------"
}

# Check dependencies
check_dependencies() {
    command -v curl >/dev/null 2>&1 || { print_error "curl required but not installed."; exit 1; }
    command -v jq >/dev/null 2>&1 || { print_error "jq required but not installed."; exit 1; }
}

check_dependencies
main "$@"

This script provides access to various AI models through simple shortcuts like claude4, gpt4, grok3, etc. AIMLAPI offers free access with limited use to all these models, with reasonable costs for additional testing. Good for DBAs who want to experiment without breaking the budget.

Script Features

The script includes comprehensive help. Here's what aiml --help shows:

AIMLAPI CLI Tool - Access to 100+ AI Models
==============================================
Usage: aiml [OPTIONS] "prompt"
       command | aiml [OPTIONS]
Core Options:
  -m, --model MODEL         Model to use (default: gpt-4o)
  -t, --tokens NUMBER       Max tokens (default: 2000)
  -T, --temperature FLOAT   Temperature 0.0-2.0 (default: 0.7)
  -s, --system PROMPT       System prompt for model behavior
Input/Output Options:
  -f, --file FILE           Read prompt from file
  -o, --output FILE         Save response to file
  -r, --raw                 Raw output (no formatting/colors)
Information Options:
  -l, --list               List popular model shortcuts
  --get-models             Fetch all available models from API
  -c, --config             Show current configuration
  -v, --verbose            Enable verbose output
  -d, --debug              Show debug information
  -h, --help               Show this help
Basic Examples:
  aiml "explain quantum computing"
  aiml -m claude "review this code"
  aiml -m deepseek-r1 "solve this math problem step by step"
  aiml -m grok3 "what are the latest AI developments?"
  aiml -m coder "optimize this Python function"
Pipe Examples:
  ps aux | aiml "analyze these processes"
  netstat -tuln | aiml "explain these network connections"
  cat error.log | aiml -m claude "diagnose these errors"
  git diff | aiml -m coder "review these code changes"
  df -h | aiml "analyze disk usage and suggest cleanup"
File Operations:
  aiml -f prompt.txt -o response.txt
  aiml -f large_dataset.csv -m llama405b "analyze this data"
  cat script.py | aiml -m coder -o review.md "code review"
Model Categories & Shortcuts:
  OpenAI:     gpt4, gpt4mini, o1, o3
  Claude:     claude, opus, haiku, sonnet, claude4
  DeepSeek:   deepseek, deepseek-r1, reasoner
  Google:     gemini, gemini2, gemma
  Meta:       llama, llama3, llama4, llama405b
  Qwen:       qwen, qwen2, qwq
  Grok:       grok, grok3, grok3mini
  Coding:     coder, codestral
Advanced Usage:
  aiml -m claude -s "You are a security expert" "audit this code"
  aiml -m deepseek-r1 -t 3000 "complex reasoning task"
  aiml -v -m grok3 "verbose query with detailed logging"
  aiml -d "debug mode to troubleshoot API issues"
Model Discovery:
  aiml -l                   # Show popular shortcuts
  aiml --get-models         # Fetch all available models from API
  aiml --config             # Show current configuration
Environment Variables:
  AIMLAPI_API_KEY          - Your AIMLAPI key (required)
  AIMLAPI_DEFAULT_MODEL    - Default model (optional)
  AIMLAPI_MAX_TOKENS       - Default max tokens (optional)
  AIMLAPI_TEMPERATURE      - Default temperature (optional)
Pro Tips:
  • Use coder for programming tasks and code reviews
  • Use deepseek-r1 for complex reasoning and math problems
  • Use claude4 for detailed analysis and long-form content
  • Use grok3 for current events and real-time information
  • Use gpt4mini for quick questions to save on API costs
  • Pipe command output directly: command | aiml "analyze this"
  • Use -v for verbose output to see what model is being used
  • Use --get-models to see all 100+ available models

Access to 100+ AI models through one simple interface!

Example: The City Table

Here's how this works with an actual MySQL table analysis. I'll analyze a City table from the classic World database (from https://dev.mysql.com/doc/index-other.html Example Databases) using three different AI models.

The Command

mysql --login-path=klarson world -e "show create table City\G" | \
aiml --model claude4 "Using a MySQL expert point of view analyze this table"

This command:

  1. Extracts the table structure from MySQL
  2. Pipes it to our AI tool
  3. Gets analysis from Claude Sonnet 4

Results

Claude Sonnet 4 Analysis

Claude 4 provided a well-organized analysis:

Strengths:

  • Proper AUTO_INCREMENT primary key for InnoDB efficiency
  • Foreign key constraints maintaining referential integrity
  • Appropriate indexing strategy for common queries

Issues Found:

  • Storage Inefficiency: Using CHAR(35) for variable-length city names wastes space
  • Character Set Limitation: latin1 charset inadequate for international city names
  • Suboptimal Indexing: name_key index only covers first 5 characters

Suggested Improvements:

-- Claude's suggested optimized structure
CREATE TABLE `City` (
  `ID` int NOT NULL AUTO_INCREMENT,
  `Name` VARCHAR(35) NOT NULL,
  `CountryCode` CHAR(3) NOT NULL,
  `District` VARCHAR(20) NOT NULL,
  `Population` int UNSIGNED NOT NULL DEFAULT '0',
  PRIMARY KEY (`ID`),
  KEY `CountryCode` (`CountryCode`),
  KEY `name_idx` (`Name`),
  KEY `country_name_idx` (`CountryCode`, `Name`),
  KEY `population_idx` (`Population`),
  CONSTRAINT `city_ibfk_1` FOREIGN KEY (`CountryCode`) 
    REFERENCES `Country` (`Code`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4080 
  DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Grok 3 Beta Analysis (The Comprehensive Reviewer)

mysql --login-path=klarson world -e "show create table City\G" | \
aiml --model grok3 "Using a MySQL expert point of view analyze this table"

Grok 3 provided an exhaustive, detailed analysis covering:

Technical Deep Dive:

  • Performance Impact Analysis: Evaluated the partial index limitation in detail
  • Storage Engine Benefits: Confirmed InnoDB choice for transactional integrity
  • Data Type Optimization: Detailed space-saving recommendations with examples

Advanced Considerations:

  • Full-text indexing recommendations for city name searches
  • Character set migration procedures with specific commands
  • Partitioning strategies for large datasets

Implementation Guidelines:

-- Grok's character set migration suggestion
ALTER TABLE City CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- Full-text index recommendation
ALTER TABLE City ADD FULLTEXT INDEX name_fulltext (Name);

GPT-4o Analysis (The Practical Advisor)

mysql --login-path=klarson world -e "show create table City\G" | \
aiml --model gpt4 "Using a MySQL expert point of view analyze this table"

GPT-4o focused on practical, immediately actionable improvements:

Pragmatic Assessment:

  • Validated the AUTO_INCREMENT primary key design
  • Confirmed foreign key constraint benefits for data integrity
  • Identified character set limitations for global applications

Ready-to-Implement Suggestions:

  • Specific ALTER TABLE commands for immediate optimization
  • Query pattern analysis recommendations
  • Index effectiveness evaluation criteria

The Power of Multi-Model Analysis

What makes this approach valuable is getting three distinct perspectives:

  1. Claude 4: Provides detailed, structured analysis with concrete code solutions
  2. Grok 3: Offers comprehensive coverage with advanced optimization strategies
  3. GPT-4o: Delivers practical, immediately actionable recommendations

Each model brings unique strengths:

  • Different focal points: Storage optimization vs. performance vs. maintainability
  • Varying depth levels: From quick wins to architectural improvements
  • Diverse analysis styles: Structured vs. comprehensive vs. practical

Implementing the Workflow

Setup Instructions

1. Install Dependencies:

# Install required tools
sudo apt install curl jq mysql-client

# Create the script directory
mkdir -p ~/.local/bin

# Make script executable
chmod +x ~/.local/bin/aiml

2. Configure API Access:

# Get your free AIMLAPI key from https://aimlapi.com (free tier with limited use)
export AIMLAPI_API_KEY="your-free-api-key-here"
echo 'export AIMLAPI_API_KEY="your-free-api-key-here"' >> ~/.bashrc

3. Test the Setup:

# Verify configuration
aiml --config

# Test basic functionality
echo "SELECT VERSION();" | aiml "explain this SQL"

Practical Usage Patterns

Quick Table Analysis

# Analyze a specific table
mysql -e "SHOW CREATE TABLE users\G" mydb | \
aiml -m claude4 "Analyze this MySQL table structure"

Compare Different Model Perspectives

# Get multiple viewpoints on the same table
TABLE_DDL=$(mysql -e "SHOW CREATE TABLE orders\G" ecommerce)

echo "$TABLE_DDL" | aiml -m claude4 "MySQL table analysis"
echo "$TABLE_DDL" | aiml -m grok3 "Performance optimization review" 
echo "$TABLE_DDL" | aiml -m gpt4 "Practical improvement suggestions"

Analyze Multiple Tables

# Quick analysis of all tables in a database
mysql -e "SHOW TABLES;" mydb | \
while read table; do
  echo "=== Analyzing $table ==="
  mysql -e "SHOW CREATE TABLE $table\G" mydb | \
  aiml -m gpt4mini "Quick assessment of this table"
done

Index Analysis

# Review index usage and optimization
mysql -e "SHOW INDEX FROM tablename;" database | \
aiml -m deepseek "Suggest index optimizations for this MySQL table"

Query Performance Analysis

# Analyze slow queries
mysql -e "SHOW PROCESSLIST;" | \
aiml -m grok3 "Identify potential performance issues in these MySQL processes"

Why AIMLAPI Makes This Possible for DBAs

Free Access with Reasonable Costs: AIMLAPI provides free access with limited use to over 100 AI models, with very reasonable pricing for additional testing. This makes it perfect for DBAs who want to experiment without committing to expensive subscriptions.

Model Diversity: Access to models from different providers (OpenAI, Anthropic, Google, Meta, etc.) means you get varied perspectives and expertise areas.

No Vendor Lock-in: You can experiment with different models to find what works best for your specific needs without long-term commitments.

Terminal-Native: Stays in your comfortable Linux environment where you're already doing your MySQL work.

Model Selection Guide

Different models excel at different aspects of MySQL analysis:

# For detailed structural analysis
aiml -m claude4 "Comprehensive table structure review"

# For performance-focused analysis  
aiml -m grok3 "Performance optimization recommendations"

# For quick, practical suggestions
aiml -m gpt4 "Immediate actionable improvements"

# For complex reasoning about trade-offs
aiml -m deepseek-r1 "Complex optimization trade-offs analysis"

# For cost-effective quick checks
aiml -m gpt4mini "Brief table assessment"

Beyond MySQL: Other CLI Examples

Since we can pipe any command output to the AI tool, here are some other useful examples:

System Administration

# Analyze system processes
ps aux | aiml "what processes are using most resources?"

# Check disk usage
df -h | aiml "analyze disk usage and suggest cleanup"

# Network connections
netstat -tuln | aiml "explain these network connections"

# System logs
tail -50 /var/log/syslog | aiml "any concerning errors in these logs?"

File and Directory Analysis

# Large files
find /var -size +100M | aiml "organize these large files by type"

# Permission issues
ls -la /etc/mysql/ | aiml "check these file permissions for security"

# Configuration review
cat /etc/mysql/my.cnf | aiml "review this MySQL configuration"

Log Analysis

# Apache logs
tail -100 /var/log/apache2/error.log | aiml "summarize these web server errors"

# Auth logs
grep "Failed password" /var/log/auth.log | aiml "analyze these failed login attempts"

The point is you can pipe almost anything to get quick analysis without leaving your terminal.

Custom System Prompts

Tailor the analysis to your specific context:

# E-commerce focus
aiml -m claude4 -s "You are analyzing tables for a high-traffic e-commerce site" \
"Review this table for scalability"

# Security focus
aiml -m grok3 -s "You are a security-focused database analyst" \
"Security assessment of this table structure"

# Legacy system focus
aiml -m gpt4 -s "You are helping migrate a legacy system to modern MySQL" \
"Modernization recommendations for this table"

Automated Reporting

# Generate a comprehensive database analysis report
DB_NAME="production_db"
REPORT_FILE="analysis_$(date +%Y%m%d).md"

echo "# Database Analysis Report for $DB_NAME" > "$REPORT_FILE"
echo "Generated on $(date)" >> "$REPORT_FILE"

for table in $(mysql -Ns -e "SHOW TABLES;" "$DB_NAME"); do
  echo "" >> "$REPORT_FILE"
  echo "## Table: $table" >> "$REPORT_FILE"
  
  mysql -e "SHOW CREATE TABLE $table\G" "$DB_NAME" | \
  aiml -m claude4 "Provide concise analysis of this MySQL table" >> "$REPORT_FILE"
done

Performance Optimization Workflow

# Comprehensive performance analysis
mysql -e "SHOW CREATE TABLE heavy_table\G" db | \
aiml -m grok3 "Performance bottleneck analysis"

# Follow up with index suggestions
mysql -e "SHOW INDEX FROM heavy_table;" db | \
aiml -m deepseek "Index optimization strategy"

# Get implementation plan
aiml -m gpt4 "Create step-by-step implementation plan for these optimizations"

Real Benefits of This Approach

Speed: Get expert-level analysis in seconds instead of hours
Multiple Perspectives: Different models catch different issues
Learning Tool: Each analysis teaches you something new about MySQL optimization
Cost-Effective: Thanks to AIMLAPI's free tier and reasonable pricing, this powerful analysis is accessible
Consistency: Repeatable analysis across different tables and databases
Documentation: Easy to generate reports and share findings with teams

Tips for Best Results

  1. Start with Structure: Always begin with SHOW CREATE TABLE for comprehensive analysis
  2. Use Specific Prompts: The more specific your request, the better the analysis
  3. Compare Models: Different models excel at different aspects - use multiple perspectives
  4. Validate Suggestions: Always test AI recommendations in development environments first
  5. Iterate: Use follow-up questions to dive deeper into specific recommendations

Getting Started Today

The beauty of this approach is its simplicity and cost-effectiveness. With just a few commands, you can:

  1. Get your free AIMLAPI key from https://aimlapi.com (includes free tier)
  2. Install the script (5 minutes)
  3. Start analyzing your MySQL tables immediately
  4. Experiment with different models to see which ones work best for your needs
  5. Use the free tier for regular analysis, pay only for heavy testing

Windows Users (Quick Option)

I'm not a Windows person, but if you need to run this on Windows, the simplest approach is:

  1. Install WSL2 (Windows Subsystem for Linux)
  2. Install Ubuntu from Microsoft Store
  3. Follow the Linux setup above inside WSL2

This gives you a proper Linux environment where the script will work exactly as designed.

This isn't about replacing DBA expertise - it's about augmenting it while staying in your terminal environment. The AI provides rapid analysis and catches things you might miss, while you provide the context and make the final decisions.

Whether you're working with a single table or a complex database with hundreds of tables, this workflow scales to meet your needs. And since AIMLAPI provides free access with reasonable costs for additional use, you can experiment and find the perfect combination for your specific use cases without budget concerns.


The combination of MySQL's powerful introspection capabilities with AI analysis creates a workflow that's both practical and cost-effective for DBAs. Give it a try on your next database optimization project - you might be surprised at what insights emerge, all while staying in your comfortable terminal environment.