Environment Setup

Start with Run your first agent for a working API that uses a fake model and SQLite. That example needs no provider credentials. This guide explains the configuration for an application deployment.

Configuration sources

For a source checkout, copy the template only if .env does not already exist:

cp .env.example .env

The template selects PostgreSQL and contains example model configurations. Replace those values before starting the service. Configure only the features that you use. A local fake-model service does not need PostgreSQL, LiteLLM, Redis, or Langfuse.

The application reads environment variables and the nearest .env file. Regular environment variables take precedence over values in that file. After loading these settings, settings.setup() validates and applies LANGGRAPH_<NAME> environment overrides. These overrides take precedence over the regular variables and the file. For example, LANGGRAPH_REQUEST_TIMEOUT overrides REQUEST_TIMEOUT.

PYTHON_DOTENV_DISABLED=1 disables explicit load_dotenv() calls. It does not stop Pydantic from reading the file selected by Settings. In embedded code, Settings(_env_file=None) disables file loading for that instance. Repository tests and documentation builds also replace find_dotenv() to prevent file discovery. The flag alone does not isolate a service from a local .env file.

Keep credentials in a secret manager or an untracked environment file. Do not put real credentials in examples, source files, or test results. .gitignore excludes the root .env and the service environment files listed below.

Authentication and identity

AUTH_MODE is an API server setting. It is not a request field or a client constructor argument. The code defaults to trusted when the setting is absent. This preserves 0.9.2 shared bearer-token authentication. The example .env uses the same mode. Installing the package does not copy that file.

For one trusted client application, configure:

AUTH_MODE=trusted
AUTH_SECRET=replace-with-a-private-shared-secret
AUTH_SERVICE_USER_ID=service

The client sends Authorization: Bearer <AUTH_SECRET>. user_id is optional. The trusted application can supply a user’s ID. A missing user_id uses AUTH_SERVICE_USER_ID (default: service). Keep the shared secret in that application. No new request header or per-user token is required for an existing shared-token deployment.

An explicit AUTH_MODE=token overrides the default. Remove it or set AUTH_MODE=trusted on every API worker to use the compatible behavior. Apply the same settings to every worker before service import.

Use AUTH_MODE=token and AUTH_USERS when users connect to the API directly. In token mode, the shared secret identifies AUTH_SERVICE_USER_ID only. A different supplied user_id receives 403. An AUTH_USERS token remains bound to its configured user in either mode. See Migrate authentication and checkpoint storage for both request formats and the separate history, validation, and checkpoint storage changes.

To accept feedback from token users, set FEEDBACK_SIGNING_SECRET to a separate server-only random value with at least 32 characters. Use the same value across workers and replicas. It must differ from every bearer token. Trusted backend feedback does not require this setting. See Migrate authentication and checkpoint storage for response proof and client changes.

user_id identifies a user for long-term memory. thread_id identifies one conversation for short-term history. Setting user_id does not create a long-term store. The application must configure and use that store.

Model providers

Install the provider extra before selecting a real model. See Installation Options for the available extras. The default OpenAI-backed blueprints use these settings:

USE_FAKE_MODEL=false
OPENAI_MODEL_NAME=your-model-name
OPENAI_API_BASE_URL=https://api.openai.com/v1

Supply OPENAI_API_KEY through the deployment environment. Choose a model available to that account. A model request can incur provider charges. OPENAI_API_VERSION is not required for the public OpenAI endpoint.

For LiteLLM, set the model name to a configured proxy alias. Set the base URL to http://litellm:4000/v1 from another Compose service, or http://127.0.0.1:4000/v1 from the host. Supply the proxy key as OPENAI_API_KEY. Container service names do not resolve on the host.

The API Docker image includes openai-aiohttp and sets LLM_HTTP_ASYNC_TRANSPORT=aiohttp. Python installations default to httpx. Leave this setting unset in .env to keep the image or Python default. Set it to httpx to override the image default. A Python installation needs the openai-aiohttp extra before selecting aiohttp. See Connections and High Traffic for pool limits and timeouts.

Named model configurations

MODEL_CONFIGS maps application names to flat provider configurations:

