Migrating Langchain To Pydantic AI
pydantic/pydantic-ai
Migrate Python LangChain, LangGraph, or Deep Agents applications to Pydantic AI and, when the source uses harness features, Pydantic AI Harness.
Agent skill
by jeremylongshore in jeremylongshore/tons-of-skills-marketplace
A reference layered architecture for production LangChain 1.0 / LangGraph 1.0 services — LLM factory with version-safe defaults, chain/graph registry, retriever and tool DI, Pydantic-validated…
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill langchain-reference-architecture -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install jeremylongshore/tons-of-skills-marketplace langchain-reference-architecture --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/.curated/langchain-reference-architecture .claude/skills/langchain-reference-architecture && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "langchain-reference-architecture" agent skill from https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/langchain-reference-architecture into .claude/skills/langchain-reference-architecture/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "langchain-reference-architecture", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/langchain-reference-architectureType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill langchain-reference-architecture -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install jeremylongshore/tons-of-skills-marketplace langchain-reference-architecture --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/.curated/langchain-reference-architecture .agents/skills/langchain-reference-architecture && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "langchain-reference-architecture" agent skill from https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/langchain-reference-architecture into .agents/skills/langchain-reference-architecture/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "langchain-reference-architecture", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill langchain-reference-architecture -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install jeremylongshore/tons-of-skills-marketplace langchain-reference-architecture --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/.curated/langchain-reference-architecture .cursor/skills/langchain-reference-architecture && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "langchain-reference-architecture" agent skill from https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/langchain-reference-architecture into .cursor/skills/langchain-reference-architecture/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "langchain-reference-architecture", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/jeremylongshore/tons-of-skills-marketplace.git --path skills/.curated/langchain-reference-architecture--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill langchain-reference-architecture -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install jeremylongshore/tons-of-skills-marketplace langchain-reference-architecture --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/.curated/langchain-reference-architecture .gemini/skills/langchain-reference-architecture && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "langchain-reference-architecture" agent skill from https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/langchain-reference-architecture into .gemini/skills/langchain-reference-architecture/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "langchain-reference-architecture", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install jeremylongshore/tons-of-skills-marketplace langchain-reference-architectureInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill langchain-reference-architecture -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/.curated/langchain-reference-architecture .github/skills/langchain-reference-architecture && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "langchain-reference-architecture" agent skill from https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/langchain-reference-architecture into .github/skills/langchain-reference-architecture/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "langchain-reference-architecture", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill langchain-reference-architecture -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install jeremylongshore/tons-of-skills-marketplace langchain-reference-architecture --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/.curated/langchain-reference-architecture .opencode/skills/langchain-reference-architecture && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "langchain-reference-architecture" agent skill from https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/langchain-reference-architecture into .opencode/skills/langchain-reference-architecture/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "langchain-reference-architecture", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
langchain-reference-architectureA reference layered architecture for production LangChain 1.0 / LangGraph 1.0 services — LLM factory with version-safe defaults, chain/graph registry, retriever and tool DI, Pydantic-validated…
Langchain Reference Architecture is an agent skill from jeremylongshore/tons-of-skills-marketplace. A reference layered architecture for production LangChain 1.0 / LangGraph 1.0 services — LLM factory with version-safe defaults, chain/graph registry, retriever and tool DI, Pydantic-validated config, per-request tenant scoping, middleware ordering, checkpointer selection per environment. Use when starting a new service, refactoring a tangled chain, or onboarding a team to existing code. Trigger with "langchain architecture", "langchain llm factory", "langchain chain registry", "langchain dependency injection"…
Its SKILL.md is about 4.7k tokens, which your agent loads only when the skill is triggered. The skill folder holds 6 other files, including reference files (for example `references/dependency-rules.md`, `references/directory-layout.md` and `references/llm-factory-pattern.md`). Compatibility notes: Designed for Claude Code
It sits in AI & LLM Engineering, covering Building AI agents. It works with LangChain, Pydantic and LangGraph. The repository describes itself as: Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com. The licence is MIT.
9 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit cfae287. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
ReadWriteEditFrom allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are python and toml).
From the folder's file list and the shell code blocks in SKILL.md.
Links to these hosts (documentation or services it may open):
python.langchain.comlangchain-ai.github.iodocs.pydantic.devfastapi.tiangolo.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Designed for Claude Code
From compatibility in the SKILL.md frontmatter.
Langchain Reference Architecture loads about 4.7k tokens when it runs, and up to ~11k if it reads all its reference files. Until then it costs about 145 tokens; SKILL.md has 1,278 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
"dev","staging","prod"]` for env names, `.env` file loader.el_config = SettingsConfigDict(env_file=".env", env_prefix="MYSVC_")return Settings() # reads env/.env at first call, cachesAutomated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from jeremylongshore/tons-of-skills-marketplace at commit cfae287, republished under its MIT licence (© jeremylongshore). 1,278 words, ~4,699 tokens.
.claude/skills/langchain-reference-architecture/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.Eight months into a LangChain service, a code review surfaces the mess.
Twelve chain definitions live inlined inside FastAPI route handlers. Three
retrievers are constructed at module-global scope, one bound to
tenant_id="acme" because that was the first tenant in the pilot —
that retriever now returns Acme's documents to every other tenant, a P33
leak that has been live in production for six weeks.
max_retries=6 is hardcoded at four separate call sites. A
RunnableWithMessageHistory backed by the default
InMemoryChatMessageHistory loses every conversation on pod restart
(P22) — which is most days, because Cloud Run scales to zero.
Config is read from os.environ in three modules with three different
fallback strategies. There is no place to put a new provider without
touching seven files, and nobody remembers why the retriever is built
at import time.
The fix is not "rename a variable." The fix is an architecture that made every one of those mistakes hard to write. This skill is the target layered architecture:
app/ — FastAPI routes. Thin. Parses HTTP, calls into services,
serializes response. No chain logic, no vendor clients, no env vars.services/ — chain and graph definitions. Take dependencies through
constructor args, not module-level imports.adapters/ — vendor clients, LLM factory, retriever factory, tool
factory. This is where langchain-anthropic is imported. Nowhere else.config/ — one Pydantic Settings class. SecretStr for keys,
Literal["dev","staging","prod"] for env names, .env file loader.domain/ — Pydantic models, typed LangGraph state, enums. No I/O.Five layers, five imports deep at most. Dependency direction is
strictly downward. app imports services; services imports
adapters; adapters imports config and domain. Never the reverse.
Import-linter enforces this in CI. Pain-catalog anchors: P22 (in-memory
history loses messages — architectural fix is persistent history
injected via DI) and P33 (per-tenant vector stores leak if retriever
bound at import — architectural fix is per-request factory). Adjacent:
P10 (recursion limits), P24 (middleware order), P28 (callback
inheritance). Pin: langchain-core 1.0.x, langgraph 1.0.x,
langchain-anthropic 1.0.x, langchain-openai 1.0.x, pydantic 2.x,
import-linter 2.x.
langchain-core >= 1.0, < 2.0, langgraph >= 1.0, < 2.0pydantic >= 2.5 and pydantic-settings >= 2.1import-linter >= 2.0 for layer enforcement in CIlangchain-anthropic, langchain-openai, etc.langgraph-checkpoint-postgres and a Postgres instancelangchain-model-inference for the LLM factory's version-safe defaultssrc/my_service/
├── app/ # Layer 1: HTTP boundary (FastAPI)
│ ├── __init__.py
│ ├── main.py # FastAPI instance, DI wiring, lifespan
│ ├── routes/
│ │ ├── support.py # POST /support → services.support.run(...)
│ │ └── health.py
│ └── deps.py # FastAPI Depends() providers
├── services/ # Layer 2: chain and graph definitions
│ ├── __init__.py
│ ├── registry.py # name → builder lookup
│ ├── support/
│ │ ├── chain.py # SupportChain(llm, retriever, memory)
│ │ └── graph.py # SupportGraph (LangGraph StateGraph)
│ └── triage/
│ └── chain.py
├── adapters/ # Layer 3: vendor integrations
│ ├── __init__.py
│ ├── llm_factory.py # chat_model(provider, **kwargs) → BaseChatModel
│ ├── retriever_factory.py # retriever_for(tenant_id) → Retriever
│ ├── tool_factory.py # tools_for(tenant_id) → list[BaseTool]
│ ├── checkpointer.py # checkpointer_for(env) → BaseCheckpointSaver
│ └── history.py # history_for(session_id, tenant_id) → BaseChatMessageHistory
├── config/ # Layer 4: configuration
│ ├── __init__.py
│ └── settings.py # Pydantic Settings
└── domain/ # Layer 5: pure models, no I/O
├── __init__.py
├── state.py # TypedDict / Pydantic for LangGraph state
└── models.py # request/response schemas
tests/
├── unit/ # fake adapters, assert service logic
├── integration/ # real adapters against ephemeral infra
└── contract/ # schema snapshots (e.g., tool specs)
pyproject.toml # includes [tool.importlinter] contractsTypical depth is 5 layers. See Directory Layout for the full tree with file-naming conventions.
adapters/llm_factory.pyChains depend on the BaseChatModel protocol, not a concrete class. The factory is the one place version-safe defaults live:
# src/my_service/adapters/llm_factory.py
from langchain_core.language_models import BaseChatModel
from langchain_anthropic import ChatAnthropic
from langchain_openai import ChatOpenAI
_SAFE_DEFAULTS = {"timeout": 30, "max_retries": 2}
def chat_model(provider: str, **overrides) -> BaseChatModel:
defaults = {**_SAFE_DEFAULTS, **overrides} # caller wins
if provider == "anthropic":
return ChatAnthropic(model="claude-sonnet-4-6", **defaults)
if provider == "openai":
return ChatOpenAI(model="gpt-4o", **defaults)
raise ValueError(f"Unknown provider: {provider!r}")The max_retries=6 scatter in the mess-case becomes max_retries=2 in exactly one file. Services that want a longer timeout pass timeout=60 — but they never set max_retries=6 by accident. Cross-reference langchain-model-inference Step 3 for the factory pattern's provenance; see LLM Factory Pattern for per-provider variants and caching.
# src/my_service/services/registry.py
from typing import Callable, Protocol
from langchain_core.runnables import Runnable
class ChainBuilder(Protocol):
def __call__(self, *, tenant_id: str) -> Runnable: ...
_BUILDERS: dict[str, ChainBuilder] = {}
def register(name: str):
def decorator(fn: ChainBuilder) -> ChainBuilder:
_BUILDERS[name] = fn
return fn
return decorator
def get(name: str, *, tenant_id: str) -> Runnable:
try:
return _BUILDERSname
except KeyError:
raise KeyError(f"No chain registered under {name!r}. Known: {list(_BUILDERS)}")Each service module registers itself:
# src/my_service/services/support/chain.py
from my_service.services.registry import register
from my_service.adapters.llm_factory import chat_model
from my_service.adapters.retriever_factory import retriever_for
@register("support_agent")
def build_support_agent(*, tenant_id: str):
llm = chat_model("anthropic")
retriever = retriever_for(tenant_id=tenant_id)
# ... compose chain ...
return chainRoutes become one line: chain = registry.get("support_agent", tenant=req.tenant_id). There is one place to look, not twelve.
This is the P33 architectural fix. The factory takes tenant_id as a runtime argument. Nothing is bound at import:
# src/my_service/adapters/retriever_factory.py
from functools import lru_cache
from langchain_core.retrievers import BaseRetriever
from langchain_pinecone import PineconeVectorStore
from my_service.config.settings import get_settings
@lru_cache(maxsize=256) # cache the *store*, not the retriever
def _store_for(tenant_id: str) -> PineconeVectorStore:
s = get_settings()
return PineconeVectorStore(
index_name=s.pinecone_index,
namespace=f"tenant:{tenant_id}", # per-tenant namespace
embedding=...,
)
def retriever_for(*, tenant_id: str, k: int = 6) -> BaseRetriever:
# Retriever construction <5ms because store is cached — do it per-request.
return _store_for(tenant_id).as_retriever(search_kwargs={"k": k})The retriever is cheap to build (<5ms typical) so per-request construction is fine. Unit test with two tenants and assert non-overlap. See Dependency Rules for the import-linter contract that forbids services/*.py from importing langchain_pinecone directly.
Settings# src/my_service/config/settings.py
from functools import lru_cache
from typing import Literal
from pydantic import SecretStr
from pydantic_settings import BaseSettings, SettingsConfigDict
class Settings(BaseSettings):
model_config = SettingsConfigDict(env_file=".env", env_prefix="MYSVC_")
env: Literal["dev", "staging", "prod"] = "dev"
anthropic_api_key: SecretStr
openai_api_key: SecretStr
pinecone_api_key: SecretStr
pinecone_index: str
postgres_dsn: SecretStr | None = None # required when env != "dev"
@lru_cache(maxsize=1)
def get_settings() -> Settings:
return Settings() # reads env/.env at first call, cachesSecretStr prevents keys from leaking into logs. Literal[...] catches typos (env="staing") at validation time, not at deploy time.
Middleware order is a correctness concern (P24 — redaction before caching, or cached responses leak PII across tenants). Wire the stack once in adapters/ and hand the composed runnable to every service:
# src/my_service/adapters/middleware.py
from langchain_core.runnables import Runnable
def wrap(model: Runnable) -> Runnable:
# Order matters: redact -> cache -> retry -> model
# Cross-reference L31 (langchain-middleware-patterns) for the full rationale.
return (
model
.with_config(tags=["mysvc"])
# | redaction_middleware()
# | cache_middleware()
# | retry_middleware()
)Cross-reference langchain-middleware-patterns (L31) for the middleware stack rationale and P25 (retry double-counting tokens).
This is the P22 architectural fix. MemorySaver is fine for dev; it is not an option for staging or prod:
# src/my_service/adapters/checkpointer.py
from langgraph.checkpoint.base import BaseCheckpointSaver
from langgraph.checkpoint.memory import MemorySaver
def checkpointer_for(env: str) -> BaseCheckpointSaver:
if env == "dev":
return MemorySaver()
# Staging/prod: Postgres-backed. Async variant for FastAPI.
from langgraph.checkpoint.postgres.aio import AsyncPostgresSaver
from my_service.config.settings import get_settings
dsn = get_settings().postgres_dsn
assert dsn is not None, "POSTGRES_DSN required outside dev"
return AsyncPostgresSaver.from_conn_string(dsn.get_secret_value())Same for chat history when you use RunnableWithMessageHistory instead of a graph: InMemoryChatMessageHistory in dev, PostgresChatMessageHistory or RedisChatMessageHistory in staging/prod. See Per-Env Checkpointer for the MemorySaver / SqliteSaver / PostgresSaver / AsyncPostgresSaver decision matrix and the migration script between them. Cross-reference langchain-langgraph-checkpointing (L27) for checkpoint schema details.
The factory boundary is also the fake boundary. Unit tests inject a FakeListChatModel where production injects ChatAnthropic:
# tests/unit/test_support_chain.py
from langchain_core.language_models.fake_chat_models import FakeListChatModel
from my_service.services.support.chain import build_support_agent
def test_support_agent_returns_expected_shape(monkeypatch):
monkeypatch.setattr(
"my_service.services.support.chain.chat_model",
lambda provider, **kw: FakeListChatModel(responses=["fixed answer"]),
)
chain = build_support_agent(tenant_id="acme")
assert chain.invoke({"input": "hi"}).content == "fixed answer"Integration tests use the real adapters against ephemeral Postgres and a sandbox Pinecone namespace. Contract tests snapshot tool JSON schemas so a silent bind_tools change fails CI.
# pyproject.toml
[tool.importlinter]
root_package = "my_service"
[[tool.importlinter.contracts]]
name = "Layered architecture"
type = "layers"
layers = [
"my_service.app",
"my_service.services",
"my_service.adapters",
"my_service.config",
"my_service.domain",
]
[[tool.importlinter.contracts]]
name = "Services do not import vendor SDKs"
type = "forbidden"
source_modules = ["my_service.services"]
forbidden_modules = [
"langchain_anthropic",
"langchain_openai",
"langchain_pinecone",
]CI runs lint-imports. A PR that puts from langchain_anthropic import ChatAnthropic inside services/support/chain.py fails — forcing the author to go through adapters/llm_factory.chat_model("anthropic") instead.
app / services / adapters / config / domainadapters/llm_factory.py as the single source of version-safe defaultsservices/registry.py with register(...) / get(name, tenant=...) lookuptenant_id (P33 closed)Settings with SecretStr keys and Literal[...] env namesadaptersMemorySaver dev, AsyncPostgresSaver staging/prod (P22 closed)import-linter contracts enforced in CI| Error | Cause | Fix |
|---|---|---|
KeyError: "No chain registered under 'support_agent'" | Registry imported before service module registered | Import services.support.chain from services/__init__.py or app.main startup |
| Retriever returns wrong tenant's documents (P33) | Retriever bound at module-import scope with hardcoded tenant | Construct retriever_for(tenant_id=...) per request; retriever build <5ms with cached store |
| Chat history empty after pod restart (P22) | RunnableWithMessageHistory backed by InMemoryChatMessageHistory in staging/prod | Switch to PostgresChatMessageHistory / RedisChatMessageHistory via history_for(env=...) factory |
pydantic.ValidationError on env="staing" typo | Literal["dev","staging","prod"] caught at Settings init | Fix env var before deploy; this is the intended behavior |
import-linter failure services imports langchain_anthropic | Vendor SDK imported in services layer | Route through adapters.llm_factory.chat_model("anthropic") |
GraphRecursionError on vague prompts (P10) | create_react_agent default recursion_limit=25 | Set recursion_limit=5-10 at graph compile time in the service |
| Cached response contains another tenant's PII (P24) | Middleware order was cache before redaction | Compose in adapters/middleware.py as redact → cache → model |
| Subgraph traces missing (P28) | Parent callbacks not inherited into subgraphs | Pass config={"callbacks": [...]} explicitly when invoking subgraph |
AssertionError: POSTGRES_DSN required outside dev | Settings.postgres_dsn None in staging | Fail fast at startup; do not fall back to MemorySaver silently |
Because retrievers are built per request from tenant_id, onboarding a new tenant is a data concern (create Pinecone namespace, seed documents), not a code concern. No file in services/ changes. No redeploy is required to add tenant_id="zeta".
adapters/llm_factory.py grows one elif branch. config/settings.py grows one SecretStr field. No service module changes — they all depend on BaseChatModel, not ChatAnthropic. Cross-reference langchain-model-inference for the list of provider packages and their 1.0 import paths.
The migration is layer by layer, bottom up:
config/settings.py first — it has no dependencies and unlocks the restadapters/llm_factory.py and replace scattered ChatAnthropic(...) callsadapters/retriever_factory.py with tenant_id as a runtime arg — this is the P33 fixservices/registry.py and move one chain at a time from routes into registered buildersimport-linter in CI with ignore_imports for routes that have not migrated yet; remove ignores as you goMemorySaver for AsyncPostgresSaver in staging last — it is the lowest-risk step once factories existdocs/pain-catalog.md (entries P10, P22, P24, P28, P33)plugins/saas-packs/langchain-py-pack/skills/ directory):langchain-model-inference — LLM factory defaults provenancelangchain-embeddings-search — retriever and vector-store selectionlangchain-sdk-patterns — composition patterns referenced by service builders© jeremylongshore, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 5 other files (references) in skills/.curated/langchain-reference-architecture of jeremylongshore/tons-of-skills-marketplace.
Open the folder on GitHubat commit cfae287
Langchain Reference Architecture next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Langchain Reference Architecture this skilljeremylongshore/tons-of-skills-marketplace | 2.8k | — | ~4.7k | Automated safety check: Notes | MIT | |
| Migrating Langchain To Pydantic AIpydantic/pydantic-ai | 21k | — | ~2.5k | Automated safety check: Pass | MIT | |
| Mem0 Platform SDKmem0ai/mem0 | 67k | 1 repos | ~2.2k | Automated safety check: Pass | Apache-2.0 | |
| LangSmith Trace DebuggingComposioHQ/awesome-claude-skills | 77k | 8 repos | ~2.7k | Automated safety check: Pass | None | |
| Add Example AgentGetBindu/Bindu | 10k | — | ~1.1k | Automated safety check: Notes | Custom licence | |
| Failproof AI SDK IntegrationFailproofAI/failproofai | 5.3k | — | ~6k | Automated safety check: Pass | Custom licence |
pydantic/pydantic-ai
Migrate Python LangChain, LangGraph, or Deep Agents applications to Pydantic AI and, when the source uses harness features, Pydantic AI Harness.
mem0ai/mem0
Adds persistent memory to AI apps with the Mem0 Python and TypeScript SDKs: store, search, update and delete user memories, with framework integrations.
ComposioHQ/awesome-claude-skills
Debugs LangChain and LangGraph agents by pulling recent execution traces with the langsmith-fetch CLI and reporting errors, tool calls, timings and token use.
GetBindu/Bindu
Add a new self-contained example agent under examples/. An agent skill from GetBindu/Bindu.
FailproofAI/failproofai
Helps instrument a custom Python or TypeScript agent to record events for Failproof AI, verify what gets written, and run an evaluator worker that scores the runs.
TencentEdgeOne/edgeone-makers-tools
Migrate existing AI agent projects (LangChain, LangGraph, OpenAI Agents SDK, Claude Agent SDK, CrewAI) to EdgeOne Makers platform conventions.
jeremylongshore/tons-of-skills-marketplace
Execute this skill enables AI assistant to conduct a security-focused code review using the security-agent plugin.
jeremylongshore/tons-of-skills-marketplace
Build this skill automates the adaptation of pre-trained machine learning models using transfer learning techniques.
jeremylongshore/tons-of-skills-marketplace
Execute proactive auto-loading: automatically detects and loads agents.md files.
jeremylongshore/tons-of-skills-marketplace
Aggregate and centralize performance metrics from applications, systems, databases, caches, and services.
jeremylongshore/tons-of-skills-marketplace
Execute this skill enables AI assistant to analyze capacity requirements and plan for future growth.
jeremylongshore/tons-of-skills-marketplace
Process use when you need to work with database indexing. An agent skill from jeremylongshore/tons-of-skills-marketplace.
Categories
A reference layered architecture for production LangChain 1.0 / LangGraph 1.0 services — LLM factory with version-safe defaults, chain/graph registry, retriever and tool DI, Pydantic-validated…. Langchain Reference Architecture is an agent skill from jeremylongshore/tons-of-skills-marketplace.0 services — LLM factory with version-safe defaults, chain/graph registry, retriever and tool DI, Pydantic-validated config, per-request tenant scoping, middleware ordering, checkpointer selection per environment.
Langchain Reference Architecture fits situations like: starting a new service; refactoring a tangled chain; onboarding a team to existing code; with langchain architecture.
Run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill langchain-reference-architecture -a claude-code`. Or copy the skill folder (skills/.curated/langchain-reference-architecture in jeremylongshore/tons-of-skills-marketplace) into .claude/skills/langchain-reference-architecture in your project. Claude Code loads it when a task matches its description.
Run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill langchain-reference-architecture -a codex`. Or copy the skill folder (skills/.curated/langchain-reference-architecture in jeremylongshore/tons-of-skills-marketplace) into .agents/skills/langchain-reference-architecture in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill langchain-reference-architecture -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/langchain-reference-architecture, .gemini/skills/langchain-reference-architecture, .github/skills/langchain-reference-architecture and .opencode/skills/langchain-reference-architecture in your project.
SKILL.md names no scripts, command-line tools or credentials: Langchain Reference Architecture is instructions for the agent only. Our summary lists: Python 3. Its frontmatter pre-approves these tools: Read, Write, Edit. Compatibility (from SKILL.md): Designed for Claude Code.
SKILL.md names 4 domains. As links in the text: python.langchain.com, langchain-ai.github.io, docs.pydantic.dev and fastapi.tiangolo.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Langchain Reference Architecture is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.7k tokens (SKILL.md is roughly 19k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 6.3k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Langchain Reference Architecture: Migrating Langchain To Pydantic AI (pydantic/pydantic-ai, 21k stars), Mem0 Platform SDK (mem0ai/mem0, 67k stars), LangSmith Trace Debugging (ComposioHQ/awesome-claude-skills, 77k stars) and Add Example Agent (GetBindu/Bindu, 10k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
jeremylongshore (a GitHub user) maintains it in jeremylongshore/tons-of-skills-marketplace, which has 2,827 GitHub stars. The repository holds 3,342 skills in this directory. The repository was last updated on October 10, 2026.
Source: jeremylongshore/tons-of-skills-marketplace on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.