{"slug": "comparing-ai-agents-python-library-options-for-production", "title": "Comparing AI Agents Python Library Options for Production", "summary": "A developer compares three Python libraries for building production AI agents: LangChain for flexibility, CrewAI for team-style orchestration, and LlamaIndex for data-centric retrieval. All three support OpenAI, Anthropic, and Azure endpoints with async APIs compatible with FastAPI, but differ in abstraction level and runtime cost.", "body_md": "If you need a Python library to build an AI agent that can run in production, start with **LangChain** for flexibility, **CrewAI** for team-style orchestration, or **LlamaIndex** if your focus is on data-centric retrieval. All three install with a single `pip`\n\ncommand, but they differ in abstraction level, runtime cost, and how easy they are to test inside a FastAPI service.\n\nThe three most battle-tested options today are **LangChain**, **CrewAI**, and **LlamaIndex**.\n\nAll three are open source, support OpenAI, Anthropic, and Azure endpoints, and have async APIs that play nicely with FastAPI.\n\nInstallation is straightforward, but each library pulls a different set of optional dependencies.\n\n```\n# Core libraries\npip install langchain crewai llama-index\n# Optional LLM providers (pick what you need)\npip install openai anthropic\n# Vector store for LlamaIndex example\npip install chromadb\npython\nfrom langchain.llms import OpenAI\nfrom langchain.prompts import PromptTemplate\nfrom langchain.chains import LLMChain\n\nllm = OpenAI(model=\"gpt-4o-mini\")\nprompt = PromptTemplate.from_template(\"Translate this to French: {text}\")\nchain = LLMChain(llm=llm, prompt=prompt)\npython\nfrom crewai import Agent, Task, Crew\n\n# Define a simple research agent\nresearcher = Agent(\n    role=\"Researcher\",\n    goal=\"Find the latest Python web frameworks\",\n    backstory=\"You are a senior backend engineer.\",\n    llm=\"gpt-4o-mini\",\n)\n\ntask = Task(\n    description=\"List three frameworks with a one‑sentence summary each.\",\n    agent=researcher,\n)\n\ncrew = Crew(agents=[researcher], tasks=[task])\npython\nfrom llama_index import VectorStoreIndex, SimpleDirectoryReader\nfrom llama_index.llms import OpenAI\n\ndocuments = SimpleDirectoryReader(\"data/\").load_data()\nindex = VectorStoreIndex.from_documents(documents, llm=OpenAI(model=\"gpt-4o-mini\"))\n```\n\nAll three snippets run in a fresh virtual environment. The biggest gotcha I’ve hit is version mismatches between `langchain`\n\nand `crewai`\n\nwhen they both depend on `openai`\n\n. Pinning `openai>=1.0,<2.0`\n\nin `requirements.txt`\n\nsaved me a day of debugging.\n\nBelow is a tiny “weather lookup” agent that takes a city name, calls a mock weather API, and returns a friendly sentence. The logic is the same; only the orchestration differs.\n\n``` python\nimport httpx\nfrom langchain.llms import OpenAI\nfrom langchain.prompts import PromptTemplate\nfrom langchain.chains import LLMChain\n\nllm = OpenAI(model=\"gpt-4o-mini\")\nprompt = PromptTemplate.from_template(\n    \"You are a helpful assistant. Use the JSON response {weather} to answer: \"\n    \"What is the weather like in {city}?\"\n)\n\nasync def fetch_weather(city: str) -> dict:\n    async with httpx.AsyncClient() as client:\n        resp = await client.get(f\"https://api.example.com/weather?city={city}\")\n        return resp.json()\n\nasync def weather_agent(city: str) -> str:\n    weather = await fetch_weather(city)\n    chain = LLMChain(llm=llm, prompt=prompt)\n    return await chain.arun(weather=weather, city=city)\npython\nfrom crewai import Agent, Task, Crew\nimport httpx\n\nweather_agent = Agent(\n    role=\"Weather Bot\",\n    goal=\"Provide a short weather summary\",\n    backstory=\"You are a backend engineer who loves concise messages.\",\n    llm=\"gpt-4o-mini\",\n)\n\nasync def fetch_weather(city):\n    async with httpx.AsyncClient() as client:\n        r = await client.get(f\"https://api.example.com/weather?city={city}\")\n        return r.json()\n\ntask = Task(\n    description=\"Summarize the JSON weather data for {city}\",\n    expected_output=\"A one‑sentence weather report.\",\n    agent=weather_agent,\n    async_func=fetch_weather,   # CrewAI lets you attach a callable\n)\n\ncrew = Crew(agents=[weather_agent], tasks=[task])\n\nasync def run_crew(city):\n    return await crew.kickoff(inputs={\"city\": city})\npython\nfrom llama_index import SimpleDirectoryReader, VectorStoreIndex, ServiceContext\nfrom llama_index.llms import OpenAI\nimport httpx\n\n# Build a trivial index containing a prompt template\ndocuments = SimpleDirectoryReader(input_files=[\"prompt.txt\"]).load_data()\nservice_context = ServiceContext.from_defaults(llm=OpenAI(model=\"gpt-4o-mini\"))\nindex = VectorStoreIndex.from_documents(documents, service_context=service_context)\n\nasync def fetch_weather(city):\n    async with httpx.AsyncClient() as client:\n        r = await client.get(f\"https://api.example.com/weather?city={city}\")\n        return r.json()\n\nasync def llama_agent(city):\n    query = f\"Summarize this JSON: {await fetch_weather(city)}\"\n    response = await index.as_query_engine().aquery(query)\n    return response.response\n```\n\nAll three agents return a string like “In Paris it’s 12 °C with light rain.” The LangChain version feels most explicit; CrewAI hides the prompt plumbing but requires you to think in terms of tasks; LlamaIndex bundles the prompt inside an index, which can be overkill for a single API call.\n\n| Feature | LangChain | CrewAI | LlamaIndex |\n|---|---|---|---|\nPrompt control |\nFull, low-level | Medium (templates per task) | Low (index-driven) |\nTool integration |\nEasy via `Tool` class |\nBuilt-in task-to-tool mapping | Requires custom retriever |\nMemory |\nBuilt-in `ConversationBufferMemory`\n|\nImplicit via task history | Index acts as persistent memory |\nAsync support |\nNative async methods | Async tasks supported | Async query engine |\nCost predictability |\nYou manage each LLM call | Crew may fire extra calls for coordination | Index creation can add one-off token cost |\nLearning curve |\nSteeper, many concepts | Gentle, opinionated | Gentle if you only need retrieval |\n\nIn my production services, LangChain adds ~15 ms per extra tool call, CrewAI adds ~30 ms overhead for task orchestration, and LlamaIndex adds a one-time indexing cost that can be several seconds for a 10 k document corpus. If you’re budget-conscious, watch out for CrewAI’s hidden “role-play” calls – they can double your token bill if you forget to set `max_tokens`\n\non the underlying LLM.\n\nFastAPI is already async-first, so you can drop any of the async agents directly into a route. Below is a minimal FastAPI app that uses the LangChain weather agent; swap the import for `crew_agent`\n\nor `llama_agent`\n\nto try the other libraries.\n\n``` python\n# app/main.py\nfrom fastapi import FastAPI, HTTPException\nfrom pydantic import BaseModel\nimport uvicorn\n\n# Choose your agent implementation\nfrom agents.langchain_weather import weather_agent  # or crew_agent, llama_agent\n\napp = FastAPI(title=\"Weather AI Agent\")\n\nclass CityRequest(BaseModel):\n    city: str\n\n@app.post(\"/weather\")\nasync def get_weather(req: CityRequest):\n    try:\n        result = await weather_agent(req.city)\n        return {\"city\": req.city, \"report\": result}\n    except Exception as exc:\n        raise HTTPException(status_code=502, detail=str(exc))\n\nif __name__ == \"__main__\":\n    uvicorn.run(\"app.main:app\", host=\"0.0.0.0\", port=8000, reload=True)\n```\n\n`httpx`\n\ntimeouts (`client = httpx.AsyncClient(timeout=10.0)`\n\n).\n`OpenAI()`\n\ninside the route handler.If you need more context, see my earlier post on [AI agent python ollama: Build, Test, Deploy with FastAPI](https://www.logiclooptech.dev/ai-agent-python-ollama-build-test-deploy-with-fastapi/) for a full deployment pipeline.\n\nTesting LLM-driven code feels weird because the output is nondeterministic. Here’s what I rely on:\n\n`assert \"Translate this to French\" in prompt`\n\n. If the prompt changes, the test fails before you even call the model.\n`OpenAI`\n\nwith a stub that returns a deterministic JSON payload. Libraries like `pytest-mock`\n\nlet you patch `OpenAI.__call__`\n\n. This isolates the business logic from the provider.\n`httpx.AsyncClient(app=app)`\n\nin pytest to hit `/weather`\n\nwith a fake city and assert the shape of the JSON response.\n`max_tokens`\n\nparameter let the model keep streaming.When you’re ready to scale, read the “Testing and validation” chapter of the official LangChain docs – they outline a “LLMMock” helper that integrates nicely with pytest.\n\n**Which library should I start with for a simple chatbot?**\n\nLangChain gives the most flexibility and the smallest dependency footprint for a single-turn bot. If you want built-in task management, try CrewAI.\n\n**Do I need a vector store for every agent?**\n\nOnly if you plan to retrieve or embed large text collections. LlamaIndex shines there; otherwise it adds unnecessary latency.\n\n**Can I swap OpenAI for an on-prem model?**\n\nAll three libraries expose a generic LLM interface. Point the client to your local server (e.g., `OpenAI(api_base=\"http://localhost:8000/v1\")`\n\n) and the rest of the code stays the same.\n\n**How do I monitor token usage per request?**\n\nWrap the LLM call in a decorator that reads the `usage`\n\nfield from the response and pushes it to Prometheus or CloudWatch. I keep a `request_id`\n\nin the FastAPI `state`\n\nto correlate logs.\n\n`pip install`\n\nline; watch version pins for `openai`\n\n.", "url": "https://wpnews.pro/news/comparing-ai-agents-python-library-options-for-production", "canonical_source": "https://dev.to/ayush_kumar_085a0f2c54e3f/comparing-ai-agents-python-library-options-for-production-g53", "published_at": "2026-07-22 07:51:03+00:00", "updated_at": "2026-07-22 08:01:41.869583+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-agents", "developer-tools", "large-language-models"], "entities": ["LangChain", "CrewAI", "LlamaIndex", "OpenAI", "Anthropic", "Azure", "FastAPI"], "alternates": {"html": "https://wpnews.pro/news/comparing-ai-agents-python-library-options-for-production", "markdown": "https://wpnews.pro/news/comparing-ai-agents-python-library-options-for-production.md", "text": "https://wpnews.pro/news/comparing-ai-agents-python-library-options-for-production.txt", "jsonld": "https://wpnews.pro/news/comparing-ai-agents-python-library-options-for-production.jsonld"}}