[{"data":1,"prerenderedAt":716},["ShallowReactive",2],{"tool-llamaindex-en":3},{"slug":4,"published":5,"minutes":6,"category":7,"tags":8,"keywords":14,"about":22,"sources":29,"cover":56,"og":57,"expertise":58,"locales":59,"lang":60,"title":63,"description":64,"coverAlt":65,"url":66,"pricing":67,"kind":9,"metaTitle":68,"takeaways":69,"faq":75,"toc":88,"blocks":113,"others":483},"llamaindex","2026-07-14",10,"agents",[9,10,11,12,13],"Agent framework","RAG","Python","Document parsing","Workflows",[4,15,16,17,18,19,20,21],"llamaindex vs langgraph","llamaindex workflows","llama index agent framework","llamaparse pricing","rag framework python","durable workflows python","document agent framework",[23,26],{"name":24,"url":25},"LlamaIndex","https:\u002F\u002Fgithub.com\u002Frun-llama\u002Fllama_index",{"name":27,"url":28},"Retrieval-augmented generation","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FRetrieval-augmented_generation",[30,32,35,38,41,44,47,50,53],{"title":31,"url":25},"LlamaIndex repository README and focus note",{"title":33,"url":34},"Agent Workflows: introduction","https:\u002F\u002Fdevelopers.llamaindex.ai\u002Fpython\u002Fllamaagents\u002Fworkflows\u002F",{"title":36,"url":37},"Agent Workflows: writing durable workflows","https:\u002F\u002Fdevelopers.llamaindex.ai\u002Fpython\u002Fllamaagents\u002Fworkflows\u002Fdurable_workflows\u002F",{"title":39,"url":40},"Agent Workflows: observability","https:\u002F\u002Fdevelopers.llamaindex.ai\u002Fpython\u002Fllamaagents\u002Fworkflows\u002Fobservability\u002F",{"title":42,"url":43},"LlamaAgents overview","https:\u002F\u002Fdevelopers.llamaindex.ai\u002Fpython\u002Fllamaagents\u002Foverview\u002F",{"title":45,"url":46},"llama-index-core on PyPI","https:\u002F\u002Fpypi.org\u002Fproject\u002Fllama-index-core\u002F",{"title":48,"url":49},"LlamaIndex and LlamaParse pricing","https:\u002F\u002Fwww.llamaindex.ai\u002Fpricing",{"title":51,"url":52},"LiteParse documentation","https:\u002F\u002Fdevelopers.llamaindex.ai\u002Fliteparse\u002F",{"title":54,"url":55},"LangGraph on GitHub","https:\u002F\u002Fgithub.com\u002Flangchain-ai\u002Flanggraph","\u002Fimages\u002Fblog\u002Fllamaindex\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fllamaindex\u002Fog.jpg","ai-engineer",[60,61,62],"en","de","hu","LlamaIndex review: the widest data toolkit, with its centre of gravity already moved","LlamaIndex in 2026: an MIT-licensed Python data and agent framework with 300+ integrations, event-driven Workflows, and a company that has moved its focus to LlamaParse.","Diagram: an event-driven workflow with typed steps, parallel workers, a fan-in step and a checkpoint after a restart.","https:\u002F\u002Fwww.llamaindex.ai","MIT · hosted platform paid","LlamaIndex: wide toolkit, shifting focus · Balázs Csorba",[70,71,72,73,74],"LlamaIndex is still the widest open-source data toolkit for LLM applications: more than 300 integration packages, one thin adapter each, on top of a small set of core abstractions.","Workflows, its orchestration layer, is event-driven: a step takes an event and returns an event, the graph is derived from type annotations, and it is validated before the run starts.","Durability is opt-in and hand-written. A run is ephemeral by default; snapshots come from `Context.to_dict()` plus a loop the team writes, and resume is at-least-once, so steps must be safe to repeat.","The company's own README now states that the focus is document parsing and extraction. LlamaParse is the paid product, priced in credits, and LiteParse is the local open-source parser.","The verdict: use the open-source core, and specifically Workflows as a small library, but keep the framework's blast radius small, because the maintenance direction has plainly moved.",[76,79,82,85],{"q":77,"a":78},"Is LlamaIndex still worth using in 2026?","Yes, with a narrowed scope. The MIT-licensed core is maintained, `llama-index-core` was at version 0.14.25 on 21 September 2026, and the Workflows orchestration layer is genuinely well designed for branching and looping logic. What has changed is the company's stated focus, which the README puts on document parsing and extraction rather than on the framework.",{"q":80,"a":81},"What are LlamaIndex Workflows and how do they work?","A workflow is a subclass of `Workflow` with methods decorated by `@step`. Each step accepts one event type and returns another, and the framework routes by type annotation, so branches are ordinary `if` statements and loops are steps returning an event handled earlier. Concurrency is a step returning `list[Event]` paired with a step accepting `list[Event]`. The event graph is validated before the run starts.",{"q":83,"a":84},"How does LlamaIndex handle durability and retries?","It does not, by default. Once `run()` returns, the state is gone. The documented mechanism is a checkpoint loop: serialise the context with `Context.to_dict()` when a `StepStateChanged` event marks a step as finished, then rebuild it with `Context.from_dict()` and call `run(ctx=...)`. Resume is at-least-once, so a step in flight when the snapshot was taken runs again. The DBOS runtime plugin is the alternative that removes the loop.",{"q":86,"a":87},"How much does LlamaParse cost?","The pricing page sells credits rather than seats: 1,000 credits at $1.25, 10,000 credits free, 40,000 on the $50 starter tier and 400,000 on the $500 pro tier, with pay-as-you-go caps of $500 and $5,000 a month. Concurrent parse jobs are 5 on free and starter, 20 on pro and 100 on enterprise. Parse, extract, classify and index all draw on the same balance.",[89,92,95,98,101,104,107,110],{"id":90,"title":91},"what-it-is","What it is",{"id":93,"title":94},"how-it-works","How Workflows works",{"id":96,"title":97},"getting-started","Getting started",{"id":99,"title":100},"durability","Durability and retries",{"id":102,"title":103},"where-it-falls-short","Where it falls short",{"id":105,"title":106},"the-pivot","The pivot to document processing",{"id":108,"title":109},"verdict","Verdict",{"id":111,"title":112},"sources","Sources",[114,118,121,124,144,167,168,194,203,231,241,242,245,247,269,288,289,310,312,327,328,331,388,391,398,399,402,417,420,426,427,430,445,449,452,453],{"type":115,"content":116},"paragraph",[117],"LlamaIndex is an MIT-licensed Python framework for wiring LLM applications to data. It began as a set of connectors and index abstractions for retrieval, and it is still the widest such toolkit: the repository publishes more than 300 integration packages covering model providers, embedding models, vector stores, document loaders and rerankers. That breadth is why most teams meet the project first, and why it stays useful even though the company's own attention has moved elsewhere. The position taken here is simple: use the open-source core, and be deliberate about which hosted parts get adopted.",{"type":115,"content":119},[120],"It sits between the model provider and the application. Nothing in the core talks to a model provider directly; every model, embedder and vector store arrives through an integration package implementing a core abstract class. That is a clean boundary and also the source of the main complaint: the same abstraction has to cover OpenAI, a local Ollama process and a dozen embedding models, so the useful common denominator is narrower than the surface area suggests. Against LangGraph it competes for the same orchestration role, against LangChain it competes on data handling, and against a hand-assembled vector store plus reranker it competes on convenience rather than capability.",{"type":122,"level":123,"id":90,"text":91},"heading",2,{"type":115,"content":125},[126,127,131,132,135,136,139,140,143],"Package layout is the first thing to check, and it is where most confusion starts. ",{"tag":128,"children":129},"code",[130],"llama-index-core"," holds the abstractions and ships Workflows with them. ",{"tag":128,"children":133},[134],"llama-index"," is the starter package that installs core plus a selection of integrations. Workflows also publishes on its own as ",{"tag":128,"children":137},[138],"llama-index-workflows",", and when it arrives through core it is imported as ",{"tag":128,"children":141},[142],"llama_index.core.workflow",". Everything else is a separate install, which is the only reason the dependency tree stays workable.",{"type":145,"ordered":146,"items":147},"list",false,[148,153,155,157,159,165],[149,150,152],"MIT licence. The current ",{"tag":128,"children":151},[130]," release is 0.14.25, published on 21 September 2026.",[154],"More than 300 integration packages on PyPI, each one a thin adapter over a core abstract class.",[156],"Workflows, the orchestration layer, is event-driven: a step receives an event and returns another, and the framework routes by type annotation rather than by a declared edge.",[158],"The event graph is validated before a run starts. Workflows where an event has no producer, a produced event has no consumer, or no terminal event is reachable are rejected.",[160,161,164],"Runs are ephemeral by default. Persistence is opt-in through ",{"tag":128,"children":162},[163],"Context.to_dict()"," snapshots, or through a runtime plugin such as DBOS that journals step transitions into a database.",[166],"Python is the practical target for the framework. Only LiteParse, the company's new local parser, ships bindings beyond Python.",{"type":122,"level":123,"id":93,"text":94},{"type":115,"content":169},[170,171,174,175,178,179,182,183,186,187,190,191,193],"Workflows is the part worth understanding, because it is also the part that outlives the framework's RAG reputation. A workflow is a subclass of ",{"tag":128,"children":172},[173],"Workflow"," whose methods are decorated with ",{"tag":128,"children":176},[177],"@step",". Each step accepts one event type and returns another; returning the start event's type begins a run, returning ",{"tag":128,"children":180},[181],"StopEvent"," ends it. Branches are ordinary ",{"tag":128,"children":184},[185],"if"," statements that return different event types, and a loop is a step that returns an event type handled earlier in the graph. Concurrency is a step that returns ",{"tag":128,"children":188},[189],"list[Event]",", paired with another step that accepts ",{"tag":128,"children":192},[189]," and acts as the fan-in.",{"type":195,"attrs":196,"inner":200,"caption":201},"diagram",{"viewBox":197,"role":198,"aria-labelledby":199},"0 0 720 350","img","li-flow-t li-flow-d","\u003Ctitle id=\"li-flow-t\">Workflows: typed events move the run forward\u003C\u002Ftitle>\u003Cdesc id=\"li-flow-d\">A start event triggers a retrieval step that fans out over eight parallel workers, a reranking step, and a terminal stop event. Below, a checkpoint step serialises the context to JSON after each finished step, and a resume path replays only the unfinished work.\u003C\u002Fdesc>\u003Ctext x=\"20\" y=\"28\" class=\"d-title\">Workflows: events move the run forward\u003C\u002Ftext>\u003Ctext x=\"700\" y=\"28\" text-anchor=\"end\" class=\"d-label\">llama-index-workflows\u003C\u002Ftext>\u003Ctext x=\"20\" y=\"56\" class=\"d-label\">ONE RUN\u003C\u002Ftext>\u003Crect x=\"20\" y=\"70\" width=\"130\" height=\"60\" rx=\"10\" class=\"d-box\" \u002F>\u003Ctext x=\"85\" y=\"100\" text-anchor=\"middle\" class=\"d-text\">question\u003C\u002Ftext>\u003Ctext x=\"85\" y=\"120\" text-anchor=\"middle\" class=\"d-small\">StartEvent\u003C\u002Ftext>\u003Cpath d=\"M150 100 H182\" class=\"d-line\" \u002F>\u003Cpath d=\"M190 100 l-9 -5 v10 z\" class=\"d-head\" \u002F>\u003Crect x=\"190\" y=\"70\" width=\"170\" height=\"60\" rx=\"10\" class=\"d-sky\" \u002F>\u003Ctext x=\"275\" y=\"100\" text-anchor=\"middle\" class=\"d-text\">retrieve\u003C\u002Ftext>\u003Ctext x=\"275\" y=\"120\" text-anchor=\"middle\" class=\"d-small\">top_k = 8\u003C\u002Ftext>\u003Cpath d=\"M360 100 H392\" class=\"d-line\" \u002F>\u003Cpath d=\"M400 100 l-9 -5 v10 z\" class=\"d-head\" \u002F>\u003Crect x=\"400\" y=\"70\" width=\"150\" height=\"60\" rx=\"10\" class=\"d-sky\" \u002F>\u003Ctext x=\"475\" y=\"100\" text-anchor=\"middle\" class=\"d-text\">rerank\u003C\u002Ftext>\u003Ctext x=\"475\" y=\"120\" text-anchor=\"middle\" class=\"d-small\">cross-encoder\u003C\u002Ftext>\u003Cpath d=\"M550 100 H582\" class=\"d-line\" \u002F>\u003Cpath d=\"M590 100 l-9 -5 v10 z\" class=\"d-head\" \u002F>\u003Crect x=\"590\" y=\"70\" width=\"110\" height=\"60\" rx=\"10\" class=\"d-accent\" \u002F>\u003Ctext x=\"645\" y=\"100\" text-anchor=\"middle\" class=\"d-text\">answer\u003C\u002Ftext>\u003Ctext x=\"645\" y=\"120\" text-anchor=\"middle\" class=\"d-small\">StopEvent\u003C\u002Ftext>\u003Cpath d=\"M275 130 V172\" class=\"d-line\" \u002F>\u003Cpath d=\"M275 182 l-5 -9 h10 z\" class=\"d-head\" \u002F>\u003Ctext x=\"20\" y=\"168\" class=\"d-label\">ONE STEP, N WORKERS\u003C\u002Ftext>\u003Crect x=\"20\" y=\"186\" width=\"160\" height=\"56\" rx=\"10\" class=\"d-box\" \u002F>\u003Ctext x=\"100\" y=\"214\" text-anchor=\"middle\" class=\"d-text\">read #1\u003C\u002Ftext>\u003Ctext x=\"100\" y=\"233\" text-anchor=\"middle\" class=\"d-small\">WorkItem\u003C\u002Ftext>\u003Cpath d=\"M180 214 H192\" class=\"d-line\" \u002F>\u003Cpath d=\"M200 214 l-9 -5 v10 z\" class=\"d-head\" \u002F>\u003Crect x=\"200\" y=\"186\" width=\"160\" height=\"56\" rx=\"10\" class=\"d-box\" \u002F>\u003Ctext x=\"280\" y=\"214\" text-anchor=\"middle\" class=\"d-text\">read #2\u003C\u002Ftext>\u003Ctext x=\"280\" y=\"233\" text-anchor=\"middle\" class=\"d-small\">WorkItem\u003C\u002Ftext>\u003Cpath d=\"M360 214 H372\" class=\"d-line\" \u002F>\u003Cpath d=\"M380 214 l-9 -5 v10 z\" class=\"d-head\" \u002F>\u003Crect x=\"380\" y=\"186\" width=\"160\" height=\"56\" rx=\"10\" class=\"d-box\" \u002F>\u003Ctext x=\"460\" y=\"214\" text-anchor=\"middle\" class=\"d-text\">read #n\u003C\u002Ftext>\u003Ctext x=\"460\" y=\"233\" text-anchor=\"middle\" class=\"d-small\">8 in flight\u003C\u002Ftext>\u003Cpath d=\"M540 214 H552\" class=\"d-line\" \u002F>\u003Cpath d=\"M560 214 l-9 -5 v10 z\" class=\"d-head\" \u002F>\u003Crect x=\"560\" y=\"186\" width=\"140\" height=\"56\" rx=\"10\" class=\"d-mint\" \u002F>\u003Ctext x=\"630\" y=\"214\" text-anchor=\"middle\" class=\"d-text\">collect\u003C\u002Ftext>\u003Ctext x=\"630\" y=\"233\" text-anchor=\"middle\" class=\"d-small\">list[Done]\u003C\u002Ftext>\u003Ctext x=\"20\" y=\"274\" class=\"d-label\">AFTER A RESTART\u003C\u002Ftext>\u003Crect x=\"20\" y=\"288\" width=\"260\" height=\"52\" rx=\"10\" class=\"d-box\" \u002F>\u003Ctext x=\"150\" y=\"312\" text-anchor=\"middle\" class=\"d-text\">checkpoint\u003C\u002Ftext>\u003Ctext x=\"150\" y=\"331\" text-anchor=\"middle\" class=\"d-small\">ctx.to_dict() JSON\u003C\u002Ftext>\u003Cpath d=\"M630 242 V314 H332\" class=\"d-line\" \u002F>\u003Cpath d=\"M320 314 l9 -5 v10 z\" class=\"d-head\" \u002F>\u003Cpath d=\"M280 314 H302\" class=\"d-line\" \u002F>\u003Cpath d=\"M310 314 l-9 -5 v10 z\" class=\"d-head\" \u002F>\u003Crect x=\"340\" y=\"288\" width=\"360\" height=\"52\" rx=\"10\" class=\"d-mint\" \u002F>\u003Ctext x=\"520\" y=\"312\" text-anchor=\"middle\" class=\"d-text\">resume from snapshot\u003C\u002Ftext>\u003Ctext x=\"520\" y=\"331\" text-anchor=\"middle\" class=\"d-small\">done steps skipped, at-least-once\u003C\u002Ftext>",[202],"The graph is derived from the step signatures and validated before the first event is dispatched. Persistence is not part of the runtime: it is a loop the team writes around it.",{"type":145,"ordered":146,"items":204},[205,210,215,221],[206,207,209],"Return ",{"tag":128,"children":208},[189]," when a step has a finite batch and can produce every work item before downstream workers start.",[211,212,214],"Accept ",{"tag":128,"children":213},[189]," when the step needs the whole batch of results before it can continue.",[216,217,220],"Call ",{"tag":128,"children":218},[219],"ctx.send_event(...)"," when the number of events is unknown in advance, or when an event has to be dispatched from outside a step.",[222,223,226,227,230],"Use ",{"tag":128,"children":224},[225],"ctx.store"," for shared per-run state, and ",{"tag":128,"children":228},[229],"Resource(...)"," for clients, models and configuration that must not be serialised into a snapshot.",{"type":115,"content":232},[233,234,236,237,240],"The type annotations are load-bearing rather than decorative. Before execution the framework derives the event graph from the step signatures and refuses to start a workflow with an unproduced event, an unconsumed event or no reachable ",{"tag":128,"children":235},[181],". That catches a class of wiring bug that a hand-written function composition does not catch at all, and it is the strongest argument for the design. The price is that a deliberately dynamic workflow has to fall back on ",{"tag":128,"children":238},[239],"ctx.send_event"," and declare which static checks to skip, which in practice means a workflow becomes progressively less checkable as it becomes more capable.",{"type":122,"level":123,"id":96,"text":97},{"type":115,"content":243},[244],"The smallest useful workflow is about twenty lines. Two install shapes are supported and they differ in the import path, which is the detail that catches people:",{"type":128,"code":246},"import asyncio\n\nfrom llama_index.core import VectorStoreIndex\nfrom workflows import Workflow, step\nfrom workflows.events import Event, StartEvent, StopEvent\n\n\nclass Answered(Event):\n    question: str\n    answer: str\n\n\nclass TriageFlow(Workflow):\n    index: VectorStoreIndex\n\n    @step\n    async def retrieve(self, ev: StartEvent) -> Answered:\n        retriever = self.index.as_retriever(similarity_top_k=8)\n        nodes = await retriever.aretrieve(ev.question)\n        best = max(nodes, key=lambda n: n.score or 0.0)\n        return Answered(question=ev.question, answer=best.node.get_content())\n\n    @step\n    async def answer(self, ev: Answered) -> StopEvent:\n        return StopEvent(result=ev.answer)\n\n\nasync def main():\n    flow = TriageFlow(index=VectorStoreIndex.from_documents(documents), timeout=60)\n    result = await flow.run(question=\"What is the refund window?\")\n    print(result.result)\n\nasyncio.run(main())",{"type":115,"content":248},[249,252,253,256,257,260,261,264,265,268],{"tag":128,"children":250},[251],"run()"," returns a ",{"tag":128,"children":254},[255],"WorkflowHandler",". It is awaitable, and keeping the handler instead of awaiting it inline also gives access to ",{"tag":128,"children":258},[259],"stream_events()"," for progress reporting. The ",{"tag":128,"children":262},[263],"timeout"," argument is in seconds and is set on the constructor. Every step is async by design, so a standalone script needs a single ",{"tag":128,"children":266},[267],"asyncio.run"," entry point; inside FastAPI or a notebook it is not necessary.",{"type":270,"variant":271,"title":272,"body":273},"callout","tip","Choose the install shape deliberately",[274],[275,276,278,279,281,282,284,285,287],"If only the orchestration is needed, install ",{"tag":128,"children":277},[138]," alone; install ",{"tag":128,"children":280},[130]," when the retrieval components come with it, because that package re-exports Workflows under ",{"tag":128,"children":283},[142],". The starter package ",{"tag":128,"children":286},[134]," pulls in a default selection of integrations, which most applications replace on the first day anyway.",{"type":122,"level":123,"id":99,"text":100},{"type":115,"content":290},[291,292,294,295,297,298,301,302,305,306,309],"Workflows are ephemeral by default: once ",{"tag":128,"children":293},[251]," returns, the state is gone and the next run starts from nothing. For a fan-out over hundreds of documents that should not restart from zero, the documented mechanism is a checkpoint loop. ",{"tag":128,"children":296},[163]," serialises the in-flight events and the state store, ",{"tag":128,"children":299},[300],"Context.from_dict()"," rebuilds them, and ",{"tag":128,"children":303},[304],"run(ctx=...)"," continues in a different process. There is no built-in checkpointer to switch on: the run emits an internal ",{"tag":128,"children":307},[308],"StepStateChanged"," event when a step finishes, and that is the signal to snapshot.",{"type":128,"code":311},"import json\n\nfrom workflows.events import StepState, StepStateChanged\n\nhandler = flow.run(question=q)\n\nasync for ev in handler.stream_events(expose_internal=True):\n    if isinstance(ev, StepStateChanged) and ev.step_state == StepState.NOT_RUNNING:\n        json.dump(handler.ctx.to_dict(), open(\"run.json\", \"w\"))\n\nresult = await handler\n\n# after a restart: resume from the last snapshot\nctx = Context.from_dict(flow, json.load(open(\"run.json\")))\nresult = await flow.run(ctx=ctx)",{"type":115,"content":313},[314,315,318,319,322,323,326],"Two properties of this design surface in operations. Resume is at-least-once: a step that was mid-execution when the snapshot was taken is rewound and runs again, so up to ",{"tag":128,"children":316},[317],"num_workers"," items are duplicated. And the snapshot is JSON, so a value the serialiser cannot encode makes ",{"tag":128,"children":320},[321],"to_dict()"," raise and the whole snapshot fail, not just the offending field. Heavy inputs therefore belong in a ",{"tag":128,"children":324},[325],"Resource",", which is re-created on resume instead of being serialised. Teams that would rather not own the loop can use the DBOS runtime plugin, which journals step transitions into a database and needs no checkpoint code.",{"type":122,"level":123,"id":102,"text":103},{"type":115,"content":329},[330],"The weaknesses are structural rather than bugs. Breadth is a maintenance surface: with hundreds of integrations, an upgrade can move the model wrapper you did not mean to touch, and pinning one integration often means pinning core. The high-level API hides enough that a prototype can reach production without anyone recording which chunk size, which top-k and which prompt template produced the answer; the defaults are convenient and are not documented as defaults. Durability is opt-in and hand-written, which is the opposite of what a long-running batch job wants. And the company behind the framework has publicly narrowed its focus, which is awkward to evaluate in 2026.",{"type":332,"head":333,"rows":342},"table",[334,336,338,340],[335],"Framework",[337],"Orchestration model",[339],"Durability and state",[341],"Where it wins",[343,355,366,377],[344,349,351,353],[345],{"tag":346,"children":347},"strong",[348],"LlamaIndex Workflows",[350],"Event-driven steps, control flow in plain Python",[352],"No built-in checkpointer; context snapshots written by the team, or the DBOS runtime plugin",[354],"Retrieval and document components live in the same library",[356,360,362,364],[357],{"tag":346,"children":358},[359],"LangGraph",[361],"Explicit state graph with conditional edges",[363],"Durable execution and checkpointers are the default",[365],"State transitions are the artefact, and stay inspectable as a graph",[367,371,373,375],[368],{"tag":346,"children":369},[370],"Haystack",[372],"Pipelines of typed components",[374],"Per-component error branches and retries",[376],"A stable component catalogue for retrieval-heavy applications",[378,382,384,386],[379],{"tag":346,"children":380},[381],"DSPy",[383],"Declarative modules, optimised offline against a metric",[385],"None; it is not an orchestration runtime",[387],"Prompt and module tuning, before any serving code exists",{"type":115,"content":389},[390],"Read the durability column across and the practical split is legible. LangGraph makes checkpointing the default and buys that by making the graph explicit, which costs cognition and pays in legibility. Workflows keeps control in plain Python, which reads better and inspects worse: a workflow that fans out over 500 documents is 500 concurrent calls whose ordering no tool is helping you see. For a team whose work is to reason about state transitions, that is the wrong trade. For a team that wants to write ordinary Python and have it behave, it is the right one.",{"type":115,"content":392},[393,394,397],"A second caveat belongs here. A dynamic workflow loses static analysis, and the documentation is explicit that unreachable steps and one-off events are exactly what those checks cannot see. Migrating a hand-drawn graph into Workflows tends to reach for ",{"tag":128,"children":395},[396],"skip_graph_checks"," early, which quietly disables the check that catches dead branches, which is the same check that would have caught the wiring mistake in the first place.",{"type":122,"level":123,"id":105,"text":106},{"type":115,"content":400},[401],"The repository README now carries an unmissable note: the current focus of LlamaIndex is document parsing and extraction, and LlamaParse is the company's enterprise platform for it. That changes what a maintenance budget is funding. The integration packages still ship and still work; what is no longer guaranteed is that each of them is extended when a new provider appears.",{"type":145,"ordered":146,"items":403},[404,406,408,410,415],[405],"LlamaParse is the paid product: agentic OCR, parsing, extraction and indexing, sold in credits rather than in seats.",[407],"LiteParse is the open-source counterweight: a Rust parser that runs locally with no LLM, no cloud dependency and no API key, with bindings for TypeScript, Python, Rust and browser WASM.",[409],"ParseBench and ExtractBench are the company's own public benchmarks for parsing and extraction.",[411,412,414],"The framework stays MIT-licensed and published on PyPI, with ",{"tag":128,"children":413},[130]," at 0.14.25 as of 21 September 2026.",[416],"The result is a split strategy: open tooling for local parsing, a hosted platform for hard documents, and the agent framework in between as the integration surface.",{"type":115,"content":418},[419],"That is a defensible business decision and a mild warning for anyone choosing a framework now. The parts of the stack most likely to be maintained are the parts behind the paywall, and the MIT core is what remains useful as a library. Read it as an argument for keeping the framework's blast radius small: use Workflows for orchestration, keep loading and parsing in house where that is possible, and be explicit about which calls leave your infrastructure.",{"type":270,"variant":421,"title":422,"body":423},"note","LlamaParse pricing, in numbers",[424],[425],"The pricing page sells credits, not seats: 1,000 credits at $1.25, 10,000 credits on the free tier, 40,000 on the $50 starter tier and 400,000 on the $500 pro tier, with pay-as-you-go caps of $500 and $5,000 a month. Concurrent parse jobs are 5 on free and starter, 20 on pro and 100 on enterprise. Parse, extract, classify and index all draw the same balance, and the same table lists smart result caching with a re-parse at zero credits, which is worth confirming for a specific parse configuration rather than assuming.",{"type":122,"level":123,"id":108,"text":109},{"type":115,"content":428},[429],"The verdict is that LlamaIndex remains the most complete answer to a narrow question, how to get documents into an LLM application without writing the integration layer yourself, and a mediocre answer to the broader question of how to orchestrate an agent. Workflows is genuinely good at turning branching logic into typed, validated Python, and its at-least-once checkpoint model is honest about its own failure semantics. What the framework does not offer is a runtime to point at and watch: no state graph to inspect, no persistence on by default, and a maintenance direction that has plainly moved elsewhere.",{"type":145,"ordered":431,"items":432},true,[433,435,437,439,441,443],[434],"Use it when most of your data is documents and the connector, chunker, embedder and reranker abstractions are already written for you. That is a real saving, and it was the original purpose.",[436],"Use Workflows on its own as a small library when the orchestration is branching, looping Python currently tangled inside asyncio. The typed event graph and the pre-run validation are the reason.",[438],"Do not pick it for a graph that has to be reasoned about. If the state transitions are the artefact under scrutiny, an explicit graph beats Python control flow.",[440],"Do not pick it for the hosted platform. LlamaParse, Extract and the index service are a separate paid product with credit pricing, and tying your ingestion bill to a framework is a decision rather than a default.",[442],"Avoid it for a TypeScript or Go stack. The core is Python; only the new LiteParse parser ships broader bindings.",[444],"Re-evaluate in a year if the integration breadth is load-bearing. With the company's focus on parsing and extraction, the long tail of vector store and embedder integrations is the part most exposed to slow maintenance.",{"type":446,"content":447},"quote",[448],"The current focus of LlamaIndex is to build the best AI-powered engine for document parsing and extraction.",{"type":115,"content":450},[451],"That sentence sits in the project README rather than in a blog post, which is unusual and worth noticing: the framework's own maintainers are the ones stating where the roadmap is going. Read as engineering, it says the orchestration layer is maintained but is not the destination, and the paid document pipeline is.",{"type":122,"level":123,"id":111,"text":112},{"type":145,"ordered":431,"items":454},[455,459,462,465,468,471,474,477,480],[456],{"tag":457,"href":25,"children":458},"a",[31],[460],{"tag":457,"href":34,"children":461},[33],[463],{"tag":457,"href":37,"children":464},[36],[466],{"tag":457,"href":40,"children":467},[39],[469],{"tag":457,"href":43,"children":470},[42],[472],{"tag":457,"href":46,"children":473},[45],[475],{"tag":457,"href":49,"children":476},[48],[478],{"tag":457,"href":52,"children":479},[51],[481],{"tag":457,"href":55,"children":482},[54],[484,549,598,662],{"slug":485,"published":486,"minutes":487,"category":7,"tags":488,"keywords":493,"about":500,"sources":504,"cover":541,"og":542,"expertise":58,"locales":543,"lang":60,"title":544,"description":545,"coverAlt":546,"url":507,"pricing":547,"kind":548},"mcp-reference-servers","2026-09-25",9,[489,490,491,492],"MCP","Reference servers","Tool protocol","Server SDKs",[494,495,496,497,498,499],"mcp reference servers","modelcontextprotocol servers github","write an mcp server","mcp server examples","mcp server sdk","mcp server security",[501],{"name":502,"url":503},"Model Context Protocol","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FModel_Context_Protocol",[505,508,511,514,517,520,523,526,529,532,535,538],{"title":506,"url":507},"MCP reference servers repository","https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fservers",{"title":509,"url":510},"Repository README and server list","https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fservers\u002Fblob\u002Fmain\u002FREADME.md",{"title":512,"url":513},"Security policy","https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fservers\u002Fblob\u002Fmain\u002FSECURITY.md",{"title":515,"url":516},"Release process and trusted publishing","https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fservers\u002Fblob\u002Fmain\u002FRELEASING.md",{"title":518,"url":519},"Filesystem server README","https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fservers\u002Fblob\u002Fmain\u002Fsrc\u002Ffilesystem\u002FREADME.md",{"title":521,"url":522},"Everything server feature list","https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fservers\u002Fblob\u002Fmain\u002Fsrc\u002Feverything\u002Fdocs\u002Ffeatures.md",{"title":524,"url":525},"MCP Registry","https:\u002F\u002Fregistry.modelcontextprotocol.io\u002F",{"title":527,"url":528},"Archived reference servers","https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fservers-archived",{"title":530,"url":531},"Model Context Protocol documentation","https:\u002F\u002Fmodelcontextprotocol.io\u002F",{"title":533,"url":534},"TypeScript MCP SDK","https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Ftypescript-sdk",{"title":536,"url":537},"Python MCP SDK","https:\u002F\u002Fgithub.com\u002Fmodelcontextprotocol\u002Fpython-sdk",{"title":539,"url":540},"FastMCP on PyPI","https:\u002F\u002Fpypi.org\u002Fproject\u002Ffastmcp\u002F","\u002Fimages\u002Fblog\u002Fmcp-reference-servers\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fmcp-reference-servers\u002Fog.jpg",[60,61,62],"MCP reference servers: what they demonstrate and what they omit","A review of modelcontextprotocol\u002Fservers: seven reference servers, what each one teaches, the SDK versions behind them and why none of them should reach production.","Seven reference servers fanning out from a single MCP client over stdio","MIT","Protocol tooling",{"slug":550,"published":551,"minutes":6,"category":7,"tags":552,"keywords":558,"about":566,"sources":573,"cover":590,"og":591,"expertise":58,"locales":592,"lang":60,"title":593,"description":594,"coverAlt":595,"url":596,"pricing":597,"kind":553},"aider","2026-09-23",[553,554,555,556,557],"Coding agent","Terminal","Git workflow","BYO key","Open source",[550,559,560,561,562,563,564,565],"aider vs claude code","aider polyglot benchmark","ai pair programming terminal","aider leaderboard","open source coding agent","aider architect mode","aider install",[567,570],{"name":568,"url":569},"Aider","https:\u002F\u002Faider.chat\u002F",{"name":571,"url":572},"Aider on GitHub","https:\u002F\u002Fgithub.com\u002FAider-AI\u002Faider",[574,576,579,582,585,587],{"title":575,"url":569},"Aider website",{"title":577,"url":578},"Aider LLM leaderboards","https:\u002F\u002Faider.chat\u002Fdocs\u002Fleaderboards\u002F",{"title":580,"url":581},"Aider linting and testing","https:\u002F\u002Faider.chat\u002Fdocs\u002Fusage\u002Flint-test.html",{"title":583,"url":584},"Aider token limits","https:\u002F\u002Faider.chat\u002Fdocs\u002Ftroubleshooting\u002Ftoken-limits.html",{"title":586,"url":572},"Aider repository on GitHub",{"title":588,"url":589},"aider-chat on PyPI","https:\u002F\u002Fpypi.org\u002Fproject\u002Faider-chat\u002F","\u002Fimages\u002Fblog\u002Faider\u002Fcover.webp","\u002Fimages\u002Fblog\u002Faider\u002Fog.jpg",[60,61,62],"Aider review: git-first pair programming in the terminal","A review of Aider 0.86.2, an Apache-2.0 terminal pair programmer whose benchmark ranks models honestly and whose release cadence has stopped.","Cover art for the Aider review: a terminal session turning a single request into a row of git commits","https:\u002F\u002Faider.chat","Free · BYO API key",{"slug":599,"published":600,"minutes":6,"category":7,"tags":601,"keywords":605,"about":614,"sources":624,"cover":655,"og":656,"expertise":58,"locales":657,"lang":60,"title":658,"description":659,"coverAlt":660,"url":627,"pricing":661,"kind":9},"openai-agents-sdk","2026-09-11",[602,603,604,489,11],"Agent runtime","Tracing","Guardrails",[606,607,608,609,610,611,612,613],"openai agents sdk","openai agents sdk vs langgraph","python agent framework comparison","openai agents sdk guardrails","agent run tracing tool calls","openai agents sdk human in the loop","openai-agents pypi","agents sdk vs responses api",[615,618,621],{"name":616,"url":617},"Model context protocol","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FModel_context_protocol",{"name":619,"url":620},"Software framework","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSoftware_framework",{"name":622,"url":623},"Agentic AI","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FAgentic_AI",[625,628,631,634,637,640,643,646,649,652],{"title":626,"url":627},"OpenAI Agents SDK documentation: Intro, and Agents SDK or Responses API","https:\u002F\u002Fopenai.github.io\u002Fopenai-agents-python\u002F",{"title":629,"url":630},"OpenAI Agents SDK documentation: Running agents","https:\u002F\u002Fopenai.github.io\u002Fopenai-agents-python\u002Frunning_agents\u002F",{"title":632,"url":633},"OpenAI Agents SDK documentation: Guardrails","https:\u002F\u002Fopenai.github.io\u002Fopenai-agents-python\u002Fguardrails\u002F",{"title":635,"url":636},"OpenAI Agents SDK documentation: Human-in-the-loop","https:\u002F\u002Fopenai.github.io\u002Fopenai-agents-python\u002Fhuman_in_the_loop\u002F",{"title":638,"url":639},"OpenAI Agents SDK documentation: Tracing","https:\u002F\u002Fopenai.github.io\u002Fopenai-agents-python\u002Ftracing\u002F",{"title":641,"url":642},"OpenAI Agents SDK documentation: Configuration","https:\u002F\u002Fopenai.github.io\u002Fopenai-agents-python\u002Fconfig\u002F",{"title":644,"url":645},"openai-agents 0.23.1 on PyPI, release history and licence","https:\u002F\u002Fpypi.org\u002Fproject\u002Fopenai-agents\u002F",{"title":647,"url":648},"OpenAI: The next evolution of the Agents SDK (15 April 2026)","https:\u002F\u002Fopenai.com\u002Findex\u002Fthe-next-evolution-of-the-agents-sdk\u002F",{"title":650,"url":651},"OpenAI API documentation: Agents, comparison of the three runtimes","https:\u002F\u002Fdevelopers.openai.com\u002Fapi\u002Fdocs\u002Fguides\u002Fagents",{"title":653,"url":654},"Arize: AI agent frameworks compared (1 October 2026)","https:\u002F\u002Farize.com\u002Fai-agents\u002Fagent-frameworks\u002F","\u002Fimages\u002Fblog\u002Fopenai-agents-sdk\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fopenai-agents-sdk\u002Fog.jpg",[60,61,62],"OpenAI Agents SDK: a small agent runtime with sharp edges","A review of the OpenAI Agents SDK: the runner loop, tracing, guardrails and approvals, plus what the release churn and the Responses-only features cost.","Diagram of the Agents SDK runner loop: input, agent, model call, final output, guardrails, and tool calls feeding back into the input","MIT · API pay per token",{"slug":663,"published":664,"minutes":487,"category":7,"tags":665,"keywords":670,"about":677,"sources":687,"cover":708,"og":709,"expertise":58,"locales":710,"lang":60,"title":711,"description":712,"coverAlt":713,"url":714,"pricing":715,"kind":553},"openhands","2026-09-09",[553,666,667,668,669],"Sandboxed execution","Automations","Self-hosted","MIT licence",[663,671,672,673,674,675,563,676],"openhands self-host","open hands coding agent","openhands vs claude code","agent canvas","openhands docker sandbox","openhands cloud pricing",[678,681,684],{"name":679,"url":680},"OpenHands","https:\u002F\u002Fwww.openhands.dev",{"name":682,"url":683},"OpenHands on GitHub","https:\u002F\u002Fgithub.com\u002FOpenHands\u002FOpenHands",{"name":685,"url":686},"Intelligent agent","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FIntelligent_agent",[688,690,693,696,699,702,705],{"title":689,"url":683},"OpenHands README",{"title":691,"url":692},"OpenHands licence (MIT)","https:\u002F\u002Fgithub.com\u002FOpenHands\u002FOpenHands\u002Fblob\u002Fmain\u002FLICENSE",{"title":694,"url":695},"Agent Canvas 1.25.0 release notes","https:\u002F\u002Fdocs.openhands.dev\u002Fopenhands\u002Fusage\u002Fagent-canvas\u002Frelease-notes\u002Fv1.25.0.md",{"title":697,"url":698},"OpenHands sandbox overview","https:\u002F\u002Fdocs.openhands.dev\u002Fopenhands\u002Fusage\u002Fsandboxes\u002Foverview.md",{"title":700,"url":701},"OpenHands quick start","https:\u002F\u002Fdocs.openhands.dev\u002Fopenhands\u002Fusage\u002Finstallation",{"title":703,"url":704},"OpenHands pricing","https:\u002F\u002Fwww.openhands.dev\u002Fpricing",{"title":706,"url":707},"Introducing the OpenHands Index","https:\u002F\u002Fwww.openhands.dev\u002Fblog\u002Fintroducing-the-openhands-index","\u002Fimages\u002Fblog\u002Fopenhands\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fopenhands\u002Fog.jpg",[60,61,62],"OpenHands: the open-source coding agent you operate","OpenHands 1.25.0 is an MIT-licensed coding agent platform with a web canvas, a CLI, sandboxed execution and scheduled automations. A review of where it is strong and where it gets heavy.","Cover artwork for the OpenHands review showing a loop from task to agent to sandboxed run and back","https:\u002F\u002Fgithub.com\u002FAll-Hands-AI\u002FOpenHands","Free · self-host",1791383548874]