Skip to main content

langgraph-init-cli

A production-oriented scaffolding CLI for LangGraph projects. Generate opinionated project layouts that start simple and scale into a full agentic architecture - with graph orchestration, LLM provider abstraction, prompt versioning, tool registries, evaluation, observability, and LangSmith-ready tracing.

pip install langgraph-init-cli
langgraph-init my-app --template advanced

Why langgraph-init?

Starting a LangGraph project from scratch means a lot of boilerplate: wiring state graphs, organizing nodes, managing prompts, hooking up LangSmith. langgraph-init gives you a well-structured starting point so you can skip the scaffolding and focus on the agent logic that matters.


Installation

pip install langgraph-init-cli

Or for a cleaner global CLI experience:

pipx install langgraph-init-cli

Usage

langgraph-init <project-name> --template <template>

Available templates:

Template Best For
base Quick experiments and prototypes
advanced Modular team projects with clean graph structure
production Full production systems with tooling, observability, and evaluation

Example:

langgraph-init my-app --template production
cd my-app
cp .env.example .env
pip install -e .
python -m src.app.main

Templates

base

A minimal LangGraph starter to get something running fast. No LLM, no config — just the graph fundamentals. Runnable via src.app.main:run

src/app/
├── state.py    # AppState TypedDict
├── nodes.py    # intake_node, draft_node, output_node
└── main.py     # StateGraph wiring + run()

Three nodes (intake -> draft -> output), a typed state, and a working app.invoke() call. Replace the stub logic with real LLM calls when you're ready.


advanced

A modular architecture for teams that want clean structure with a real LLM wired in — without full production overhead.

src/app/
├── llm/provider.py           # get_llm() — OpenAI / Anthropic / Google / WatsonX
├── graph/                    # builder, state, edges, constants, registry
├── memory/checkpointer.py    # MemorySaver for in-process conversation persistence
├── nodes/                    # intent_node, processing_node, output_node
├── prompts/versions/         # .txt prompt files loaded by task + version
├── services/prompt_service.py
├── tools/calculator.py       # Pydantic-validated arithmetic tool
└── utils/logger.py           # JSON structured logger
  • Names / Nodes / Tags pattern for readable graph wiring
  • ChatPromptTemplate + get_llm() in every node - real LLM calls from day one
  • Conditional routing with retry logic (route_after_process)
  • Calculator tool with Pydantic input/output validation
  • MemorySaver checkpointer wired in - same thread_id resumes a conversation

production

A complete scaffold intended for real systems. Everything is modular, runnable without external services, and ready to extend.

src/app/
├── config.py                 # Settings dataclass — all config from .env
├── llm/provider.py           # get_llm() — OpenAI / Anthropic / Google / WatsonX
├── graph/                    # builder, state, edges (retry + error routing), constants, registry
├── memory/checkpointer.py    # MemorySaver / SqliteSaver / PostgresSaver via MEMORY_BACKEND env var
├── nodes/                    # intent, processing, validation, output, error
├── services/                 # llm_service, prompt_service, tool_service, evaluation_service, versioning_service
├── prompts/versions/         # intent/v1+v2, extraction/v1, validation/v1
├── tools/                    # BaseTool + registry + calculator, retriever, db query, http tools
├── models/                   # ExtractionSchema + WorkflowResult (Pydantic)
├── storage/                  # workflow_store, prompt_store, cache (in-memory singletons)
├── observability/            # metrics counters, @traceable decorator, LangSmith config
├── evaluation/               # field coverage evaluator + confidence scoring formula
└── api/                      # FastAPI-ready /run + /health endpoints
  • Graph orchestration with StateGraph, conditional routing (complete / retry / error), and retry cap from config
  • RunnableParallel for concurrent extraction and analysis in processing_node
  • Prompt versioning system (prompts/versions/<task>/v1.txt, v2.txt) with version config in config.py
  • Full tool framework with BaseTool, registry, and four demo tools (calculator, retriever, DB query, HTTP)
  • ExtractionSchema and WorkflowResult Pydantic models - type-safe extraction and serialization
  • Evaluation: field coverage + confidence scoring → validation pass/fail → auto retry
  • Structured JSON logging, metrics counters, trace_block() context manager
  • LangSmith integration @traceable decorator for LangSmith (environment-driven, safe when disabled)
  • In-memory storage singletons (workflow_store, prompt_store, cache) designed to swap for a real DB

