πŸ“• Build AI Agents using LangGraph.js is now out!

Prompt Templates, Partial Templates, and Composition in LangChain.js

LangChain.js offers powerful tools for formatting and interacting with text prompts for LLMs.

Given that LLMs use natural language as their primary input and output, LangChain has a core module dedicated to formatting and interacting with text prompts.

Keep in mind that, in their essence, LLMs are giant functions that map text to text.

In this article, we will cover:

  1. The PromptTemplate class in LangChain.js
  2. Using F-String or Mustache syntax
  3. How to create Partial Templates in LangChain.js
  4. Template composition using PipelinePromptTemplate

The PromptTemplate class in LangChain.js

The core class for handling input prompts in LangChain.js is the PromptTemplate class.

The PromptTemplate allows you to create templates that can be dynamically filled with data. Think of the PromptTemplate as a parameterized editable prompt, with its final form determined at execution.

Here's a simple JS example:

import { PromptTemplate } from '@langchain/core/prompts'

const template = `
You are an expert in the {lang} programming language.
{query}
`

// `fromTemplate` will interpolate the `inputVariables`
const promptFromTemplate = PromptTemplate.fromTemplate(template)

const prompt = await promptFromTemplate.format({
    lang: 'JavaScript', 
    query: 'Write a function to calculate the square of a number.'
})

console.log(prompt)
// You are an expert in the JavaScript programming language.
// Write a function to calculate the square of a number.

To see how to execute the actual JS code, refer to this article on how to execute AI-generated code with LangChain.

LangChain's prompt templates are similar to JavaScript's template literals or Lodash's template function, but are specifically adapted for interactions with an LLM.

Using F-String or Mustache Syntax

The default format for writing prompt templates is the F-String format, popular in Python:

const prompt = PromptTemplate.fromTemplate(
  `What is the capital of {country}?`
)

If you prefer the more familiar double curly braces JavaScript Mustache format:

const prompt = PromptTemplate.fromTemplate(
  `What is the capital of {{country}}?`,
  {templateFormat: "mustache"}
)

How to create Partial Templates in LangChain.js

Sometimes, you'll have some values for the inputVariables, but not all of them initially. LangChain.js simplifies handling this with the partial() method of PromptTemplate.

This is also useful for functions like getting the current date.

Here's a JavaScript example of its usage:

import { PromptTemplate } from '@langchain/core/prompts'

const getDateNow = () => new Date().toLocaleDateString()

const template = `
I initially visited {country1}, but as of {now}, 
I visited {country2} as well.`

const prompt = new PromptTemplate({
    template,
    inputVariables: ['now', 'country1', 'country2']
})

const partial = await prompt.partial({
    now: getDateNow,
    country1: 'πŸ‡ͺπŸ‡Έ Spain'
})

const formatted = await partial.format({ country2: 'πŸ‡ΊπŸ‡Έ USA' })

console.log(formatted)
// I initially visited πŸ‡ͺπŸ‡Έ Spain, but as of 5/8/2024, 
// I visited πŸ‡ΊπŸ‡Έ USA as well.

Using the .partial() method, you can fill in data as it becomes available and build the final prompt by calling format().

Template Composition Using the PipelinePromptTemplate

Advanced prompts often have multiple sections that need to be consolidated.

LangChain.js allows you to combine multiple PromptTemplate instances into a single one using the PipelinePromptTemplate class.

This is particularly useful for few-shot prompting, where you provide examples to the LLM.

Here's how to implement this:

import { 
    PipelinePromptTemplate, PromptTemplate 
} from '@langchain/core/prompts'

const fullTemplate = `
{intro}

{example}

{actual}`

const fullPrompt = PromptTemplate.fromTemplate(fullTemplate)

const introTemplate = `You are impersonating {who}`

const exampleTemplate = `
Here's an example Q&A:
Q: {exampleQuestion}
A: {exampleAnswer}
`

const actualTemplate = `
Here's the next Q&A:
Q: {actualQuestion}
A:
`

const introPrompt = PromptTemplate.fromTemplate(introTemplate)
const examplePrompt = PromptTemplate.fromTemplate(exampleTemplate)
const actualPrompt = PromptTemplate.fromTemplate(actualTemplate)

const composedPrompt = new PipelinePromptTemplate({
    pipelinePrompts: [
        { name: 'intro', prompt: introPrompt },
        { name: 'example', prompt: examplePrompt },
        { name: 'actual', prompt: actualPrompt },
    ],
    finalPrompt: fullPrompt,
})

const finalPrompt = await composedPrompt.format({
    who: 'Luke Skywalker',
    exampleQuestion: 'What is your main weapon?',
    exampleAnswer: "It's the lightsaber.",
    actualQuestion: 'Who is your father?'
})

console.log(finalPrompt)

And the output of the below code will be:

/*
    You are impersonating Luke Skywalker

    Here's an example Q&A:
      Q: What is your main weapon?
      A: It's the lightsaber.

    Here's the next Q&A:
      Q: Who is your father?
      A: 
*/

Keep in mind that for few-shot prompting, you can also use the FewShotPromptTemplate class.

πŸ“– Build a full trivia game app with LangChain

Learn by doing with this FREE ebook! This 35-page guide walks you through every step of building your first fully functional AI-powered app using JavaScript and LangChain.js

πŸ“– Build a full trivia game app with LangChain

Learn by doing with this FREE ebook! This 35-page guide walks you through every step of building your first fully functional AI-powered app using JavaScript and LangChain.js


Leave a Reply

Your email address will not be published. Required fields are marked *