DEV Community

Cover image for 10 Python Libraries for AI Automation That Are Better Than LangChain
Akash Raidas
Akash Raidas

Posted on

10 Python Libraries for AI Automation That Are Better Than LangChain

LangChain is powerful. But sometimes you just need to hammer a nail, not operate a pneumatic construction system.

After building a dozen AI automation projects, I've discovered something freeing: you can often get better results with simpler, focused libraries that do one thing exceptionally well. Here are ten that have saved my sanity.

1. Instructor: When You Actually Need Structured Data

Remember spending hours writing regex to parse LLM outputs? Yeah, Instructor made me forget about those dark times too.

It's beautifully simple—you define a Pydantic model, and Instructor forces the LLM to return data in exactly that structure. No more "the AI returned a string when I needed a list" bugs at 2 AM.

import instructor
from pydantic import BaseModel
from openai import OpenAI

client = instructor.from_openai(OpenAI())

class UserInfo(BaseModel):
    name: str
    age: int
    email: str

user = client.chat.completions.create(
    model="gpt-4",
    response_model=UserInfo,
    messages=[{"role": "user", "content": "Extract: John Doe, 30, john@example.com"}]
)
Enter fullscreen mode Exit fullscreen mode

That's it. No chains, no output parsers, no crying into your keyboard.

2. LiteLLM: The Universal Adapter

Ever started a project with OpenAI, then needed to switch to Anthropic, then your client wanted to try Google's models? LiteLLM is the adapter that keeps you sane.

One interface for 100+ LLM providers. Same code, different models. It's like having a universal charger for your phone, laptop, and that weird Bluetooth speaker.

from litellm import completion

# Works with OpenAI
response = completion(
    model="gpt-4",
    messages=[{"role": "user", "content": "Hello"}]
)

# Same code, different provider
response = completion(
    model="claude-3-sonnet-20240229",
    messages=[{"role": "user", "content": "Hello"}]
)
Enter fullscreen mode Exit fullscreen mode

The best part? It handles rate limits, retries, and fallbacks automatically. Your code stays clean.

3. Tenacity: Because APIs Fail (A Lot)

Here's what nobody tells you about building with LLMs: they fail. Rate limits, timeouts, random 500 errors at the worst possible moment.

Tenacity is the library that turns "it broke in production" into "it recovered automatically." It's a retry library with actual intelligence.

from tenacity import retry, stop_after_attempt, wait_exponential
import openai

@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=4, max=10)
)
def call_gpt(prompt):
    return openai.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}]
    )
Enter fullscreen mode Exit fullscreen mode

It waits intelligently between retries, gives up when it should, and logs everything. Production-grade reliability in five lines.

4. Pydantic: The Bouncer Your Data Needs

If Instructor is the translator, Pydantic is the security guard making sure nothing sketchy gets into your application.

You define what your data should look like, and Pydantic validates it with zero tolerance for nonsense. Wrong type? Rejected. Missing field? Rejected. Weird format? You guessed it—rejected.

from pydantic import BaseModel, EmailStr, field_validator

class User(BaseModel):
    username: str
    email: EmailStr
    age: int

    @field_validator('age')
    def check_age(cls, v):
        if v < 0 or v > 120:
            raise ValueError('Invalid age')
        return v
Enter fullscreen mode Exit fullscreen mode

Every AI project I've seen that fell apart in production? They skipped proper data validation. Don't be that project.

5. Streamlit: From Script to App in Minutes

Need to show your AI creation to someone who doesn't live in a terminal? Streamlit turns Python scripts into web apps faster than you can say "npm install."

No HTML, no CSS, no JavaScript frameworks—just Python. It's perfect for internal tools, demos, and MVPs.

import streamlit as st
import openai

st.title("Simple AI Chat")

prompt = st.text_input("Ask something:")
if st.button("Send"):
    response = openai.chat.completions.create(
        model="gpt-4",
        messages=[{"role": "user", "content": prompt}]
    )
    st.write(response.choices[0].message.content)
Enter fullscreen mode Exit fullscreen mode

Run streamlit run app.py and boom—you have a working interface. Show it to your boss, your client, your confused relatives who think you "work with computers."

6. Jinja2: Templates for Prompts That Don't Suck

Concatenating strings to build prompts is the programming equivalent of eating cereal with a fork. It works, technically, but why would you do that to yourself?

Jinja2 is the templating engine that makes prompt engineering actually manageable.

from jinja2 import Template

template = Template("""
You are a {{ role }} assistant.

User context:
- Name: {{ user.name }}
- Preferences: {{ user.preferences }}

Task: {{ task }}
""")

