LangSmith Prompt Hub: Versioning and Sharing Prompts
Somewhere in your codebase right now, there is probably a prompt living inside a Python string. Maybe it is a triple-quoted block in prompts.py, maybe it is a constant pasted into three different services, maybe it is a Slack message someone copied into production last quarter. When that prompt changes, nobody knows who changed it, why, or which version was running when a customer complained about a weird answer. This is exactly the problem the LangSmith Prompt Hub exists to solve. It gives your prompts what your code has had for decades: a home, a history, and a way to share them safely. In this guide, we will walk through how the langsmith prompt hub handles versioning, tagging, pulling, and pushing prompts, with real code you can run today.
What the LangSmith Prompt Hub Actually Is
The LangSmith Prompt Hub is a prompt registry built into LangSmith, the observability and evaluation platform from the LangChain team. Think of it as a package registry, but for prompts instead of libraries. Every prompt you store in the hub gets a name, an owner, a full commit history, and optional tags. You can pull a prompt into your application at runtime, push updated versions from code or from the LangSmith UI, and pin production systems to a specific commit so a teammate experimenting in the playground can never break your live traffic.
There are two sides to the hub. The public hub is a community space where anyone can browse and pull prompts shared by other developers, including well-known community prompts for agents, RAG pipelines, and summarization. The private side lives inside your LangSmith workspace, where your team stores proprietary prompts that never leave your organization. Both sides use the same SDK calls and the same versioning model, so the workflow you learn once applies everywhere.
The hub is tightly integrated with the rest of LangSmith. Prompts you store there open directly in the Playground, where you can edit them, test them against different models, and commit new versions without touching code. Because LangSmith also captures traces from your running application, you can connect a specific production trace back to the specific prompt commit that generated it. That closed loop, from prompt version to observed behavior and back, is what separates a real prompt management workflow from a folder full of text files.
The key mental shift is this: prompts are not configuration, and they are not quite code. They are model-facing behavior that changes frequently, often edited by non-engineers, and they deserve their own lifecycle. The hub gives them one.
Why Prompts Deserve Real Version Control
It is tempting to say "just keep prompts in Git" and move on. Git is a fine place for prompts, and plenty of teams do exactly that. But prompts have properties that make a dedicated registry meaningfully better in practice.
First, prompts are edited by people who do not open pull requests. Product managers, domain experts, and support leads often have the best instincts about wording, tone, and edge cases. If changing a prompt requires cloning a repo, editing a Python file, and waiting for CI, those people are locked out, and engineers become a bottleneck for what is essentially copy editing. The Prompt Hub lets a non-engineer edit a prompt in the LangSmith Playground, test it against live models, and commit a new version, all without touching the codebase.
Second, prompt changes need to be decoupled from deploys. A prompt tweak should not require rebuilding a Docker image and rolling pods. When your application pulls its prompt from the hub at runtime, you can ship a wording fix in seconds and roll it back just as fast by moving a tag back to the previous commit. That deployment decoupling is the single biggest operational win teams notice after adopting the hub.
Third, prompts need evaluation-aware history. A Git diff tells you what changed in the text. It does not tell you that version a1b2c3d4 scored 84 percent on your golden dataset while the new version scored 71 percent. Because the hub lives inside LangSmith, each prompt version can be run against datasets and evaluators, so history is not just "what changed" but "what changed and whether it got better."
Finally, there is the audit question. When something goes wrong in an LLM product, the first question is always "what exactly did we send the model?" With hub-managed prompts, every commit is immutable and hash-addressed. You can answer that question precisely, for any point in time, which matters enormously for regulated industries and for plain old debugging.
Setting Up the SDK and Your First Pull
Getting started takes about five minutes. You need a LangSmith account, an API key from the settings page, and the SDK installed. The langsmith package provides the client, and if you want prompts returned as ready-to-use LangChain objects, install langchain alongside it.
pip install -U langsmith langchain langchain-openai
export LANGSMITH_API_KEY="lsv2_pt_..."
export LANGSMITH_TRACING=trueThe LANGSMITH_TRACING variable is optional for hub work, but turning it on means every chain you run also gets traced, which you will want anyway once you start iterating on prompt versions.
With the environment set, pulling a prompt is one call. Here is the classic first example, pulling a popular public prompt and using it immediately:
from langsmith import Client
from langchain_openai import ChatOpenAI
client = Client()
# Pull a public prompt from the hub
prompt = client.pull_prompt("rlm/rag-prompt")
# It comes back as a ChatPromptTemplate, ready to compose
llm = ChatOpenAI(model="gpt-4o-mini")
chain = prompt | llm
result = chain.invoke({
"context": "LangSmith is a platform for tracing and evaluating LLM apps.",
"question": "What is LangSmith used for?",
})
print(result.content)A few things worth noticing. The identifier rlm/rag-prompt follows the owner/prompt-name convention for public prompts. For prompts inside your own workspace, you drop the owner prefix and just use the prompt name, like client.pull_prompt("support-triage"). The object you get back is a genuine ChatPromptTemplate, so it slots into LCEL chains, agents, and anything else in the LangChain ecosystem without conversion.
If you have older code using from langchain import hub and hub.pull(...), that still works and delegates to the same underlying API, but the Client interface is the current recommended path and gives you access to the full prompt management surface, including pushing, listing, and deleting prompts.
Pulling Prompts: Versions, Tags, and Model Configs
The pull you just did fetched the latest commit of the prompt. That is fine for experimentation, but the real power of the langsmith prompt hub shows up when you start being explicit about versions.
Every commit to a prompt gets a content hash, and you reference a specific version by appending the first eight characters of that hash after a colon. You can also attach human-readable tags to commits, such as prod or staging, and pull by tag instead. Tags are movable pointers, exactly like Git tags that you re-point at new commits as they are promoted.
from langsmith import Client
client = Client()
# Pull the latest commit (implicit ":latest")
latest = client.pull_prompt("support-triage")
# Pull an exact, immutable commit by hash prefix
pinned = client.pull_prompt("support-triage:f3d0a812")
# Pull whatever commit the "prod" tag currently points to
production = client.pull_prompt("support-triage:prod")
# Pull the prompt together with its saved model configuration
runnable = client.pull_prompt("support-triage:prod", include_model=True)
answer = runnable.invoke({"ticket": "My export keeps timing out after 30 seconds."})The include_model=True flag deserves attention. When someone saves a prompt in the LangSmith Playground, they can save the model settings alongside it: which model, what temperature, structured output schemas, and so on. Pulling with include_model=True returns not just the template but a bound runnable that already includes the model, so invoking it goes straight to a completion. This is how you let a prompt engineer change both the wording and the model choice without an engineer editing code. Note that your application still needs the relevant provider API key available, since the model runs with your credentials.
The same operations exist in TypeScript for Node applications. The langchain/hub entrypoint mirrors the Python behavior:
import * as hub from "langchain/hub";
// Latest version
const prompt = await hub.pull("support-triage");
// Pinned to a commit, with the stored model attached
const runnable = await hub.pull("support-triage:f3d0a812", {
includeModel: true,
});
const res = await runnable.invoke({ ticket: "Cannot reset my password." });One practical guideline: pull by tag in deployed environments and by explicit hash in anything that must be perfectly reproducible, such as evaluation runs and incident postmortems. Pulling :latest belongs in notebooks and local development, not in production services, because it silently changes under you whenever anyone commits.
Pushing Prompts to the Hub
Pulling is half the story. The other half is publishing your own prompts, and this is where the hub becomes your team's single source of truth. The push_prompt method creates the prompt if it does not exist and creates a new commit if it does. If the content is identical to the current head, the push is a no-op, so it is safe to call idempotently.
from langsmith import Client
from langchain_core.prompts import ChatPromptTemplate
client = Client()
prompt = ChatPromptTemplate.from_messages([
(
"system",
"You are a support triage assistant for a B2B SaaS product. "
"Classify the ticket into exactly one category: billing, bug, "
"how-to, or feature-request. Then write a one-sentence summary. "
"Respond in JSON with keys 'category' and 'summary'.",
),
("human", "Ticket text:\n\n{ticket}"),
])
url = client.push_prompt(
"support-triage",
object=prompt,
description="Triage classifier for inbound support tickets",
tags=["support", "classification"],
)
print(url) # Direct link to the new commit in LangSmithThe returned URL points straight at the commit in the LangSmith UI, which is handy to drop into a pull request or a Slack thread so reviewers can inspect the change and open it in the Playground with one click.
You can also push a prompt bundled with a model, mirroring the include_model pull. Wrap the prompt and model into a runnable sequence and push the whole thing:
from langchain_openai import ChatOpenAI
chain = prompt | ChatOpenAI(model="gpt-4o-mini", temperature=0)
client.push_prompt("support-triage-with-model", object=chain)By default, prompts you push are private to your workspace. If you want to publish to the public hub, you set the prompt's visibility to public, and it becomes pullable by anyone under your handle. Most teams keep everything private and treat the public hub as a read-only source of inspiration.
Beyond push and pull, the client gives you the rest of the management surface: client.list_prompts() to enumerate what your workspace contains, client.get_prompt("support-triage") for metadata, client.like_prompt(...) for public prompts you want to bookmark, and client.delete_prompt(...) when something is truly dead. Listing supports filtering, which becomes important once your workspace grows past a few dozen prompts and you need naming conventions to stay sane.
Version Pinning Strategies for Production
Once prompts live in the hub, the question becomes: how should each environment decide which version to run? There are three workable strategies, and mature teams usually converge on the second or third.
The first strategy is floating on latest. Every environment pulls the newest commit. This is simple and fine for a solo developer, but it means an experimental commit made at 5 pm on Friday is live in production at 5:01. Do not run this way with real users.
The second strategy is tag-based promotion. You maintain environment tags, typically dev, staging, and prod. New commits land untagged or tagged dev. After the version passes evaluation, someone moves the staging tag to it, and after a bake period, moves prod. Your production service always pulls support-triage:prod, so promotion and rollback are just tag moves in the LangSmith UI or via the API, with zero deploys. This gives you the decoupling benefit while keeping a controlled release path.
The third strategy is hash pinning through configuration. Your service reads a commit hash from its own config system and pulls exactly that commit. This is the most rigid and the most auditable: the deployed config captures precisely which prompt version runs, and changing it goes through your normal config review process. Teams in regulated environments tend to land here.
Whichever strategy you choose, cache the pulled prompt in memory. Pulling from the hub on every request adds latency and creates an availability dependency you do not want on your hot path. A simple pattern covers most needs:
import time
from langsmith import Client
client = Client()
_cache: dict[str, tuple[float, object]] = {}
TTL_SECONDS = 300
def get_prompt(identifier: str):
now = time.time()
if identifier in _cache:
fetched_at, prompt = _cache[identifier]
if now - fetched_at < TTL_SECONDS:
return prompt
try:
prompt = client.pull_prompt(identifier)
_cache[identifier] = (now, prompt)
return prompt
except Exception:
# Fall back to a stale copy rather than failing the request
if identifier in _cache:
return _cache[identifier][1]
raiseWith a five-minute TTL, a tag move propagates to all instances within minutes, while the hub itself is off the critical path for essentially all traffic. The stale-on-error fallback means a transient network issue degrades freshness, not availability. For stricter setups, pull once at startup and refresh on a background schedule instead.
Sharing Prompts: Workspaces, the Public Hub, and Collaboration
Versioning solves the history problem. Sharing solves the people problem, and it is where the hub quietly changes how teams work.
Inside a LangSmith workspace, every prompt is visible to every member with access, in one searchable place. That kills the most common failure mode of prompt work: three teams independently maintaining three slightly different summarization prompts because nobody knew the others existed. A shared registry with descriptions and tags makes prompts discoverable the way an internal package registry makes libraries discoverable. It is worth investing in naming conventions early, something like team-purpose-variant, because flat namespaces get crowded fast.
The collaboration loop with non-engineers is the standout feature. A domain expert opens a prompt in the Playground, edits the wording, runs it against sample inputs and a dataset, and commits. Each commit records who made it and supports a commit message explaining why. Engineers never merge a text-only change again, and the expert never waits on a deploy. Meanwhile, the application code keeps pulling by tag, so nothing reaches users until someone deliberately promotes the new commit. Editing is decoupled from releasing, which is exactly the property you want.
The public hub adds an outward-facing dimension. Pulling a battle-tested community prompt for a common pattern, such as RAG answer generation or agent scaffolding, is often a better starting point than a blank page. You can also fork a public prompt into your workspace and evolve it privately. Publishing your own prompts publicly is optional, but it is a genuinely useful way for educators and open-source maintainers to distribute known-good prompts alongside their libraries.
One caution on sharing: prompts frequently encode business logic, product names, internal terminology, and occasionally things they should not, like example data. Treat prompt visibility with the same care as repository visibility, and review a prompt like you would review code before flipping it public.
Common Pitfalls When Teams Adopt the Prompt Hub
Most Prompt Hub problems are workflow problems, and they repeat across teams predictably. Here are the ones worth avoiding from day one.
- Pulling
:latestin production. This is the number one mistake. It turns every experimental commit into an instant production release. Always pull an environment tag or a pinned hash in deployed code. - Pulling on every request without caching. Adds network latency to every LLM call and couples your uptime to the hub's. Cache with a TTL, or load at startup and refresh in the background.
- Skipping commit messages. A history full of unlabeled commits is nearly as opaque as no history. Require a one-line reason for each commit, the same discipline as Git.
- Promoting without evaluation. The hub sits next to LangSmith's dataset and evaluator tooling for a reason. Make "passes the golden dataset" a gate before a commit earns the
prodtag, not an afterthought when users complain. - Forgetting that variables are part of the contract. Renaming an input variable in a prompt, say from
questiontoquery, silently breaks every caller that passes the old name. Treat variable names like a function signature: change them deliberately and version the change. - Letting the workspace turn into a junk drawer. Playground experiments multiply. Archive or delete abandoned prompts, and keep the canonical ones documented in their descriptions, or discovery stops working.
- Ignoring the model config dimension. If you use
include_model, remember that model choice and temperature are now versioned alongside the text. That is a feature, but only if reviewers look at both when approving a commit.
None of these are hard to fix, and a team that adopts tags, caching, commit messages, and eval gates in week one will never really feel them. The pattern behind all of them is the same: the hub gives prompts a software lifecycle, and it pays off exactly to the degree that you actually treat them like software.
Keep Going: Master LangSmith End to End
The Prompt Hub is the version-control layer of a bigger system. Pulling and pushing prompts becomes dramatically more powerful when you combine it with the rest of LangSmith: tracing to see exactly how a prompt version behaves on real traffic, datasets and evaluators to score candidate commits before promotion, and the Playground to iterate with your whole team in the loop. Start small. Push one real prompt from your codebase into the hub, tag it prod, switch your service to pull by tag, and make your next wording change without a deploy. Once you feel that loop, you will not go back to prompts in string constants.
If you want a structured, hands-on path through all of this, the LangSmith Tutorial course on teachyou.ai walks you through the full workflow: tracing your first chains, building datasets, running evaluations, and managing prompts with the hub the way production teams do. It is built by engineers who run LLM systems in production, and it turns the concepts in this article into muscle memory. Your prompts are already versioned in someone's head. Move them somewhere the whole team can see.
BootcampA 30-day guided bootcamp: build, harden and ship a production autonomous agent from scratch.
AI AgentsUnderstand how AI agents really work: the loop, the tools, the memory, and why most agent projects fail.
Related reading