Dynamiq: A Python Orchestration Framework for LLM Agents and Workflows
Dynamiq is an orchestration framework for agentic AI and LLM applications
At a glance
- What is it?
- Dynamiq is an Apache-2.0 Python framework that wires LLM nodes, agents and tools into explicit workflows. It is a reasonable fit if you want your orchestration graph expressed in code you own, and a poor fit if you want a hosted platform or stable long-term APIs.
- Who is it for?
- Adopt Dynamiq if you are a Python team that wants agent and RAG orchestration expressed as explicit nodes and flows in your own codebase, and you are willing to track a project that ships a release most weeks. Do not adopt it if you need stable public APIs across upgrade cycles, a hosted control plane, or orchestration in a non-Python service, because the README shows a code-first library with no server component and no stated compatibility policy.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The Problem Dynamiq Targets: Agent Logic Spread Across Application Code
Building an LLM feature usually starts as a single call and ends as a graph. A prompt goes to a model, the model asks for a tool, the tool returns data, a second model rewrites the result, and somewhere in between you need retries, parallelism and a record of what each step received. Without a framework, that logic lives in the same functions as your HTTP handlers and database access, and it becomes hard to change one step without touching the others.
Dynamiq addresses that by making each step a node. The README describes it as "an orchestration framework for agentic AI and LLM applications", and the examples bear that out: an LLM is a node, a tool is a node, an agent is a node, and a Workflow holds nodes and runs them. The audience is Python developers building RAG pipelines and tool-using agents who want the wiring to be explicit and inspectable rather than hidden inside a chain abstraction.
The topics listed on the repository (agents, generative-ai, gpt, llm, llmops, rag) match that scope. This is not a serving layer or a gateway. It is the layer where you describe what should happen and in what order.
Nodes, Connections, Flows: The Actual Mechanism
Three objects do most of the work. A connection holds credentials, for example OpenAIConnection(api_key="OPENAI_API_KEY") or E2BConnection(api_key="E2B_API_KEY"). A node wraps a capability and takes a connection, an id, and configuration such as model, temperature and max_tokens. A flow holds nodes and decides execution order.
In the simple LLM example, the node is constructed with a Prompt built from Message objects, where the message content contains a template placeholder in double braces, {{ text }}. Calling llm.run(input_data={"text": "Hola Mundo!"}) fills that placeholder and returns an object whose output attribute holds the result. That is the whole data path for a single step: input dict in, template rendered, model called, result object out.
Agents add a loop. The ReAct agent example passes an LLM, a list of tools, a role string, and max_loops=10. The README's comment describes max_loops as a "limit on the number of processing loops", which is the only stated guard against an agent that keeps calling tools. The agent is run with await agent.run(input_data={"input": "..."}), and the example reads the answer from result.output.get("content"), so the returned output is a dict rather than a plain string. Note the shape difference between a bare LLM node (result.output) and an agent (result.output.get("content")); the two are not interchangeable.
Workflows compose nodes. The README shows wf.flow.add_nodes(first_agent) called twice, with the comment that Workflow "automatically handles running the agents in parallel where possible". It also shows the equivalent construction as Workflow(flow=Flow(nodes=[agent_first, agent_second])). Sequential execution is expressed differently, by importing InputTransformer and NodeDependency from dynamiq.nodes.node and attaching dependencies, which is how one node's output is routed into the next node's input. The README's sequential example is truncated mid-definition, so the exact dependency syntax is not fully visible in the supplied material. The documentation site is the place to confirm it.
Installing and Running a First Flow
The install path is short. From PyPI: pip install dynamiq. From source: git clone https://github.com/dynamiq-ai/dynamiq.git, then cd dynamiq, then uv sync. The package requires Python 3.10 or later, per the badge in the README. The source route assumes uv is already available on the machine.
The smallest working program needs four imports from the package: dynamiq.nodes.llms.openai.OpenAI, dynamiq.connections.OpenAI as a connection, and dynamiq.prompts.Prompt and dynamiq.prompts.Message. Construct the Prompt with a message whose role is "user" and whose content contains a {{ text }} placeholder, construct the OpenAI node with id, connection, model, temperature, max_tokens and prompt, then call run with a dict containing the key the template expects.
API keys are passed as strings to the connection constructors in every README example, for instance OpenAI(api_key="OPENAI_API_KEY") and E2B(api_key="E2B_API_KEY"). The examples show literal placeholder strings rather than reads from the environment, so if you follow them verbatim you will need to substitute real values or wire in your own secret handling. The framework does not appear to prescribe one.
For the agent example, the imports widen to dynamiq.nodes.agents.Agent and dynamiq.nodes.tools.e2b_sandbox.E2BInterpreterTool. The README also notes that code sandboxes are available via Daytona (DaytonaInterpreterTool) and AWS Bedrock AgentCore (BedrockAgentCoreInterpreterTool, using the standard AWS connection). Only the E2B path has a full worked example in the supplied material.
Release Cadence and the Upgrade Bill It Implies
The release history shown is dense: v0.61.0 on 2026-08-18, v0.62.0 on 2026-08-25, v0.63.0 on 2026-09-08, with the last push to main on 2026-09-09. Three minor releases in roughly three weeks, all still on a 0.x version line.
That cadence has a direct cost. In pre-1.0 Python libraries, minor version bumps are where breaking changes usually land, and nothing in the supplied material states a deprecation policy or a compatibility guarantee. If you build on Dynamiq, the practical move is to pin an exact version in your dependency file and treat upgrades as scheduled work with a test run, not as background noise. The README's own examples are the cheapest regression suite you have: if the parallel agents snippet stops producing output under the keys first_agent.id and second_agent.id, something in the result shape changed.
The upside of the cadence is that the sandbox integrations listed in the README (E2B, Daytona, Bedrock AgentCore) suggest active work on tool coverage rather than a stalled project. The repository is not archived. Beyond that, the supplied material gives no information about maintainer count, funding, or long-term support commitments, so those questions are open.
Where Dynamiq Is the Wrong Tool
The most concrete limitation visible in the material is the shape of the output. A bare node returns an object whose output is the model result; an agent returns a dict you index with get("content"); a workflow returns a dict keyed by node id, and the README's parallel example reaches two levels deep, result.output[first_agent.id].get("input").get("input") and result.output[first_agent.id].get("output").get("content"). Three different result shapes for three levels of composition. That is workable, but it means downstream code that consumes results is coupled to the structure of the graph, and refactoring a flow can ripple into callers.
A second limitation is the agent loop. max_loops=10 is the only stated bound in the ReAct example, and the README does not describe what happens when the limit is reached: whether the agent raises, returns a partial answer, or silently stops. If your agent can call a sandbox interpreter, that behaviour matters before you put it near anything expensive.
Third, this is a Python-only library. Nothing in the material suggests a server, a control plane, or a language-agnostic runtime. If your orchestration needs to be invoked from a JVM service or a TypeScript frontend, Dynamiq is not the layer for that.
Finally, the documentation is a separate site, and the README is thin on operational topics. There is no mention of tracing, evaluation, cost accounting, or deployment. Those may exist in the docs, but they are not evidenced in the supplied material, and you should confirm them before assuming they are covered.
Compared with LangGraph: Explicit Graphs vs. State Machines
The closest widely used alternative in Python is LangGraph, which models an application as a state machine: you define a typed state object, add nodes that read and write that state, and connect them with edges, including conditional edges. The unit of composition is the state schema, and control flow is expressed as transitions between named nodes.
Dynamiq takes a different route. There is no shared state object in the examples. Each node receives an input dict, and when you need one node's output to feed another, you attach a dependency using InputTransformer and NodeDependency from dynamiq.nodes.node. Parallelism is implicit: adding two nodes to a Workflow runs them in parallel where possible, per the README comment, rather than being declared as fan-out edges. Results come back keyed by node id.
The practical difference is where the complexity sits. LangGraph pushes you toward defining state up front and reasoning about transitions; Dynamiq pushes you toward declaring nodes and letting the flow resolve order. Dynamiq's model is quicker to read for a linear or fan-out pipeline. LangGraph's is easier to reason about when the graph has cycles or when many nodes need to read overlapping pieces of shared context, because the state contract is explicit.
Neither approach is free. Dynamiq's implicit parallelism means you need to know which nodes are independent; the README's comment that Workflow handles parallel execution "where possible" leaves the resolution rules to the documentation. If you have already built on LangGraph, the migration is not mechanical: node signatures, result shapes and dependency wiring all differ.
Licence and What to Verify Before Adopting
Dynamiq is licensed under Apache-2.0, the same permissive licence used by much of the Python data and ML stack. In practical terms that permits commercial use, modification and redistribution, with the usual requirements around retaining notices and stating changes. This is a description of the licence identifier, not legal advice; if you are embedding the library in a distributed product or modifying it, have counsel read the actual LICENSE file in the repository.
One licence-adjacent point is worth flagging. The README's agent examples call out to third-party sandbox services: E2B, Daytona and AWS Bedrock AgentCore. Those are separate services with their own terms and their own billing, reached through connection objects that take API keys. The Apache-2.0 grant covers the Dynamiq code, not those services, and running agent-generated code inside a sandbox is a decision with its own risk profile regardless of the framework's licence.
What to verify first, concretely: confirm that the imports in the sequential workflow example (InputTransformer and NodeDependency from dynamiq.nodes.node) exist in the version you pin, since the README's snippet is cut off before the wiring is shown. Confirm the result shape your chosen composition level returns, because node, agent and workflow differ. Confirm what max_loops does when it is exhausted. And confirm, from the documentation site rather than the README, whether tracing and evaluation are built in or left to you, because the supplied README does not say.
Editorial conclusion
Adopt Dynamiq if you are a Python team that wants agent and RAG orchestration expressed as explicit nodes and flows in your own codebase, and you are willing to track a project that ships a release most weeks. Do not adopt it if you need stable public APIs across upgrade cycles, a hosted control plane, or orchestration in a non-Python service, because the README shows a code-first library with no server component and no stated compatibility policy. Before committing, pin the version you install, run the two parallel agents example from the README against your own model provider, and check whether the InputTransformer and NodeDependency imports used in the sequential example resolve in that pinned version.
Community notes