DEV Community

Cover image for Build an Simple AI Assistant Using PromptTemplate & LangChain
vaasav kumar
vaasav kumar

Posted on

Build an Simple AI Assistant Using PromptTemplate & LangChain

In the previous blog, we saw how to work with multiple AI providers.

In this blog, let’s take the next step and use LangChain to build simple helper functions.

Let’s imagine this use case:

Your friend is a doctor and wants to open a new clinic. They need help with:

  • generating a professional clinic name
  • searching possible locations for the clinic

With AI, we can build a simple workflow for this.

In this blog, we will cover:

  1. Generate a clinic name using an LLM
  2. Generate the same using PromptTemplate
  3. Write code to suggest locations for the clinic

Refer previous blog for selecting LLM, then follow the below steps

pip install langchain langchain-openai
Enter fullscreen mode Exit fullscreen mode

1. Generate Clinic Name Using LLM

response = llm.invoke("Opening New Ayurvedic clinic. Generate only 1 professional name for that.")
response.content
Enter fullscreen mode Exit fullscreen mode

Output

'Here\'s a professional name for the Ayurvedic clinic:\n\n1. **Dhara Wellness Centre**\n\nThis name is inspired by "Dhara", a Sanskrit word that means \'stream\' or \'flow\', which is often used in Ayurvedic practices to describe the continuous flow of healing energy, or \'prana\'. This name conveys the sense of a holistic and continuous approach to wellness, making it a fitting choice for an Ayurvedic clinic.'
Enter fullscreen mode Exit fullscreen mode

This works, but the output is longer than expected.
We asked for only one name, but the model also returned an explanation.

That is normal with LLMs, and this is where better prompt design helps.

2. Generate Clinic Name Using PromptTemplate

Instead of writing the full prompt again and again, we can use PromptTemplate.

This makes the code cleaner and reusable.

from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate

def generate_clinic_name(llm, clinic_type):
    name_template = PromptTemplate.from_template(
        "Opening New {clinic_type} clinic. Generate only 1 professional name for that."
    )
    chain = name_template | llm
    response = chain.invoke({"clinic_type": clinic_type})
    return response.content

generate_clinic_name(llm, 'ayurvedic')
Enter fullscreen mode Exit fullscreen mode

This approach is better because:

  • the prompt becomes reusable
  • we can pass different clinic types
  • the code is cleaner and easier to maintain

For example, you can now generate names for ayurvedic clinic, dental clinic, homeopathy clinic, and more.

3A. Search Locations for a Clinic

We will ask the model to suggest clinic locations based on:

  • clinic type
  • city
  • distance radius
from langchain_core.runnables import RunnablePassthrough

def search_location_for_clinic(llm, clinic_type, city, km):
    name_template = PromptTemplate.from_template(
        "Opening New {clinic_type} clinic. Generate only 1 professional name for that."
    )

    search_location_template = PromptTemplate.from_template(
        "Opening a new clinic for {new_clinic}, search 5 locations in {city} where no other opponents are found within {km} distance."
        "Return ONLY comma-separated area names. No explanation, no numbering."
    )

    name_chain = name_template | llm
    full_chain = (
        RunnablePassthrough()
        | {
            "new_clinic": name_chain,
            "city": lambda x: x["city"],
            "km": lambda x: x["km"],
        }
        | search_location_template
        | llm
    )

    response = full_chain.invoke({
        "clinic_type": clinic_type,
        "city": city,
        "km": km
    })
    return response.content


location = search_location_for_clinic(llm, 'ayurvedic', 'chennai', 5)
print(location)
Enter fullscreen mode Exit fullscreen mode

Output

Arumbakkam, Jafferkhanpet, Nanganallur, Pallavaram, Perumbakkam, Singaperumal Koil, Thirumazhisai, Vandalur
Enter fullscreen mode Exit fullscreen mode

FYI, I have given prompt to check opponents factor also but unfortunately that doesn't seems working. May be we need to combine tools like Google Maps and Business data.

3B. Display Location with Clinic Name

Now let’s improve the result by returning both:

  • clinic name
  • suggested locations
from langchain_core.output_parsers import StrOutputParser

def search_location_for_clinic_with_name_method1(llm, clinic_type, city, km):
    parser = StrOutputParser()

    name_template = PromptTemplate.from_template(
        "Opening New {clinic_type} clinic. Generate only 1 professional name for that."
    )

    search_location_template = PromptTemplate.from_template(
        "Opening a new clinic for {new_clinic}, search 5 locations in {city} where no other opponents are found within {km} distance."
        "Return ONLY comma-separated area names. No explanation, no numbering."
    )

    name_chain = name_template | llm | parser

    full_chain = (
        RunnablePassthrough()
        | {
            "new_clinic": name_chain,
            "city": lambda x: x["city"],
            "km": lambda x: x["km"],
        }
        | {
            "clinic_name": lambda x: x["new_clinic"],
            "locations": search_location_template | llm | parser,
        }
    )

    response = full_chain.invoke({
        "clinic_type": clinic_type,
        "city": city,
        "km": km
    })
    return response

location = search_location_for_clinic_with_name_method1(llm, 'homeopathy', 'chennai', 10)
print(location)
Enter fullscreen mode Exit fullscreen mode

Output

{'clinic_name': '"Nature\'s Balance Homeopathic Centre"', 'locations': 'Ambattur, Thirumullaivoyal, Vandalur, Kattankulathur, Pammal'}
Enter fullscreen mode Exit fullscreen mode

3C. Beginner-Friendly Version

If you are new to LangChain, the previous chain-based approach may look advanced.

So here is a simpler version that does the same thing step by step.

def search_location_for_clinic_with_name_method2(llm, clinic_type, city, km):
    parser = StrOutputParser()

    name_template = PromptTemplate.from_template(
        "Opening New {clinic_type} clinic. Generate only 1 professional name for that."
    )

    search_location_template = PromptTemplate.from_template(
        "Opening a new clinic for {new_clinic}, search 5 locations in {city} where no other opponents are found within {km} distance. "
        "Return ONLY comma-separated area names. No explanation, no numbering."
    )

    # Step 1: Get clinic name
    name_chain = name_template | llm | parser
    clinic_name = name_chain.invoke({"clinic_type": clinic_type}).strip()

    # Step 2: Get locations
    location_chain = search_location_template | llm | parser
    locations = location_chain.invoke({
        "new_clinic": clinic_name,
        "city": city,
        "km": km
    })

    # Return both
    return {
        "clinic_name": clinic_name,
        "locations": locations
    }

location = search_location_for_clinic_with_name_method2(llm, 'ayurvedic', 'madurai', 5)
print(location)
Enter fullscreen mode Exit fullscreen mode

Output

{'clinic_name': '"Sanjeevani Ayurvedic Wellness Centre" \n\nThis name combines "Sanjeevani" which is a Sanskrit word meaning "elixir of life" and "Ayurvedic Wellness Centre" to convey a holistic approach to health and wellness.', 'locations': 'Aruppukottai Road, Alagappan Nagar, Veerapandi, Pasumalai, Kattukottai.'}
Enter fullscreen mode Exit fullscreen mode

For Developers

If you are learning AI, examples like this are very useful because they move beyond single prompts.

You start learning how to:

  • break a problem into steps
  • create reusable helper functions
  • build mini workflows using LangChain

That is where real AI development begins.

In the next blog, we’ll turn this into a real web app using Streamlit.

Top comments (0)