prompt = template.render(
    role="helpful",
    user={"name": "Alice", "preferences": "concise answers"},
    task="Explain quantum computing"
)
Enter fullscreen mode Exit fullscreen mode

Now your prompts are readable, reusable, and don't make you want to throw your laptop out the window.

7. Loguru: Logging That Doesn't Make You Angry

Python's built-in logging is fine if you hate yourself. For everyone else, there's Loguru.

It's logging that actually makes sense—colors, automatic formatting, sane defaults. Perfect for debugging those "why did the AI do that?" moments.

from loguru import logger

logger.add("ai_app.log", rotation="500 MB")

logger.info("Starting AI request")
logger.debug(f"Prompt: {prompt}")
logger.success("Got response in {time}s")
logger.error("API call failed: {error}")
Enter fullscreen mode Exit fullscreen mode

When something breaks at 3 AM (and it will), you'll thank past-you for having readable logs.

8. httpx: Because requests Isn't Async

Calling multiple LLM APIs simultaneously? Python's beloved requests library will make you wait for each one sequentially like it's 2010.

httpx is the modern async HTTP client that actually respects your time.

import httpx
import asyncio

async def call_multiple_ais(prompts):
    async with httpx.AsyncClient() as client:
        tasks = [
            client.post("https://api.openai.com/v1/chat/completions", ...)
            for prompt in prompts
        ]
        return await asyncio.gather(*tasks)
Enter fullscreen mode Exit fullscreen mode

Three API calls that took 9 seconds? Now they take 3. Math has never felt this good.

9. Rich: Terminal Output That Doesn't Look Like 1995

Building AI automation often means watching progress in your terminal. Rich makes that experience not miserable.

Progress bars, formatted tables, syntax highlighting, and panels—all in your terminal, all gorgeous.

from rich.console import Console
from rich.progress import track
import time

console = Console()

console.print("[bold green]Starting AI pipeline...[/bold green]")

for step in track(range(100), description="Processing..."):
    time.sleep(0.01)

console.print("[bold blue]Complete![/bold blue]")
Enter fullscreen mode Exit fullscreen mode

Your terminal becomes a dashboard. Your coworkers think you're a wizard. Everyone wins.

10. DuckDB: When Your AI Needs a Database (But Not the Drama)

LLMs generate data. Lots of it. You need to store it somewhere that isn't a JSON file named data_final_final_v3_ACTUAL.json.

DuckDB is SQLite's cooler cousin—an embedded analytical database that's shockingly fast and requires zero setup.

import duckdb

con = duckdb.connect('ai_data.db')

# Store AI responses
con.execute("""
    CREATE TABLE IF NOT EXISTS responses (
        id INTEGER PRIMARY KEY,
        prompt TEXT,
        response TEXT,
        model TEXT,
        timestamp TIMESTAMP
    )
""")

con.execute("""
    INSERT INTO responses VALUES (?, ?, ?, ?, ?)
""", (1, prompt, response, "gpt-4", datetime.now()))

# Query with SQL
results = con.execute("""
    SELECT model, COUNT(*) as count 
    FROM responses 
    GROUP BY model
""").fetchall()
Enter fullscreen mode Exit fullscreen mode

No Docker containers, no PostgreSQL configuration files, no DevOps tickets. Just data, stored and queryable.


The Pattern I've Noticed

After using all these libraries across different projects, I've noticed something: the best AI automation setups aren't built around one giant framework. They're composed of small, excellent tools that each solve one problem really well.

LangChain tries to be everything. These libraries try to be one thing, exceptionally.

Need structured outputs? Instructor. Need reliability? Tenacity. Need to switch models? LiteLLM.

Pick what you need, ignore what you don't. Your code will be simpler, your debugging will be faster, and you'll actually understand what's happening when things break.

And they will break. But at least now you have the right tools to fix them.

What Actually Matters

Look, I'm not saying LangChain is bad. For complex agent systems with memory, routing, and multi-step reasoning, it's probably the right choice.

But most AI automation isn't that. Most of the time, you just need to:

  • Call an API reliably
  • Get structured data back
  • Validate it
  • Store it
  • Show it to someone

These ten libraries do exactly that, without making you learn a new paradigm every other Tuesday.

Start simple. Add complexity only when you need it. Your future self—the one debugging at midnight—will thank you.


Which libraries are you using for AI automation? Have I missed your favorite? Let me know—I'm always hunting for tools that make this work easier.

Top comments (0)