Generated layout:

src/app/
├── main.py
├── config.py
├── graph/
├── nodes/
├── services/
├── tools/
├── prompts/
├── models/
├── storage/
├── utils/
├── observability/
├── evaluation/
└── api/

Graph Wiring Pattern

The advanced and production templates use a three-concept pattern to keep graph wiring readable and maintainable:

class Names:
    INTENT = "intent"         # Stable node identifiers

class Nodes:
    INTENT = intent_node      # Callable implementations

class Tags:
    COMPLETE = "complete"     # Routing labels for conditional edges
    RETRY = "retry"
    ERROR = "error"

This separates string identifiers from executable functions, making edges easy to read and refactor. constants.py is always the first file to update when adding a new node.


Understanding the Generated Files

Here's what each file and folder does, and where to make changes when building your own agent.

config.py — App Settings

Centralizes all configuration in a Settings dataclass. Every module imports the shared settings instance — nothing reads .env directly.

from src.app.config import settings

settings.log_level                 # "INFO"
settings.default_prompt_versions   # {"intent": "v2", "extraction": "v1", "validation": "v1"}
settings.max_validation_retries    # 2
settings.langsmith_tracing         # True/False
# What's inside:
project_name       # Your app name
environment        # "development" | "production" (from APP_ENV)
log_level          # "INFO" by default (from LOG_LEVEL)
langsmith_tracing  # Toggle LangSmith tracing on/off (from LANGSMITH_TRACING)
langsmith_api_key  # Your LangSmith API key (from LANGSMITH_API_KEY)
default_prompt_versions  # e.g. {"intent": "v2", "extraction": "v1"}
max_validation_retries   # How many times to retry failed validation (default: 2)

What to change here: your project name,default_prompt_versions to activate a new prompt version, max_validation_retries for retry behavior. Add any new env-driven fields your agent needs.


main.py — Entrypoint

Builds the graph and runs it with app.invoke() and a thread_id for conversation memory. This is what executes when you run python -m src.app.main

sample_state = {
    "input_text": "Please calculate 12 + 7 and validate the answer.",
    "retry_count": 0,
    "messages": [],
    "prompt_versions": settings.default_prompt_versions.copy(),
    "tool_results": {},
}
result = app.invoke(sample_state, config={"configurable": {"thread_id": "session-1"}})

What to change here: replace sample_state with your real input schema. Swap the input_text for whatever your agent actually receives (a user message, a document, an API payload, etc.).

graph/ — Graph Orchestration

File Purpose
builder.py Wires nodes and edges into a StateGraph - start here to understand the flow
state.py WorkflowState TypedDict - every field that flows between nodes
edges.py Routing functions + EDGE_MAP for conditional edges
constants.py Names, Nodes, Tags — update this first when adding a new node
registry.py NODE_REGISTRY dict - loaded by builder.py

What to change here: add new nodes in registry.py, define new routes in edges.py, and expand the state schema in state.py.

nodes/ — Node Implementations

File What it does
intent.py Step 1: classifies input via ChatPromptTemplate + LLM
processing.py Step 2: parallel enrichment + tool dispatch
validation.py Step 3: scores quality, decides retry or continue
output.py Step 4: builds WorkflowResult, saves to workflow_store
error.py Fallback: structured error response

What to change here: this is where most of your agent logic lives. Replace stub LLM calls with real provider clients. The function signature - (state: WorkflowState) -> WorkflowState - stays the same.


services/ — Reusable Logic

Holds logic that multiple nodes share:

File What it does
llm_service.py classify_intent + parallel_enrich via RunnableParallel
prompt_service.py load_prompt(task, version) with fallback + access logging
evaluation_service.py Coordinates field coverage + confidence scoring
versioning_service.py switch_version() for runtime prompt switching
tool_service.py Dispatches tool calls from the registry

What to change here: replace the keyword-matching stubs in llm_service.py with real get_llm() calls.


tools/ — Tool Framework

BaseTool contract + ToolRegistry. Comes with four demo tools you can run immediately and replace later.

Tool What it does
calculator_tool.py Safe arithmetic with Pydantic input/output validation
retriever_tool.py Stub retriever (returns fixed text)
query_tool.py Stub DB query (returns fixed result)
http_tool.py Stub HTTP tool (returns fixed response)

What to change here: add your own tools by implementing BaseTool, register in tools/registry.py, call in tool_service.py.Delete the demo tools when you no longer need them.


