Skip to main content

CLI scaffolder for LangGraph projects

Project description

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.pymetrics.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.


Links


License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

langgraph_init_cli-0.1.4.tar.gz (86.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

langgraph_init_cli-0.1.4-py3-none-any.whl (143.1 kB view details)

Uploaded Python 3

File details

Details for the file langgraph_init_cli-0.1.4.tar.gz.

File metadata

  • Download URL: langgraph_init_cli-0.1.4.tar.gz
  • Upload date:
  • Size: 86.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for langgraph_init_cli-0.1.4.tar.gz
Algorithm Hash digest
SHA256 e03c422e03bf40abbf12f95a77a9981278216aba55517a6617383e1ce72ea585
MD5 9e27f2c4db8c3173484c336154adb8ce
BLAKE2b-256 0ec4506759ac3ecf22dc923f8a62479e1c7e978c073f6dfa1b3cc7da351853be

See more details on using hashes here.

File details

Details for the file langgraph_init_cli-0.1.4-py3-none-any.whl.

File metadata

File hashes

Hashes for langgraph_init_cli-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 8ff47edb6ce0188bff4fc6e003845e1d1947ddcac603e9649df0725ac77948dc
MD5 5ab9a456ec361ff495ed3e0988d679be
BLAKE2b-256 faca60f19141dd012d515ce4bfb7d1d8130b23bf125274938e961b4859d82bed

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page