Show HN: AQVEN – typed LLM workflows, checked before a token is spent AQVEN, a source-available Python framework and local Studio for building typed LLM workflows, launched in alpha with a validation command that checks every connection and simulates every flow before any tokens are spent. AQVEN stores each workflow as typed files in a repository — a flow, one file per step, prompts in Markdown, and declared types, agents and tools — and connects to coding agents including Claude Code and Codex through its MCP server, which registers via a generated .mcp.json. The framework requires Python >=3.14,<3.15 and installs via `uv tool install aqven`; real runs spend against an OPENROUTER_API_KEY, while `aqven check` needs neither a key nor the network. AQVEN is a Python framework and a local Studio for building reliable LLM workflows: multi-step pipelines of models, tools and human review. Your coding agent runs the experiments. You see the evidence and decide. Documentation https://aqvenstudio.com · Quickstart https://aqvenstudio.com/start/quickstart/ · Use cases https://aqvenstudio.com/use-cases/ · Studio https://aqvenstudio.com/studio/ · llms.txt https://aqvenstudio.com/llms.txt AQVEN keeps an AI workflow as typed files in your repository: a flow, one file per step, prompts in Markdown, and declared types, agents and tools. aqven check validates every connection and simulates every flow before you spend a token. Studio, a local browser app in the same install, shows each run step by step. Your coding agent Claude Code, Codex or any MCP client works on the same files through AQVEN's MCP server, and runs experiments whose verdicts AQVEN computes. Note AQVEN is in alpha: expect changes between releases. It is source-available, not open source. See License license . | Find https://aqvenstudio.com/use-cases/ find | "What am I missing?" Your agent explores cases and variants you wouldn't try yourself. | | Explain https://aqvenstudio.com/use-cases/ explain | "Why did this fail?" Follow a bad answer back to the step where it started. | | Compare https://aqvenstudio.com/use-cases/ compare | "What should I change?" Models and prompts side by side, with cost and latency. | | Confirm https://aqvenstudio.com/use-cases/ confirm | "Can I trust this change?" A verdict on held-out cases that is allowed to say inconclusive. | | Build https://aqvenstudio.com/use-cases/ build | "How do I keep it readable as it grows?" Typed files in your repo, checked before a run costs a token. | You need uv https://docs.astral.sh/uv/getting-started/installation/ . AQVEN runs on Python 3.14, and uv fetches it for you. uv tool install aqven aqven new my project --template minimal --provider openrouter aqven new writes the project, installs its environment with uv sync and generates typed Python models. It also prepares the project for a coding agent: AGENTS.md , CLAUDE.md , an .mcp.json that registers AQVEN's MCP server, and Claude Code hooks that run aqven check as the agent works. A real run needs a model key: copy my project/.env.example to my project/.env and set OPENROUTER API KEY in it. A run spends against whichever key it finds, in .env or exported in your shell, so a real run is never free. aqven check needs neither a key nor the network. | Platform | Status | |---|---| | Linux | The full CI suite runs on ubuntu-latest on every change. | | macOS | Primary development platform. The install path and the offline aqven check are smoke-tested from a built wheel by the Platform smoke workflow; the full test suite is not yet run on macOS in CI. | | Windows | The install path is not yet proven: the Platform smoke workflow builds and installs the wheel on a Windows runner and runs aqven check , but nothing beyond that is tested there. If it breaks for you, open an issue https://github.com/lastonoga/AQVEN/issues — help making AQVEN a proven Windows citizen is welcome. | Python version policy. AQVEN requires =3.14,<3.15 : the engine runs on exactly one minor version, so step code behaves the same everywhere. uv fetches 3.14 for you. Python 3.15 was released in October 2026; support is planned, and it will land in a release when the engine, its dependencies and CI are green on it — we are not promising a date. Start Claude Code in the project and approve the aqven server when it asks: cd my project claude Then hand it a task. It builds the flow, runs aqven check after every change, and works in rounds: Build a flow that reads an incoming support e-mail and returns its intent defect, delivery or question and a one-line summary. Done means: the intent is right on more than 90% of held-out cases, and a case costs under $0.002. Work in rounds: explore on working cases, confirm once on held-out cases. Stop when every "done" criterion is confirmed, or when you have spent $5. Then report FINDINGS.md, the decisions you made and the risks that are left. Open Studio next to it to watch every run, or chat from there: its chat panel https://aqvenstudio.com/studio/chat/ runs Claude Code or Codex on the same project. uv run aqven dev my project For Codex, Cursor or another MCP client, see How to set up a coding agent outside Studio https://aqvenstudio.com/mcp-cli/set-up-an-agent-outside-studio/ . aqven new already puts AQVEN's skills into the project; to have them in Claude Code everywhere, install them as a plugin: /plugin marketplace add lastonoga/AQVEN , then /plugin install aqven@aqven . Check the new project: cd my project uv run aqven check my project errors: 0, warnings: 0 aqven check validates every file, then simulates a run of every flow with stand-ins for the model calls. Run it after every change. With a key in .env , run the flow for real, one line per event as it happens: echo '{"text": "How long does a light strip last?", "tone": "friendly"}' question.json uv run aqven run answer question --root my project --input question.json This is the project, trimmed to the files that define the workflow: my project/ AGENTS.md CLAUDE.md .mcp.json .claude/ pyproject.toml my project/ aqven.yaml agents/assistant.yaml tools/count words.yaml types/enums/tone.yaml types/records/question.yaml types/records/answer.yaml flows/answer question/ flow.yaml nodes/prepare/ prepare.node.yaml prepare.py nodes/reply/ reply.node.yaml reply.inference.yaml reply.prompt.md flows/answer question/flow.yaml declares the input, the output and the order of the steps: apiVersion: "aqven/v1" kind: "Flow" description: "Cleans up a question and answers it in the requested tone" input: "Question" output: "Answer" returns: - name: "reply" from: "$reply.out.reply" - name: "tone" from: "$input.tone" order: - "prepare" - "reply" flows/answer question/nodes/reply/reply.node.yaml is a model step. It takes text from the prepare step and tone from the flow input: apiVersion: "aqven/v1" kind: "Node" node: "llm" description: "Answers the prepared question with the assistant agent" agent: "assistant" in: - name: "text" from: "$prepare.out.text" - name: "tone" from: "$input.tone" reply.prompt.md is the prompt, a file of its own. reply.inference.yaml declares the typed input and output of the call. Answer the question in a {{ tone }} tone, in at most 120 words. If you are not sure a draft fits, count its words with the count words tool.