prompts/ — Prompt Versioning

Prompts are plain .txt files. Edit them directly without touching Python code. Add a v2.txt alongside v1.txt to iterate safely — the registry falls back to v1.txt if a requested version doesn't exist.

prompts/versions/
├── intent/
│   ├── v1.txt
│   └── v2.txt
├── extraction/
│   └── v1.txt
└── validation/
    └── v1.txt

The prompt service loads the version specified in config.py and falls back to v1 if a version doesn't exist. This lets you iterate on prompts without changing code - just add a new version file and update the config.

What to change here: edit the .txt files directly. Add new task folders as your agent gains new capabilities.

observability/ — Logging and Tracing

Structured JSON logging and metrics counters out of the box. Trace decorators make it easy to instrument any function for LangSmith.

  • metrics.py — metrics.increment("event") / metrics.snapshot() — global counters
  • langsmith.py — @traceable(name="...") decorator — sends traces to LangSmith when LANGSMITH_TRACING=true

What to change here: add custom metrics or extend the trace decorators for new nodes.


evaluation/ — Output Scoring

Field coverage evaluation and confidence scoring to measure output quality. Feeds the validation node's retry decision.

score = (field_coverage × 0.6) + (confidence × 0.4)
is_valid = field_coverage >= 0.5 AND score >= 0.5

What to change here: expand the scoring rubric to match your domain's definition of a good output.


storage/ — Persistence Layer

In-memory singletons designed to swap for a real database without changing node code:

File What it stores
workflow_store.py WorkflowResult.model_dump() after each successful run
prompt_store.py Which prompt version ran per task per call
cache.py Simple key-value cache

Designed to be swapped for a real database (Postgres, Redis, S3, etc.) without changing node code.

What to change here: implement the storage interface for your target database when you're ready to persist results.

api/ — Optional API Surface

A thin API layer (FastAPI-ready) you can enable if you want to expose the agent as an HTTP service.

FastAPI app with /run and /health already wired in routes.py. Serve it when ready:

pip install fastapi uvicorn
uvicorn src.app.api.routes:api --reload

What to change here: add your routes and request/response models here when you're ready to serve the agent over HTTP.


After Generation

Recommended next steps once you have your scaffold:

  • Set your .env — provider, model, log level, memory backend
  • Uncomment the right provider in pyproject.toml and run pip install -e .
  • Replace keyword-matching stubs in llm_service.py with get_llm() calls
  • Update state.py, schema.py, and workflow.py for your domain's data shape
  • Add domain-specific tools in tools/ implementing BaseTool
  • Add real persistence in storage/ for your target database
  • Set LANGSMITH_TRACING=true and add LANGSMITH_API_KEY to activate tracing
  • Add tests around graph routing and node behavior

Generated langgraph.json

All projects include:

{
  "dependencies": ["."],
  "graphs": {
    "<project-name>": "src.app.main:run"
  }
}

This keeps the entrypoint consistent and compatible with LangGraph tooling.



License

MIT

Metadata

Release files for langgraph-init-cli 0.1.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for langgraph-init-cli 0.1.5
File Size Uploaded
langgraph_init_cli-0.1.5.tar.gz 86.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for langgraph-init-cli 0.1.5
File Interpreter ABI Platform
langgraph_init_cli-0.1.5-py3-none-any.whl Python 3 none any Details

Total release size: 230.8 kB

Release files / langgraph_init_cli-0.1.5.tar.gz

Download URL langgraph_init_cli-0.1.5.tar.gz
Size 86.8 kB
Tags Source
SHA-256 checksum
How to use checksums
a168cf5096406f5122be8c8aa5661b42e397cf863a80db4d070ec8a1dc7b11f6
BLAKE2b-256 checksum
How to use checksums
6f23985c54a76c5f521ff01f5e1d1e2157ab24f2060cf6c617321e1b6dd812df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release files / langgraph_init_cli-0.1.5-py3-none-any.whl

Download URL langgraph_init_cli-0.1.5-py3-none-any.whl
Size 144.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ece6cf9466ec0a9d57f9a2fc4d58a129bdc04656d9cedadcf5000598e793e7d7
BLAKE2b-256 checksum
How to use checksums
86b8c6be9d85332a38500b1ddac0629fb17d2904a14b293777d538185a5817ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.12

Release history Release notifications | RSS feed

This release

0.1.5 This release

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page