• Home
  • LLMs
  • Python
  • Docker
  • Kubernetes
  • Java
  • Maven
  • All
  • About
LLMs | Prompt Engineering
  1. Introduction to Prompt Engineering
  2. Prompt Types and Techniques
  3. Example: Basic Prompts
  4. Example: Instruction Prompts
  5. Example: Prompt Chaining
  6. Example: Prompt Chaining - Multiple Chains

  1. Introduction to Prompt Engineering
    Prompt engineering is the systematic process of designing, refining, and optimizing input prompts to guide large language models (LLMs) toward generating desired outputs. It requires an understanding of both the model's capabilities and the specific task requirements.

    Good prompts significantly improve output quality and relevance, ensure consistent results across similar tasks, and provide better control over model behavior and output format.

    Effective prompts consist of several key components that work together to guide the model:

    • Role Definition: Establish the model's role or persona.
      You are a software engineer.

    • Task Instructions: Provide specific, unambiguous instructions.
      Review the following code and identify any issues that may affect performance.

    • Context and Background: Supply relevant background information.
      Context: This review is necessary due to a significant performance regression that may be linked to this section of the code.

    • Input Data: Present the data that needs to be processed.
      Data: [Insert the code here]

    • Output Specifications: Define the desired format, length, tone, and structure of the response.
      Format: Provide a structured review with:
      - Issues (bullet points with explanations)
      - Recommendation (clear action item)

    • Constraints and Guidelines: Set boundaries and specify any limitations or requirements.
      Constraints:
      - Keep review objective and data-driven
      - Avoid speculation beyond provided code

    • Examples (Optional): Provide sample inputs and outputs to demonstrate expected behavior.

    Instructions can be framed as questions, requests, or statements. They should clearly and specifically describe the task to be performed. Instructions can be placed at either the beginning or end of the prompt.

    When accuracy is critical, it's best to instruct the model to respond only if it is confident in its answer.

    For complex tasks, consider breaking the prompt into smaller, simpler prompts and using them across multiple model calls—a technique known as chain prompting. The output from one model can be used as input for the next, potentially involving different models at each step.
  2. Prompt Types and Techniques
    • Basic prompts:
      The prompt can be a simple question or sentence with no guidelines given to the model. The model will try to answer the question or complete the sentence.

      Input: What is the capital of Canada?
      Output: The capital of Canada is Ottawa.
      Input/Output:
      [
          {'role': 'user', 'content': 'What is the capital of Canada?'},
          {'role': 'assistant', 'content': 'The capital of Canada is Ottawa.'}
      ]
    • Instruction prompts:
      Structured prompts with clear role definition and specific instructions. An instruction prompt has two parts: the instruction and the data

      Template:
      Role: you are a [expert] [role]
      Task: [clear instruction]
      Input: [data to be processed]
      Output: [format/structure]
      Input:
      <Instruction> You are a helpful assistant. You will classify the text into negative or positive.
      <data> The weather is great today!
      Output: Positive
      Input/Output:
      [
          {'role': 'system', 'content': 'You are a helpful assistant. You will classify the text into negative or positive.'},
          {'role': 'user', 'content': 'The weather is great today!'},
          {'role': 'assistant', 'content': 'Positive'}
      ]
    • Instruction prompts with indicators:
      The indicators guide the LLM toward the desired output.

      Input:
      <Instruction> You are a helpful assistant. You will extract entities from the text.
      <indicator> Definition: an entity is an organization, a person, or a location.
      <data> The capital of Canada is Ottawa.
      Output:
      [
          {'role': 'system', 'content': 'You are a helpful assistant. You will extract entities from the text.'},
          {'role': 'system', 'content': 'Definition: an entity is an organization, a person, or a location.'},
          {'role': 'user', 'content': 'The capital of Canada is Ottawa.'},
          {'role': 'assistant', 'content': 'Ottawa - Location (capital of Canada)'}
      ]
    • Few-Shot Prompting:
      Providing examples to demonstrate the desired input-output pattern.

      Structure:
      • Zero-shot prompting: no examples provided.
      • One-shot prompting: single example provided.
      • Few-shot prompting: multiple examples provided.

      Input:
      <question> What's the capital of Canada?
      <answer> Ottawa is the capital of Canada and is located in Ontario.
      <Instruction> You are a helpful assistant. Answer the following question?
      <data>: What's the capital of France?
      Input/Output:
      [
          {'role': 'system', 'content': 'You are a helpful assistant. Answer the following questions.'},
          {'role': 'user', 'content': 'What is the capital of Canada?'},
          {'role': 'assistant', 'content': 'Ottawa is the capital of Canada and is located in Ontario.'},
          {'role': 'user', 'content': 'What is the capital of France?'},
          {'role': 'assistant', 'content': 'Paris is the capital of France. It is not only the political center but also a major cultural and ...'}
      ]
    • Chain-of-Thought Prompting:
      Encouraging the model to show its reasoning process step-by-step.

      Example:
      Problem: I have five apples. If I ate one in the morning and three in the afternoon, how many apples do I have left?
      
      Let's solve this step by step:
      1. Calculate the total number of apples eaten: 1 (morning) + 3 (afternoon) = 4
      2. Subtract the total eaten from the original amount: 5 - 4 = 1
      3. Answer: I have 1 apple left.
    • Prompt Chaining:
      Breaking complex tasks into smaller, sequential prompts where each output feeds into the next prompt.
  3. Example: Basic Prompts
    Let's work on this simple basic prompt.

    Let's download the model:
    $ wget https://huggingface.co/microsoft/Phi-3-mini-4k-instruct-gguf/resolve/main/Phi-3-mini-4k-instruct-q4.gguf
    Python code:
    $ vi prompt.py
    from langchain_community.llms.llamacpp import LlamaCpp
    from langchain_core.callbacks import CallbackManager, StreamingStdOutCallbackHandler
    
    callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])
    
    llm = LlamaCpp(
        model_path="./Phi-3-mini-4k-instruct-q4.gguf",
        temperature=0,
        max_tokens=50,
        top_p=0,
        callback_manager=callback_manager,
        verbose=False
    )
    
    prompt = "What's 1+1?"
    
    llm.invoke(prompt)
    Run the Python script:
    $ python3 prompt.py
    Output:
    <|assistant|> 1+1 equals 2.
  4. Example: Instruction Prompts
    Let's work on this simple instruction prompt.

    Python code:
    $ vi instruction-prompt.py
    from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
    
    model = AutoModelForCausalLM.from_pretrained("microsoft/Phi-4-mini-instruct")
    tokenizer = AutoTokenizer.from_pretrained("microsoft/Phi-4-mini-instruct")
    
    generator = pipeline(
        "text-generation",
        model=model,
        tokenizer=tokenizer
    )
    
    generation_args = {
        "max_new_tokens": 10,
        "return_full_text": False,
        "do_sample": False,
    }
    
    prompt = [
        {"role": "system", "content": "You are a helpful assistant. You will answer questions in a concise and informative manner."},
        {"role": "user", "content": "What's the capital of Canada?"}
    ]
    
    output = generator(prompt, **generation_args)
    
    print(output[0]["generated_text"]) # Ottawa
    
    #prompt_template = generator.tokenizer.apply_chat_template(prompt, tokenize=False)
    #print(prompt_template)
    Run the Python script:
    $ python3 instruction-prompt.py
    Output:
    Ottawa
    If we set the "return_full_text" parameter to "True", we can see the full chat text:
    [
        {'role': 'system', 'content': 'You are a helpful assistant. You will answer questions in a concise and informative manner.'},
        {'role': 'user', 'content': "What's the capital of Canada?"},
        {'role': 'assistant', 'content': 'Ottawa'}
    ]
    If you uncomment these two lines in the code above, you will see the prompt template as created by the pipeline from the prompt:
    prompt_template = generator.tokenizer.apply_chat_template(prompt, tokenize=False)
    print(prompt_template)
    Output:
    <|system|>You are a helpful assistant. You will answer questions in a concise and informative manner.<|end|>
    <|user|>What's the capital of Canada?<|end|>
    <|endoftext|>
    Note the special tokens: |system|, |user|, |assistant|

    • System: provides guidelines for the model
      <|system|>: Start of guidelines
      You are a helpful assistant. You will answer questions in a concise and informative manner.: guidelines
      <|end|>: end of guidelines
    • User: provides the user input
      <|user|>: Start of prompt
      What's the capital of Canada?: prompt
      <|end|>: end of prompt
    • Assistant: gives the generated output
      <|assistant|>: start of output
      Ottawa: output
      <|end|>: end of output
    • The end of text:
      <|endoftext|>: end of the model output
  5. Example: Prompt Chaining
    Let's use LangChain to create a simple chain between a prompt and a model.

    Python code:
    $ vi chain-prompt.py
    from langchain_community.llms.llamacpp import LlamaCpp
    from langchain_core.callbacks import CallbackManager, StreamingStdOutCallbackHandler
    from langchain_core.prompts import PromptTemplate
    
    template = """Question: {question}
    
    Answer: Explain how you arrived at the correct answer."""
    
    prompt = PromptTemplate.from_template(template)
    
    callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])
    
    llm = LlamaCpp(
        model_path="./Phi-3-mini-4k-instruct-q4.gguf",
        temperature=0,
        max_tokens=100,
        top_p=0,
        callback_manager=callback_manager,
        verbose=False
    )
    
    llm_chain = prompt | llm
    
    llm_chain.invoke({"question": "What's 1+1?"})
    Run the Python script:
    $ python3 chain-prompt.py
    Output:
    <|assistant|> To arrive at the correct answer for 1+1, we start with the number 1 and add another 1 to it.
    When you combine one unit with another unit, you get a total of two units.
    Therefore, 1 + 1 equals 2.
    This is based on basic arithmetic addition where combining quantities results in their sum.
    ```
  6. Example: Prompt Chaining - Multiple Chains
    Let's use LangChain to chain the execution of two prompts.

    Python code:
    $ vi multiple-chain-prompt.py
    from langchain_community.llms.llamacpp import LlamaCpp
    from langchain_core.callbacks import CallbackManager, StreamingStdOutCallbackHandler
    from langchain_core.prompts import PromptTemplate
    
    callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])
    
    llm = LlamaCpp(
        model_path="./Phi-3-mini-4k-instruct-q4.gguf",
        temperature=0,
        max_tokens=100,
        top_p=0,
        callback_manager=callback_manager,
        verbose=False
    )
    
    sentiment_template = """<|user|>
    Analyze the following sentence whether it is positive or negative {sentence}.<|end|>
    <|assistant|>"""
    
    sentiment_prompt = PromptTemplate(
        template=sentiment_template,
        input_variables=["sentence"]
    )
    
    sentiment_llmchain = sentiment_prompt | llm
    
    sentiment_refined_template = """<|user|>
    If the sentiment of the sentence is negative, rewrite the sentence {sentence} to sound positive.<|end|>
    <|assistant|>"""
    
    sentiment_refined_prompt = PromptTemplate(
        template=sentiment_refined_template,
        input_variables=["sentence"]
    )
    
    sentiment_refined_llmchain = sentiment_refined_prompt | llm
    
    llm_chain = sentiment_llmchain | sentiment_refined_llmchain
    
    llm_chain.invoke("Not a good day today. I don't feel like going out!")
    Run the Python script:
    $ python3 multiple-chain-prompt.py
    Output:
    The sentence "Not a good day today. I don't feel like going out!" is negative.
    It expresses dissatisfaction with the current day and a lack of desire to engage in social activities, indicating an overall unfavorable mood or sentiment.
    
    Despite today not being as vibrant as I'd hoped, it presents a perfect opportunity for some cozy indoor activities that I truly enjoy!
© 2025  mtitek