langchain4j / langchain4j

Java version of LangChain
https://docs.langchain4j.dev
Apache License 2.0
4.91k stars 978 forks source link

Improve Prompt Templates #2118

Open langchain4j opened 1 week ago

langchain4j commented 1 week ago

Consider adding a few improvements to current prompt template features:

Consider using existing (lightweight) templating engine (can be different ones for vanially LC4j and SB integration) for this.

langchain4j commented 1 week ago

cc @glaforge (you were interested in this)

glaforge commented 1 week ago

So the idea would be to bring back templating like mustache or jinja (often used in the Python ecosystem) as a dedicated module maybe? Or you want to extend the current variable placeholder mechanism?

langchain4j commented 1 week ago

I guess we need to consider and evaluate all options. Ofc it would be great to have more features by default, but if it will require importing heawyweight library, then it is a no-go. Having a separate out-of-the-box module that enables better templating sounds good, but I would investigate first if there is lightweight option to include by default.

glaforge commented 1 week ago

I was looking at Jinja, because it's what's used by LangChain, so it could help porting nice prompts from LangChain to LangChain4j, however the jinjava library has tons of dependencies. On the other hand, the jmustache library has zero dependencies at all. But there are other options as well...

My fear is that we turn the existing placeholder value replacement into something a bit too complex, and we invent yet another template engine :-)

langchain4j commented 1 week ago

Let's not reinvent the wheel and search for a lightweight solution that we can include with LC4j by default. If there is no such option, we can always implement a separate module that will optionally enable advanced templating features with one of the popular temlating engines (even if heavyweight)

kpavlov commented 6 days ago

This is an example, how to introduce external template source and rendering mechanism it by extending LC4J. Here is the documentation and test.

TL;DR:

interface Assistant {
    @UserMessage(
        // "Hello, {{userName}}! {{message}}"
        "prompts/ServiceWithTemplatesTest/default-user-prompt.mustache", 
    )
    fun askQuestion(
        @UserName userName: String,
        @V("message") question: String,
    ): String
}

val assistant = AiServices
      .builder(Assistant::class)
      .systemMessageProvider(
          TemplateSystemMessageProvider(
              //  "You are helpful assistant using chatMemoryID={{chatMemoryID}}"
              "prompts/ServiceWithTemplatesTest/default-system-prompt.mustache",
          ),
      ).chatLanguageModel(model)
      .build()

val response = assistant.askQuestion(userName = "My friend", question = "How are you?")

Regarding jmustache, it is important to make sure, that code execution via template is not allowed, to prevent prompt injection attack vector. Simple placeholder replacement is very easy to achieve with no dependencies.