Course Content
LangChain Mastery
7 sections · 109 lessons
How do you save and load a LangChain chain for reuse?
What you need to know
"Saving a chain" means three different things, and each has its own right answer.
What to store
- The prompt text (a file or LangSmith)
- Model name and settings (config)
- The pipeline shape (Python code)
What not to store
- A pickled chain object
- API keys inside a JSON blob
- Anything that must be loaded from user input
The recommended pattern: a factory function
1from langchain.chat_models import init_chat_model2from langchain_core.prompts import ChatPromptTemplate3from langchain_core.output_parsers import StrOutputParser45def build_summary_chain(cfg: dict):6 prompt = ChatPromptTemplate.from_messages([7 ("system", cfg["system_prompt"]), # loaded from a YAML file8 ("human", "{text}"),9 ])10 llm = init_chat_model(cfg["model"], temperature=cfg.get("temperature", 0))11 return prompt | llm | StrOutputParser()The code is versioned in Git and unit-tested; the configuration can differ per environment. This is how LangChain apps are normally shipped.
When you do need serialisation
1from langchain_core.load import dumps, loads23blob = dumps(prompt, pretty=True) # JSON text, safe to store4same_prompt = loads(blob) # core classes are allowed by defaultKey facts, checked against langchain-core 1.6:
- Only classes marked serialisable round-trip. A
RunnableLambdaholding your own Python function does not. - Secrets are replaced by placeholders, so the API key is never written out.
- By default
loadsonly allows core classes. A chain containingChatOpenAIneeds an explicit allowlist, and secrets are only read from the environment if you passsecrets_from_env=True. - A serialised payload is executable configuration: it can set a
base_urlor headers. Load only what you wrote yourself. prompt.save()andload_prompt()are deprecated in favour ofdumpsandloads.
A real-life example
A lead-qualification pipeline for a Hyderabad real-estate firm scores website enquiries as hot, warm or cold. The first version pickled the whole chain to S3 so the worker could load it. After a library upgrade, the pickle no longer loaded and the worker crashed at 2 a.m. The rebuild moved the scoring prompt to prompts/lead_score.yaml, the model name to an environment variable, and the chain into build_lead_chain(cfg). Now a prompt change is a small YAML diff that the sales-ops lead can review, and the evaluation set of 200 past enquiries runs on every change before deploy.
Follow-up questions to expect
- "How do you let non-engineers edit prompts?" — Store prompts in LangSmith's prompt hub and pull a tagged version at start-up with
Client().pull_prompt("lead-score:prod"). - "Why is
loadson user input dangerous?" — It creates Python objects from the payload, and a crafted payload can point a model at an attacker'sbase_urlor leak environment secrets. - "What about saving an agent's state?" — That is conversation state, not the chain: use a LangGraph checkpointer such as
PostgresSaver.