Skip to content

Commit

Permalink
Update PromptTemplates documentation for customization
Browse files Browse the repository at this point in the history
Revised the documentation to include detailed instructions on customizing prompt templates, including examples for implementing and configuring custom PromptTemplateSource and TemplateRenderer. Improved clarity by removing default configuration details and adding a section on how the mechanisms work.
  • Loading branch information
Konstantin Pavlov authored and Konstantin Pavlov committed Nov 17, 2024
1 parent 5f0f058 commit 6930521
Showing 1 changed file with 91 additions and 25 deletions.
116 changes: 91 additions & 25 deletions docs/PromptTemplates.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
# Using Prompt Templates with AiServices
# Customizing Prompt Templates

This guide demonstrates how to configure and use prompt templates with the AiServices module. This setup involves
configuring prompt templates, creating prompt template sources, and rendering templates with specific variables.
Additionally, a test class validates the functionality of these templates.

## Configuration

First, make sure you have the necessary configuration in your `langchain4j-kotlin.properties` file. This is default
configuration:

```properties
prompt.template.source=me.kpavlov.langchain4j.kotlin.prompt.ClasspathPromptTemplateSource
prompt.template.renderer=me.kpavlov.langchain4j.kotlin.prompt.SimpleTemplateRenderer
```

This configuration specifies the source and renderer for the prompt templates.
This guide demonstrates how to configure and use prompt templates with
the [LangChain4J's AiServices](https://docs.langchain4j.dev/tutorials/ai-services). This setup involves
configuring prompt templates, defining and extending prompt template sources and template rendering.

## Creating and Using Prompt Template

Include the necessary classes. Your prompt templates will be sourced from the classpath and rendered using a simple
template renderer.
Let's start with built-in mechanizm of loading prompt template from classpath. Your prompt templates should be located
in the classpath, e.g.

File: `prompts/default-system-prompt.mustache`

Expand Down Expand Up @@ -74,13 +62,14 @@ System and user prompts will be:
- **System prompt:** "You are helpful assistant using chatMemoryID=default"
- **User Prompt:** "Hello, My friend! How are you?"

In this example, `TemplateSystemMessageProvider` handles the system prompt template and `AiServices` uses the templates
to generate responses.
## How does it work

`PromptTemplateFactory` is registered automatically via Java ServiceLoaders mechanism and is used to provide
`PromptTemplate`. This class is responsible for obtaining prompt templates from a `PromptTemplateSource` and rendering
them using a `TemplateRenderer`. If the specified template cannot be found, it will fallback to using the input template
content.
In the default implementation, `TemplateSystemMessageProvider` handles the system prompt template and `AiServices` uses
the templates to generate responses.

`PromptTemplateFactory` provides `PromptTemplateFactory.Template` for `AiServices`. It is registered automatically via
Java ServiceLoaders mechanism. This class is responsible for obtaining prompt templates from a `PromptTemplateSource`.
If the specified template cannot be found, it will fallback to using default LC4J's the input template content.

`ClasspathPromptTemplateSource` is implementing `PromptTemplateSource` interface and provides a mechanism to load prompt
templates from the classpath using the template name as the resource identifier. It attempts to locate the template file
Expand All @@ -90,12 +79,89 @@ overridden.
Implementers of the `TemplateRenderer` interface will typically replace placeholders in the template with corresponding
values from the variables map.

`SimpleTemplateRenderer` finds and replaces placeholders in the template in the format `{{key}}`, where `key`
`SimpleTemplateRenderer` finds and replaces placeholders in the template in the Mustache-like format `{{key}}`, where
`key`
corresponds to an entry in the variables map. If any placeholders in the template are not defined in the variables map,
an `IllegalArgumentException` will be thrown.

`RenderablePromptTemplate` implements both `PromptTemplate` and LangChain4j's `PromptTemplateFactory.Template`
interfaces. It uses a `TemplateRenderer` to render the template content using provided variables.

## Customization

You may customize templates via configuration file `langchain4j-kotlin.properties`, located in the classpath.

| Key | Description | Default Value |
|----------------------------|-------------------|----------------------------------------------------------------------|
| `prompt.template.source` | Template source | `me.kpavlov.langchain4j.kotlin.prompt.ClasspathPromptTemplateSource` |
| `prompt.template.renderer` | Template renderer | `me.kpavlov.langchain4j.kotlin.prompt.SimpleTemplateRenderer` |

### Extending PromptTemplateSource

To create a custom template source, implement the PromptTemplateSource interface:

```kotlin
interface PromptTemplateSource {
fun getTemplate(name: TemplateName): PromptTemplate?
}
```

Example implementation for Redis and Jedis:

```kotlin
package com.example

// Redis/Jedis-backed template source

class RedisPromptTemplateSource(private val jedis: Jedis) : PromptTemplateSource {
override fun getTemplate(name: TemplateName): PromptTemplate? {
return jedis.get(name)?.let {
SimplePromptTemplate(it)
}
}
}
```

Register your implementation in the `langchain4j-kotlin.properties` configuration file:

```properties
prompt.template.source=com.example.RedisPromptTemplateSource
```

### Extending TemplateRenderer

To create a custom template renderer, implement the TemplateRenderer interface:

```kotlin
interface TemplateRenderer {
fun render(
template: TemplateContent,
variables: Map<String, Any?>
): String
}
```

Example implementation:

```kotlin
package com.example

// Freemarker-based renderer
class MyTemplateRenderer : TemplateRenderer {

override fun render(template: TemplateContent, variables: Map<String, Any?>): String {
TODO("Add implementation here")
}
}
```

Register your implementation in the `langchain4j-kotlin.properties` configuration file:

```properties
prompt.template.renderer=com.example.MyTemplateRenderer
```

## Examples

You may find the unit test with the
example [here](../langchain4j-kotlin/src/test/kotlin/me/kpavlov/langchain4j/kotlin/service/ServiceWithPromptTemplatesTest.kt)

0 comments on commit 6930521

Please sign in to comment.