Project Structure¶
How to lay out a real latent project — agents, tools, guardrails, flows, and data — using the conventions the Latent team follows in production agents and that Agent Studio expects.
The go-to layout¶
The canonical structure is a uv workspace monorepo with an agents/
folder — one installable package per agent — served by an apps/backend that
runs the Agent Studio runtime. This is what agents like stratus and docs
use, and what Agent Studio's tooling (agent-studio link / push) is built
around.
my-agents/ # uv workspace monorepo root
├── pyproject.toml # [tool.uv.workspace] members + [tool.uv.sources] linking latent & agent-studio-*
├── devbox.json # env: LATENT_WORKSPACE_ROOT=$PWD, LATENT_FLOWS_DIR, provider keys
├── studio.config.yaml # Agent Studio integration (points the CLI at your Convex backend)
│
├── agents/ # ← one package per agent
│ ├── common/ # shared agent code (optional)
│ └── support/
│ ├── pyproject.toml # package name: latent-agents-support
│ ├── kb/ # knowledge-base markdown (public/ internal/ playbooks/)
│ ├── tests/
│ └── src/latent_agents/support/ # the latent_agents.<name> namespace
│ ├── __init__.py # re-exports the agent class + factories
│ ├── agent.py # @agent("support") class SupportAgent(GuidedAgent | ReActAgent | …)
│ ├── prompt.py # SYSTEM_PROMPT (or prompts/sections/ for composable fragments)
│ ├── tools.py # build_tools() — or a tools/ package, one file per tool
│ ├── guardrails.py # @guardrail mixin + custom scanners
│ ├── guidelines.py journey.py kb.py # GuidedAgent behavior, retriever wiring
│ └── flows/<flow>/ # flow logic may live next to the agent
│
├── apps/
│ ├── backend/ # FastAPI runtime that serves the agents (app.py, runtime.py, worker.py)
│ └── web/ # Agent Studio UI (optional)
├── convex/ # Agent Studio Convex backend (when running it locally)
│
├── flows/ # flow-discovery dir (directory name = flow name)
│ ├── global.yaml # shared parameter defaults across flows
│ └── <flow>/
│ ├── flow.py tasks.py
│ ├── parameters.yaml # flow params + mlflow.experiment_name
│ └── catalog.yaml # datasets (type / path / schema)
│
└── data/
├── stable/ # versioned, shared artifacts: chroma_db/, glossary.json, …
├── ground_truth/ # curated eval sets
└── <flow>/{input,output}/ # per-flow data; flows write to output/
How an agent fits in¶
- One package per agent under
agents/. Each is auvworkspace member namedlatent-agents-<name>, exposing thelatent_agents.<name>namespace. (You can use your own package name/namespace — theagents/<name>/folder and per-agent package are what matter.) agent.pyregisters the agent with@agent("<name>", description=...)on aReActAgent/GuidedAgent/PipelineAgentsubclass. latent's@agentregistry discovers it by name;__init__.pyre-exports the class and any factories.tools.py/tools/,guardrails.py,prompt.py,kb/hold the agent's capabilities, safety rules, prompt fragments, and knowledge-base markdown — see the Agent Cookbook for the patterns.
How Agent Studio serves it¶
apps/backendruns the Agent Studio runtime and serves every@agent-registered agent (the backend factory closure-binds per-conversation context, e.g. a customer id).studio.config.yamlpoints theagent-studioCLI at your Convex backend;agent-studio linkwires the local packages andagent-studio pushregenerates the Convex wrappers. See Agent Studio.pyproject.tomluses[tool.uv.sources]to bringlatentand theagent-studio-*packages in as workspace/editable deps.
Flows and data on disk¶
flows/<flow>/— each flow lives in a directory whose name is the flow name (@flow("agent_inference")↔flows/agent_inference/), containingflow.py,parameters.yaml, usuallycatalog.yaml, andtasks.py. See Flow Building, Flow Parameters, and Data Catalog.global.yamlsupplies defaults merged under each flow'sparameters.yaml(precedence: bundled <global.yaml< flow). See the layering model.data/stable/holds version-controlled shared artifacts (the Chroma index, glossaries) read viacatalog.stable;data/<flow>/output/is where outputs land (also MLflow artifacts).
Two flow-discovery conventions¶
- Root
flows/(default) — keep flows atLATENT_WORKSPACE_ROOT/flows. Flow bodies may live next to their agent and be re-exported from a thinflows/<name>/flow.pyshim that carries theparameters.yaml/catalog.yaml. LATENT_FLOWS_DIRoverride — pointLATENT_FLOWS_DIRat a dedicated pipelines package (e.g.apps/<app>/pipelines/src/pipelines) so flows live with the app and need no shims.
Configuration: env vars or TOML¶
Production repos configure entirely through environment variables in
devbox.json (LATENT_WORKSPACE_ROOT, LATENT_FLOWS_DIR, LATENT_DATA_DIR,
provider keys) rather than a latent.toml. Either works — env vars take
precedence. See Workspace Configuration.
A single-agent variant¶
For one agent and a handful of flows you don't need the full monorepo — drop the
agents/ and apps/ layers and keep a single package:
my-agent/
├── pyproject.toml # deps incl. "latent[eval]"
├── devbox.json
├── src/my_agent/ # agent.py, tools/, guardrails/, prompt.py
├── flows/<flow>/{flow.py,parameters.yaml,catalog.yaml}
└── data/{stable,<flow>/output}/
Promote to the agents/-folder monorepo above once you add a second agent or
wire up Agent Studio.
Development with Claude Code skills¶
The Latent team builds these projects with Claude
Code using a set of skills shipped through
the team's chezwork dotfiles (deployed to ~/.claude/skills/). They encode
the conventions in these docs — load latent-best-practices plus the relevant
domain skill when working in a latentsp repo.
| Skill | Use it for |
|---|---|
latent-best-practices |
The foundation — cross-cutting team conventions: architecture (side-effects at the edges, factory pattern), error handling, testing, observability, tooling. Load alongside the others. |
python-best-practices |
Python: FastAPI / Pydantic patterns, async conventions, uv / ruff, typing, error handling |
llm-best-practices |
Agents & LLM features — LiteLLM calls, prompt management, RAG (retrieval, chunking, embedding, hybrid search) |
ml-best-practices |
Eval flows — Prefect orchestration, MLflow experiment tracking, evaluation workflows |
data-best-practices |
Datasets & the catalog — Pydantic validation, ETL, dataset management, SQL |
testing-strategy |
Where tests live + the tooling/patterns to use |
agent-studio |
Agent Studio cross-repo workflows — linking, pushing Convex wrappers, debugging naming mismatches |
plan · architect · spec |
Plan → critique a design → write a spec, before building |
review · code-review · build · implement |
The build-and-review loop (simplicity, deep modules, honest types) |
Team tooling
These skills are part of the Latent team's Claude Code setup (managed in the
chezwork dotfiles repo). They're conventions, not part of the latent
package — but they map one-to-one onto the building blocks here:
llm-best-practices → agents, ml-best-practices →
flows, data-best-practices → the
catalog, and latent-best-practices ties them together.
See Also¶
- Getting Started — build your first flow end to end
- Agent Cookbook — class recipes for the agent package
- Agent Studio — the platform that serves these agents
- Flow Building & Style · Flow Parameters · Data Catalog