Free GitHub Agent Frameworks I Ship With

Last month I rebuilt a piece of my content pipeline that had been running on a hand-rolled agent loop for about a year. The rewrite took a weekend because I finally leaned on open-source frameworks instead of maintaining my own scaffolding. This post is the honest tour: which free GitHub repos I actually run in production, where each one earns its keep, and where I've been burned.
Everything here is Apache-2.0 or MIT. No paid tier required to ship. The only money you spend is on model tokens and infrastructure.
The short answer: which framework for which job
If you want the TL;DR before the details: LangGraph for anything with branching, retries, or human-in-the-loop; CrewAI for role-based content and research swarms; AutoGen for conversational multi-agent reasoning and code generation; Pydantic AI or llama-index agents when you want the smallest surface area possible; and smolagents from Hugging Face when you need code-writing agents that stay under 1,000 lines of dependencies.
Here is how I actually decide, on a real project:
| Framework | GitHub | Best for | State handling | My verdict |
|---|---|---|---|---|
| LangGraph | langchain-ai/langgraph | Deterministic workflows with LLM steps | Explicit graph + checkpointer | My default for production |
| CrewAI | crewAIInc/crewAI | Role-based content/research crews | Task passing | Great DX, watch the abstractions |
| AutoGen | microsoft/autogen | Chat-driven multi-agent, code exec | Conversation history | Strong for R&D, heavier for prod |
| Pydantic AI | pydantic/pydantic-ai | Typed tool-calling agents | Minimal, you own it | Underrated, boring in a good way |
| smolagents | huggingface/smolagents | Code-writing agents, tiny footprint | In-memory | Perfect for narrow tools |
The rest of the post is what I wish someone had told me before I picked one.
LangGraph: the one I keep coming back to
LangGraph (github.com/langchain-ai/langgraph) is what I use for the orchestration layer in my BizFlowAI ContentStudio pipeline. It is a graph runtime: nodes are functions (usually LLM calls or tools), edges are transitions, and state is a typed dict that flows through. That model matches how production agent work actually behaves. You are not chatting with a magic entity, you are moving a piece of state through a series of decisions and side effects.
What makes it stick for real systems:
- Checkpointing works. The
SqliteSaverandPostgresSaverlet you resume a run after a crash, replay from any node, or hand control to a human and come back later. In my content pipeline, if the "publish" node fails because a WordPress endpoint is down, the graph resumes exactly there on the next scheduled run. No re-running the $0.40 of research. - Conditional edges are explicit. No hidden routing logic inside an agent prompt. You write
add_conditional_edgesand the failure modes are visible. - Streaming is first-class. For a UI, you get token-level and node-level streaming without a wrapper.
The gotcha I hit: do not put your entire application state in one giant TypedDict. Split state per subgraph. When I had 22 fields flowing through 14 nodes, prompt debugging became painful because I could not tell which node mutated which field. Now I use small subgraphs with their own state, composed into a parent graph.
A minimum viable node looks like this:
from langgraph.graph import StateGraph, END
from typing import TypedDict
class State(TypedDict):
topic: str
draft: str
approved: bool
def research(state: State) -> State:
# call your LLM, return partial state update
return {"draft": llm_draft(state["topic"])}
def review(state: State) -> State:
return {"approved": llm_review(state["draft"])}
g = StateGraph(State)
g.add_node("research", research)
g.add_node("review", review)
g.add_edge("research", "review")
g.add_conditional_edges("review", lambda s: END if s["approved"] else "research")
g.set_entry_point("research")
app = g.compile()
That is 20 lines and you already have retry logic, resumability (once you add a checkpointer), and observability via LangSmith or your own logger.
CrewAI: when the mental model is a team
CrewAI (github.com/crewAIInc/crewAI) leans into the "give each agent a role, a goal, and a backstory" metaphor. I was skeptical at first because that sounded like anthropomorphized fluff. It turned out to be a useful abstraction for content workflows specifically, because SEO content really is a small team: researcher, outliner, writer, editor, SEO reviewer.
I use CrewAI for one specific sub-pipeline: long-form article generation with three specialized roles. It ships tomorrow, not next month, because the framework does the boring parts (task chaining, output parsing, tool binding) with about 40 lines of YAML or Python.
Real numbers from my setup:
- 4 agents per crew, ~1,800 tokens of role prompts total
- Average article: ~$0.18 in Claude Sonnet costs, ~90 seconds end to end
- Failure rate before retries: ~4%, mostly JSON parsing when I forget to pin
response_format
Where CrewAI hurts: state passing between tasks is loose. If task B needs a specific field from task A, you often end up parsing the previous task's freeform output. For anything with real branching, I graduate to LangGraph. CrewAI is where I start, not where I end.
Also: pin your version. The API surface has moved several times. I keep crewai==0. pinned exactly and read the changelog before bumping.
AutoGen: heavier, but the reasoning quality shows
Microsoft's AutoGen (github.com/microsoft/autogen) treats multi-agent work as a conversation. Agents talk, a group chat manager decides who speaks next, and you can drop a code-executor agent in the middle. The v0.4 rewrite made it more production-friendly with an async event-driven core, but it is still the heaviest of the three big frameworks.
I use AutoGen for one thing in production: a research and synthesis loop where a critic agent challenges a writer agent until the writer produces something with sourced claims. The back-and-forth genuinely improves output for research-heavy pieces. For pure content generation it is overkill.
Trade-off I've measured on the same input topic:
| Framework | Tokens used | Wall clock | Output quality (my rubric) |
|---|---|---|---|
| LangGraph, single pass | ~4k | 12s | 7/10 |
| CrewAI, 4 roles | ~9k | 90s | 8/10 |
| AutoGen, critic loop | ~18k | 140s | 8.5/10 |
That 0.5 quality bump costs 2x the tokens of CrewAI and 4x LangGraph. For a landing page hero, worth it. For a programmatic SEO page, absolutely not. Match the framework to the unit economics.
The lightweight tier: Pydantic AI and smolagents
The frameworks above are opinionated. Sometimes you want almost nothing between you and the model.
Pydantic AI (github.com/pydantic/pydantic-ai) is my pick when I need a typed tool-calling agent inside an existing FastAPI service. It is written by the Pydantic team, so the validation story is airtight. Tool definitions are Python functions with type hints. Output types are Pydantic models. That is the whole framework. If your agent is really just "LLM plus a few tools plus structured output", this saves you from importing 400 MB of dependencies.
smolagents (github.com/huggingface/smolagents) from Hugging Face is worth studying even if you do not adopt it. Its core idea is that agents should write code, not JSON, to call tools. In practice this means fewer schema errors and more expressive multi-step reasoning in a single generation. I use it for a narrow internal tool that scrapes and normalizes data. Under 1,000 lines of framework code. You can read the entire source in an afternoon.
The setup gotchas nobody documents
These are the ones that cost me real time. In no particular order.
- Model provider abstractions leak. LangChain's
ChatAnthropicandChatOpenAIbehave differently around streaming, tool calls, and system prompts. If you swap providers, test each tool call path. I once shipped a bug where a tool worked fine on Claude but silently returned a stringified null on OpenAI because the function-calling shape differed. - Async or sync, pick one and commit. Mixing them inside a graph node produces the ugliest stack traces you will ever see. LangGraph supports both; AutoGen v0.4 is async-first. Read the docs before your first commit.
- Rate limits eat you alive in parallel fan-out. If your graph fans out to 10 parallel research subagents, you will hit provider rate limits on any real project. Add a semaphore. I use
asyncio.Semaphore(3)for Anthropic andSemaphore(8)for OpenAI, tuned to my tier. - Retries need idempotency. If your "publish to CMS" node retries on failure, make sure it does not double-publish. I use a deterministic idempotency key derived from the run ID plus node name.
- Observability is not optional. LangSmith, Langfuse (self-hostable, open-source, github.com/langfuse/langfuse), or your own OpenTelemetry setup. Without traces you cannot debug non-deterministic systems. Langfuse is what I recommend for teams that want to self-host and stay off vendor pricing.
- Costs compound silently. A critic loop with a max of 5 iterations, run 10,000 times a month, is not the same bill as a single-pass agent. Log token counts per node from day one and set a hard budget cap in your graph.
A boring, production-safe stack
If you asked me to greenfield a multi-agent system this week, here is what I would use:
- LangGraph for orchestration, with a Postgres checkpointer
- CrewAI as a subgraph for one specific content-writing role team, exposed to LangGraph as a single node
- Pydantic AI for any narrow, typed tool-calling agent that lives in the same repo
- Langfuse for tracing, self-hosted on a small VPS
- pgvector in Postgres for retrieval, with hybrid search (BM25 + vector, fused with RRF)
- Claude Sonnet as the workhorse model, GPT-4-class as a fallback via a provider router
- AWS Lambda + EventBridge for scheduled runs, or a small always-on worker if the graph is long-running
That combination has kept my own content pipeline running 24/7 with almost no intervention. When something breaks, the checkpointer plus Langfuse traces tell me exactly where within a couple of minutes.
What I'd do if I were starting today
Pick LangGraph. Not because it is the most exciting, but because it forces you to think in states and transitions, which is how you have to reason about production agent systems anyway. Add CrewAI only when you have a genuine "team of roles" problem. Reach for AutoGen when a critic loop measurably improves output on your specific task. Keep Pydantic AI in your back pocket for the small stuff.
Do not adopt a framework because a tutorial made it look pretty. Adopt it because you can name the specific failure mode you are trying to prevent. In my experience the failures that matter are: losing state on retry, silent tool-call errors, unbounded token spend, and lack of observability. Every framework I named above solves at least three of those. Some solve all four, if you configure them right.
Close
Free open-source frameworks are where I do 90% of my agent work. The paid platforms make sense at a specific scale and for specific compliance stories, but you can ship real revenue-generating systems with the repos above and a Postgres database.
If you are building something along these lines and want a second pair of eyes from someone who runs this stack in production, I take a small number of engagements each quarter. You can reach me at lazar-milicevic.com/#contact, or read more posts on the blog if you want to see how the pieces fit together on real projects.
Frequently asked questions
Which open-source agent framework should I use for a production LLM workflow?
For production workflows with branching, retries, or human-in-the-loop, I default to LangGraph because it gives you an explicit graph with typed state, checkpointing (SqliteSaver/PostgresSaver), and first-class streaming. For role-based content or research crews, I reach for CrewAI. For chat-driven multi-agent reasoning and code execution, AutoGen is the strongest choice. If you want the smallest possible surface area, Pydantic AI or llama-index agents work well, and Hugging Face's smolagents is ideal for narrow code-writing tools. All of these are Apache-2.0 or MIT and free on GitHub.
What is LangGraph and why is it good for production agents?
LangGraph (github.com/langchain-ai/langgraph) is a graph runtime where nodes are functions (usually LLM calls or tools), edges are transitions, and state is a typed dict flowing through. It's production-friendly because checkpointing lets you resume a run after a crash or hand control to a human and come back later, conditional edges make routing explicit instead of hiding it inside a prompt, and streaming works at both token and node level. In my own content pipeline, if a publish step fails, the graph resumes exactly there without re-running the expensive research. The main pitfall is putting your whole app state in one giant TypedDict, split it into small subgraphs.
When should I use CrewAI instead of LangGraph?
I use CrewAI (github.com/crewAIInc/crewAI) when the mental model of the job really is a team, for example, long-form article generation with researcher, outliner, writer, and editor roles. It handles task chaining, output parsing, and tool binding in about 40 lines of YAML or Python, so you ship fast. In my setup, a 4-agent crew produces an article for about $0.18 in Claude Sonnet costs in ~90 seconds with a ~4% pre-retry failure rate. The weakness is loose state passing between tasks: if you need real branching or structured hand-offs, graduate to LangGraph. Also pin your version, because the API has changed several times.
What is Microsoft AutoGen best used for?
AutoGen (github.com/microsoft/autogen) models multi-agent work as a conversation: agents talk to each other, a group chat manager decides who speaks next, and you can drop in a code-executor agent to run generated code. It shines for conversational multi-agent reasoning and code generation tasks where you want emergent back-and-forth. The v0.4 rewrite introduced an async event-driven core that made it more production-friendly, but it's still the heaviest of the major frameworks, so I mostly use it for R&D and narrow production slots rather than as a general orchestration layer.
Are there lightweight alternatives to LangGraph and CrewAI for simple agents?
Yes, when I want minimal surface area and full control, I use Pydantic AI (pydantic/pydantic-ai) for typed tool-calling agents where you own the state entirely; it's boring in a good way and underrated. For code-writing agents with a tiny footprint, Hugging Face's smolagents (huggingface/smolagents) stays under 1,000 lines of dependencies and is perfect for narrow tools. Both are free, open-source (Apache-2.0/MIT), and avoid the heavier abstractions of the bigger frameworks. Pick them when your workflow is small and well-defined instead of a multi-role pipeline.
Building something hard with AI or automation? I am open to talk.
Get in touch