LangChain Mastery

Course Content

LangChain Mastery

7 sections · 109 lessons

How do you implement a custom prompt template with dynamic inputs?


What you need to know

"Dynamic input" means a value that is not simply passed in by the caller. There are three levels, from least to most code.

  1. Partial with a function — for values that are the same kind every time, such as the date or the app version.
  2. A step that computes variables — for values that need a lookup: documents, user profile, prices.
  3. An example selector or a custom class — when which examples or sections appear depends on the input.

Levels 1 and 2 together

Python
from datetime import datefrom langchain_core.prompts import ChatPromptTemplatefrom langchain_core.runnables import RunnablePassthroughprompt = ChatPromptTemplate.from_messages([    ("system", "Today is {today}. Label the enquiry hot, warm or cold. "               "Current offers: {offers}"),    ("human", "{enquiry}"),]).partial(today=lambda: date.today().isoformat())build = RunnablePassthrough.assign(offers=lambda x: active_offers(x["city"])) | promptchain = build | llm | parserchain.invoke({"enquiry": "2BHK in HSR, ready to book this week", "city": "Bengaluru"})

partial(today=...) with a function means the date is fresh on every call, not frozen at start-up. RunnablePassthrough.assign keeps the original input and adds an offers key computed from city. The active_offers function can be tested on its own, without a model.

Level 3: examples chosen per input

Python
from langchain_core.example_selectors import SemanticSimilarityExampleSelectorfrom langchain_core.prompts import FewShotChatMessagePromptTemplateselector = SemanticSimilarityExampleSelector.from_examples(    examples, embeddings, InMemoryVectorStore, k=2, input_keys=["enquiry"])few_shot = FewShotChatMessagePromptTemplate(    example_selector=selector,    example_prompt=ChatPromptTemplate.from_messages(        [("human", "{enquiry}"), ("ai", "{label}")]),    input_variables=["enquiry"],)

Put few_shot between the system and human messages. For each new enquiry, the selector embeds it and inserts the 2 most similar labelled examples.

Keep validation working

LangChain checks that every variable in the template is supplied. That check is what catches a renamed key before the model sees a literal {offers}. Keep variable names in one place and test the prompt with a sample input.

A real-life example

A real-estate firm's lead-qualification prompt labels website enquiries. With 6 fixed examples, it mislabelled villa enquiries, because all 6 examples were about flats. The team built a bank of 120 labelled enquiries and used a semantic example selector with k=3, so a villa question now sees villa examples. They also added the current offers per city through RunnablePassthrough.assign, because "no brokerage this month" changes how urgent a lead is. On 400 held-out enquiries, "hot" precision rose from 72% to 84%, and the prompt stayed shorter than before because it holds 3 examples instead of 6.

Follow-up questions to expect

  • "Partial with a value or with a function?" — A value is fixed when you call partial; a function runs on every format, which is what you want for time or anything that changes.
  • "When would you subclass BasePromptTemplate?" — Rarely: only when prompt building is complex enough to need its own class. A function step before the prompt is usually clearer.
  • "How do you stop the prompt from growing too large?" — Limit k, trim long inputs, or use a length-based example selector with a token budget.