MODEL_CONFIGS='{"assistant":{"provider":"openai","name":"your-model-name"}}'

For a larger configuration, store JSON in a private file and set MODEL_CONFIGS_PATH. For example, data/models.json can contain:

{
  "assistant": {
    "provider": "openai",
    "name": "your-model-name"
  },
  "azure_assistant": {
    "provider": "azure_openai",
    "name": "your-model-name",
    "azure_endpoint": "https://your-resource.openai.azure.com/",
    "azure_deployment": "your-deployment-name",
    "api_version": "your-supported-api-version"
  }
}
MODEL_CONFIGS_PATH=data/models.json

The factory accepts name or model_name. It passes other fields to the provider’s model constructor. Use azure_endpoint and azure_deployment for Azure. The factory does not expand a nested params object. Supply OPENAI_API_KEY or AZURE_OPENAI_API_KEY through the environment for these examples.

Set one configuration source. An explicit MODEL_CONFIGS value, including {}, takes precedence over MODEL_CONFIGS_BASE64 and MODEL_CONFIGS_PATH. Base64 takes precedence over the file path. Remove the inline template entry before using the file path. Base64 encodes content; it does not encrypt it.

The chatbot-agent reads the request’s model_config_key and creates the selected model from this mapping. Custom agents must read that setting or use CompletionModelFactory.get_model_from_config themselves. The Deep Agent blueprint instead selects MODEL_CONFIGS.deep_agent at startup. See Choose an agent integration and Deep Agents before changing model selection.

Persistence

For local durable conversation history, use SQLite:

MEMORY_BACKEND=sqlite
SQLITE_DB_PATH=checkpoints.db

The service must have write access to the database directory. A container needs a persistent volume if history must survive container replacement. SQLite checkpointing does not provide a long-term store.

For PostgreSQL, supply the password separately and configure:

MEMORY_BACKEND=postgres
POSTGRES_HOST=127.0.0.1
POSTGRES_PORT=5432
POSTGRES_USER=your-database-user
POSTGRES_DB=agents
POSTGRES_SCHEMA=public

Use POSTGRES_HOST=postgres for the repository’s Compose network. Set POSTGRES_PASSWORD to the password for the selected user. Size checkpoint and conversation-lock pools for the total worker count. See Deployment and Recovery for database setup, pool sizing, and worker recovery.

Observability

Observability is optional. For Langfuse, install one SDK selector and set OBSERVABILITY_BACKEND=langfuse. Supply LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, and the project’s LANGFUSE_HOST. LANGFUSE_BASE_URL is an accepted URL alias and takes precedence over LANGFUSE_HOST. Use http://langfuse-web:3000 inside Compose or http://127.0.0.1:3000 from the host.

For LangSmith, install langsmith and set OBSERVABILITY_BACKEND=langsmith. Supply LANGSMITH_API_KEY, LANGSMITH_PROJECT, LANGSMITH_ENDPOINT=https://api.smith.langchain.com, and LANGSMITH_TRACING=true. Keep the unused tracing backend disabled. See Langfuse compatibility for the difference between SDK and server versions.

Optional Compose services

The full Compose stack includes external databases, LiteLLM, and Langfuse. Prepare its configuration files before starting it:

cp configs/litellm/config.example.yaml configs/litellm/config.yaml
cp configs/litellm/.litellm.env.example configs/litellm/.litellm.env
cp configs/redis/.redis.env.example configs/redis/.redis.env
cp configs/postgres/.postgres.env.example configs/postgres/.postgres.env
cp configs/minio/.minio.env.example configs/minio/.minio.env
cp configs/clickhouse/.clickhouse.env.example configs/clickhouse/.clickhouse.env
cp configs/langfuse/.langfuse.env.example configs/langfuse/.langfuse.env

Use these copy commands only for files that do not yet exist. Replace example passwords, host names, model aliases, and API versions for the selected services. Keep shared credentials consistent across their environment files. The LiteLLM example reads provider credentials through os.environ/... references. Supply the referenced variables to the LiteLLM container.

The checked-in Compose file selects Langfuse server v3. A package extra does not change that server image. See Deployment and Recovery for startup commands and Langfuse compatibility before changing the server version.