Exploring Few-Shot Prompts with LangChain
Data Mastery Series — Episode 28: LangChain Website (Part 3)
Exploring Few-Shot Prompts with LangChain
Data Mastery Series — Episode 28: LangChain Website (Part 3)

Connect with me and follow our journey: Linkedin, Facebook
Hey everyone! Welcome back to the Data Mastery Series! We’re diving deeper into LangChain and exploring more about prompts. If you’re new here, feel free to catch up on our previous episodes:
- Part 1: LangChain Model I/O Basics
- Part 2: Unpacking Prompt Templates with LangChain
Note: As we dive into LangChain, I’ll be sharing insights and key notes from my own study of the LangChain documentation. Let’s jump in and explore some fascinating features in today’s episode!
Source: https://python.langchain.com/v0.1/docs/modules/model%5Fio/prompts/
Today, we’re continuing our discussion on Prompt, focusing on Few-Shot Prompts, Partial Prompts, and Composition. “Few-shot learning” allows us to give our language models examples to learn from, improving their performance.
1. Few-Shot Examples for Chat Models: Learning from Examples
There are two main approaches to using examples in few-shot prompting:
- A. Fixed Examples
With Fixed Examples, you give the model a set of examples that it will always follow. This approach is simple and effective when you want consistent responses.
Example - Fixed Few-shot Examples
examples = [
{"input": "2+2", "output": "4"},
{"input": "2+3", "output": "5"},
]
example_prompt = ChatPromptTemplate.from_messages(
[
("human", "{input}"),
("ai", "{output}"),
]
)
few_shot_prompt = FewShotChatMessagePromptTemplate(
example_prompt=example_prompt,
examples=examples,
)
final_prompt = ChatPromptTemplate.from_messages(
[
("system", "You are a wondrous wizard of math."),
few_shot_prompt,
("human", "{input}"),
]
)
chat = ChatOpenAI(temperature=0.0, model="gpt-3.5-turbo", api_key=OPENAI_API_KEY)
chain = final_prompt | chat
response = chain.invoke({"input": "What's the square of a triangle?"})
print(response)
Output
'''
content='A triangle does not have a square. The square of a number is the result of multiplying the number by itself.' additional_kwargs={} response_metadata={'token_usage': {'completion_tokens': 23, 'prompt_tokens': 52, 'total_tokens': 75, 'completion_tokens_details': {'audio_tokens': None, 'reasoning_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}}, 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-8e084845-a7fe-4340-8225-efa68fbc4f4f-0'
'''
In this example, we’ve given the model some basic math problems, like "2+2" → "4" and "2+3" → "5", When the user asks a question, the model combines these examples with its knowledge, generating a relevant response.
- B. Dynamic Examples:
Sometimes, we want the model to pick examples that match the input’s context. Dynamic Examples allow the AI to find the most relevant examples for the current query, adjusting its response accordingly.
Example - Dynamic Few-shot Examples
examples = [
{"input": "2+2", "output": "4"},
{"input": "2+3", "output": "5"},
{"input": "2+4", "output": "6"},
{"input": "What did the cow say to the moon?", "output": "nothing at all"},
{"input": "Write me a poem about the moon", "output": "One for the moon, and one for me, who are we to talk about the moon?"},
]
to_vectorize = [" ".join(example.values()) for example in examples]
embeddings = OpenAIEmbeddings(api_key=OPENAI_API_KEY)
vectorstore = Chroma.from_texts(to_vectorize, embeddings, metadatas=examples)
example_selector = SemanticSimilarityExampleSelector(
vectorstore=vectorstore,
k=2,
)
few_shot_prompt = FewShotChatMessagePromptTemplate(
input_variables=["input"],
example_selector=example_selector,
example_prompt=ChatPromptTemplate.from_messages(
[("human", "{input}"), ("ai", "{output}")]
),
)
print(few_shot_prompt.format(input="What's 3+3?"))
Output
'''
Human: 2+3
AI: 5
Human: 2+2
AI: 4
'''
In this example, we use a Semantic Similarity Selector to pull in the most relevant examples based on the query. When the user asks “What’s 3+3?”, the prompt selects math-related examples, such as “2+3” and “2+2.” This dynamic setup ensures the model’s response is closely aligned with the type of question being asked.
Example - Dynamic Few-shot Examples
print(few_shot_prompt.format(input="horse on the moon"))
Output
'''
Human: What did the cow say to the moon?
AI: nothing at all
Human: Write me a poem about the moon
AI: One for the moon, and one for me, who are we to talk about the moon?
'''
This time, when the input is about “the moon,” the model picks examples related to the moon, showing how it can adapt to different contexts. This flexibility is key to making chatbots that can handle a variety of topics with relevant and interesting responses.
2. Few-shot prompt templates
There are two main approaches: using an example set (Fixed Set) or an example selector.
- A. Using an example (Fixed Set)
This approach involves giving the model a specific set of examples that demonstrate the type of responses we want. The model uses these examples to learn the desired format and logic, which it then applies to new questions.
Example - Using an example
examples = [
{
"question": "Who lived longer, Muhammad Ali or Alan Turing?",
"answer": """
Are follow up questions needed here: Yes.
Follow up: How old was Muhammad Ali when he died?
Intermediate answer: Muhammad Ali was 74 years old when he died.
Follow up: How old was Alan Turing when he died?
Intermediate answer: Alan Turing was 41 years old when he died.
So the final answer is: Muhammad Ali
""",
},
{
"question": "When was the founder of craigslist born?",
"answer": """
Are follow up questions needed here: Yes.
Follow up: Who was the founder of craigslist?
Intermediate answer: Craigslist was founded by Craig Newmark.
Follow up: When was Craig Newmark born?
Intermediate answer: Craig Newmark was born on December 6, 1952.
So the final answer is: December 6, 1952
""",
},
{
"question": "Who was the maternal grandfather of George Washington?",
"answer": """
Are follow up questions needed here: Yes.
Follow up: Who was the mother of George Washington?
Intermediate answer: The mother of George Washington was Mary Ball Washington.
Follow up: Who was the father of Mary Ball Washington?
Intermediate answer: The father of Mary Ball Washington was Joseph Ball.
So the final answer is: Joseph Ball
""",
},
{
"question": "Are both the directors of Jaws and Casino Royale from the same country?",
"answer": """
Are follow up questions needed here: Yes.
Follow up: Who is the director of Jaws?
Intermediate Answer: The director of Jaws is Steven Spielberg.
Follow up: Where is Steven Spielberg from?
Intermediate Answer: The United States.
Follow up: Who is the director of Casino Royale?
Intermediate Answer: The director of Casino Royale is Martin Campbell.
Follow up: Where is Martin Campbell from?
Intermediate Answer: New Zealand.
So the final answer is: No
""",
},
]
example_prompt = PromptTemplate(
input_variables=["question", "answer"],
template="Question: {question}\n{answer}"
)
prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
suffix="Question: {input}",
input_variables=["input"],
)
print(prompt.format(input="Who was the father of Mary Ball Washington?"))
Output
'''
Question: Who lived longer, Muhammad Ali or Alan Turing?
Are follow up questions needed here: Yes.
Follow up: How old was Muhammad Ali when he died?
Intermediate answer: Muhammad Ali was 74 years old when he died.
Follow up: How old was Alan Turing when he died?
Intermediate answer: Alan Turing was 41 years old when he died.
So the final answer is: Muhammad Ali
Question: When was the founder of craigslist born?
Are follow up questions needed here: Yes.
Follow up: Who was the founder of craigslist?
Intermediate answer: Craigslist was founded by Craig Newmark.
Follow up: When was Craig Newmark born?
Intermediate answer: Craig Newmark was born on December 6, 1952.
So the final answer is: December 6, 1952
Question: Who was the maternal grandfather of George Washington?
Are follow up questions needed here: Yes.
Follow up: Who was the mother of George Washington?
Intermediate answer: The mother of George Washington was Mary Ball Washington.
Follow up: Who was the father of Mary Ball Washington?
Intermediate answer: The father of Mary Ball Washington was Joseph Ball.
So the final answer is: Joseph Ball
Question: Are both the directors of Jaws and Casino Royale from the same country?
Are follow up questions needed here: Yes.
Follow up: Who is the director of Jaws?
Intermediate Answer: The director of Jaws is Steven Spielberg.
Follow up: Where is Steven Spielberg from?
Intermediate Answer: The United States.
Follow up: Who is the director of Casino Royale?
Intermediate Answer: The director of Casino Royale is Martin Campbell.
Follow up: Where is Martin Campbell from?
Intermediate Answer: New Zealand.
So the final answer is: No
Question: Who was the father of Mary Ball Washington?
'''
In this setup, the model refers to the full list of examples and applies similar logic to the input question.
- B. Using an example selector
Sometimes, we want the model to focus on examples most relevant to the input question, rather than going through an entire set. An Example Selector helps by choosing only the examples that best match the current question. This can improve response accuracy and relevance.
Example - Using an example selector
example_selector = SemanticSimilarityExampleSelector.from_examples(
examples,
OpenAIEmbeddings(api_key=OPENAI_API_KEY),
Chroma,
k=1,
)
question = "Who was the father of Mary Ball Washington?"
selected_examples = example_selector.select_examples({"question": question})
for example in selected_examples:
print(f"question: {example['question']}")
print("\n")
print(f"answer: {example['answer']}")
Output
'''
question: Who was the maternal grandfather of George Washington?
answer:
Are follow up questions needed here: Yes.
Follow up: Who was the mother of George Washington?
Intermediate answer: The mother of George Washington was Mary Ball Washington.
Follow up: Who was the father of Mary Ball Washington?
Intermediate answer: The father of Mary Ball Washington was Joseph Ball.
So the final answer is: Joseph Ball
'''
In this example, the Semantic Similarity Selector uses embeddings to match the input question with the example that is most similar to it.
3. Partial Prompt Templates
Partial Prompts allow you to pre-fill parts of a prompt and leave placeholders to fill in later. This is especially useful when you have some details ready but need to wait for others. Let’s look at two ways to use partial prompts: with strings and with functions.
- A. Partial with strings
Sometimes, you only have part of the information you need for a prompt. With partials, you can set certain parts now and complete the rest later.
Example - Partial with strings
prompt = PromptTemplate.from_template("{foo}{bar}")
partial_prompt = prompt.partial(foo="foo")
rompt.partial(foo="foo") creates a partial template where the value of 'foo' is set to 'foo',
but 'bar' is still unset.
##########################################
Later, we can just pass the value for 'bar'
print(partial_prompt.format(bar="baz"))
Output
'''
foobaz
'''
This example creates a partial template with foo set to "foo" and leaves bar as a placeholder. Later, you can fill in bar with "baz," resulting in "foobaz." You can also set initial values when defining the template:
Example - Partial with strings
prompt = PromptTemplate(
template="{foo}{bar}", input_variables=["bar"], partial_variables={"foo": "foo"}
)
print(prompt.format(bar="baz")))
Output
'''
foobaz
'''
- B. Partial with Functions
Partial prompts can also use functions, which is helpful if you want a value that changes, like the current date or time.
Example - Partial with Functions
def _get_datetime():
now = datetime.now()
return now.strftime("%m/%d/%Y, %H:%M:%S")
prompt = PromptTemplate(
template="Tell me a {adjective} joke about the day {date}",
input_variables=["adjective", "date"],
)
partial_prompt = prompt.partial(date=_get_datetime)
print(partial_prompt.format(adjective="funny"))
Output
'''
Tell me a funny joke about the day 10/10/2024, 10:10:10 (หรือเวลา ณ ขณะนั้น)
'''
Here, _get_datetime() dynamically retrieves the current date and time each time it’s called, so you can always generate a prompt with the latest information. Set date as a template:
Example - Partial with Functions
prompt = PromptTemplate(
template="Tell me a {adjective} joke about the day {date}",
input_variables=["adjective"],
partial_variables={"date": _get_datetime},
)
print(prompt.format(adjective="funny"))
Output
'''
Tell me a funny joke about the day 10/10/2024, 10:10:10 (หรือเวลา ณ ขณะนั้น)
'''
4. Composition: Building Complex Prompts
LangChain also supports Prompt Composition, allowing you to build more sophisticated prompts by combining simple ones. This makes it easier to reuse components across different prompts.
- A. String prompt composition
String prompt composition lets you chain templates together, creating a more detailed prompt from simple components.
Example - String prompt composition
prompt = (
PromptTemplate.from_template("Tell me a joke about {topic}")
+ ", make it funny"
+ "\n\nand in {language}"
)
formatted_prompt = prompt.format(topic="sports", language="Thai")
print(formatted_prompt).
Output
'''
Tell me a joke about sports, make it funny
and in Thai
'''
You can then combine this prompt with a chat model to get a complete response:
Example - String prompt composition
model = ChatOpenAI(model="gpt-4", api_key=OPENAI_API_KEY)
chain = LLMChain(llm=model, prompt=prompt)
result = chain.run(topic="sports", language="Thai")
result
Output
'''
เขาถามนักกีฬาว่า "ทำไมคุณถึงชอบวิ่งครับ?"
นักกีฬาตอบว่า "เพราะว่าถ้าฉันไม่วิ่ง ฉันก็จะต้องออกกำลังกายครับ
'''
- B. Chat Prompt Composition
Chat Prompt Composition is designed for conversation-style prompts, enabling you to set up dialogue sequences easily.
Example - Chat Prompt Composition
prompt = SystemMessage(content="You are a nice pirate")
new_prompt = (
prompt + HumanMessage(content="hi") + AIMessage(content="what?") + "{input}"
)
print(new_prompt.format_messages(input="i said hi"))
Output
'''
[SystemMessage(content='You are a nice pirate', additional_kwargs={}, response_metadata={}),
HumanMessage(content='hi', additional_kwargs={}, response_metadata={}),
AIMessage(content='what?', additional_kwargs={}, response_metadata={}),
HumanMessage(content='i said hi', additional_kwargs={}, response_metadata={})]
'''
Using this prompt with the model:
Example - Chat Prompt Composition
chain = LLMChain(llm=model, prompt=new_prompt)
response = chain.run("i said hi")
response
Output
'''
Ahoy there! How can I assist you on this fine day?
'''
- C. Using PipelinePrompt
The PipelinePromptTemplate allows for building complex prompts by defining separate parts, making the overall prompt easier to manage and reuse.
Example - Using PipelinePrompt
full_template = """{introduction}
{example}
{start}"""
full_prompt = PromptTemplate.from_template(full_template)
introduction_template = """You are impersonating {person}."""
introduction_prompt = PromptTemplate.from_template(introduction_template)
example_template = """Here's an example of an interaction:
Q: {example_q}
A: {example_a}"""
example_prompt = PromptTemplate.from_template(example_template)
start_template = """Now, do this for real!
Q: {input}
A:"""
start_prompt = PromptTemplate.from_template(start_template)
Combine into a pipeline prompt
input_prompts = [
("introduction", introduction_prompt),
("example", example_prompt),
("start", start_prompt),
]
pipeline_prompt = PipelinePromptTemplate(
final_prompt=full_prompt, pipeline_prompts=input_prompts
)
print(
pipeline_prompt.format(
person="Elon Musk",
example_q="What's your favorite car?",
example_a="Tesla",
input="What's your favorite social media site?",
)
)
Output
'''
You are impersonating Elon Musk.
Here's an example of an interaction:
Q: What's your favorite car?
A: Tesla
Now, do this for real!
Q: What's your favorite social media site?
A:
'''
In this post, we’ve covered ways to build and refine prompts in LangChain, making them more flexible and capable of handling complex interactions. In the next episode, we’ll dive into Chat Models and further explore LangChain’s capabilities. Thanks for joining me, and happy prompt crafting!
Data Science Explore the world of data science with Donato_Story
Dashboard Discover the power of data visualization with Donato_Story
Donato_Journey Join me on my journey (Thai version)
Course_Review Discover the training courses with Donato_Story (Thai version)
I really value your thoughts and feedback. Please share any comments or questions you have below, or reach out to me on:
Medium: medium.com/donato-story
Facebook: web.facebook.com/DonatoStory
Linkedin: linkedin.com/in/nattapong-thanngam
Originally published on Medium
Related
Chat with Document: A Closer Look at Splitting, Embeddings, and RAG
Data Mastery Series — Episode 21: The Chat with Document and Langchain Series (Part 2)
Chat with Document: Basics and Demonstrations
Data Mastery Series — Episode 20: The Chat with Document and Langchain Series (Part 1)
Continue Exploring Chat Models with LangChain
Data Mastery Series — Episode 31: LangChain Website (Part 6)
Continue Exploring Retrievers with LangChain
Data Mastery Series — Episode 39: LangChain Website (Part 14 )