Add prompt(String) method to ChatClient

This commit introduces a new overloaded method prompt(String content)
to the ChatClient API. It provides a convenient way to create prompts
using only a string of user content, simplifying the process for basic
chat interactions.

Fixes gh-1286

Signed-off-by: Thomas Vitale <ThomasVitale@users.noreply.github.com>
This commit is contained in:
Thomas Vitale
2024-08-28 20:55:51 +02:00
committed by Mark Pollack
parent c67442d605
commit acb31e7b75
4 changed files with 68 additions and 1 deletions

View File

@@ -74,6 +74,8 @@ public interface ChatClient {
ChatClientRequestSpec prompt();
ChatClientPromptRequestSpec prompt(String content);
ChatClientPromptRequestSpec prompt(Prompt prompt);
/**

View File

@@ -99,6 +99,11 @@ public class DefaultChatClient implements ChatClient {
return new DefaultChatClientRequestSpec(this.defaultChatClientRequest);
}
@Override
public ChatClientPromptRequestSpec prompt(String content) {
return new DefaultChatClientPromptRequestSpec(this.chatModel, new Prompt(content));
}
@Override
public ChatClientPromptRequestSpec prompt(Prompt prompt) {
return new DefaultChatClientPromptRequestSpec(this.chatModel, prompt);

View File

@@ -435,6 +435,19 @@ public class ChatClientTest {
assertThat(userMessage.getMessageType()).isEqualTo(MessageType.USER);
}
@Test
public void simpleUserPromptAsString() {
when(chatModel.call(promptCaptor.capture()))
.thenReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("response")))));
assertThat(ChatClient.builder(chatModel).build().prompt("User prompt").call().content())
.isEqualTo("response");
Message userMessage = promptCaptor.getValue().getInstructions().get(0);
assertThat(userMessage.getContent()).isEqualTo("User prompt");
assertThat(userMessage.getMessageType()).isEqualTo(MessageType.USER);
}
@Test
public void simpleUserPrompt() {
when(chatModel.call(promptCaptor.capture()))

View File

@@ -64,9 +64,20 @@ ChatClient.Builder builder = ChatClient.builder(myChatModel);
ChatClient chatClient = ChatClient.create(myChatModel);
----
== ChatClient Fluent API
The `ChatClient` fluent API allows you to create a prompt in three distinct ways using an overloaded `prompt` method to initiate the fluent API.
* `prompt()`: This method with no arguments is the most flexible, allowing you to build up user, system, and other parts of the prompt using the fluent API.
* `prompt(Prompt prompt)`: This method accepts a `Prompt` argument, letting you pass in a `Prompt` instance that you have created using the Prompt's non-fluent APIs. The prompt passed to the model is 'sealed', meaning you can't modify it using fluent API methods.
* `prompt(String content)`: This is a convenience method similar to the previous overload. It takes the user's text content and creates a `Prompt` instance internally via `new Prompt(content)`.
== ChatClient Responses
The `ChatClient` API offers several ways to format the response from the AI Model.
The `ChatClient` API offers several ways to format the response from the AI Model using the fluent API.
=== Returning a ChatResponse
@@ -85,6 +96,7 @@ ChatResponse chatResponse = chatClient.prompt()
.chatResponse();
----
=== Returning an Entity
You often want to return an entity class that is mapped from the returned `String`.
@@ -318,6 +330,39 @@ This contextual data can be of different types. Common types include:
* **Conversational history**: The chat model's API is stateless. If you tell the AI model your name, it won't remember it in subsequent interactions. Conversational history must be sent with each request to ensure previous interactions are considered when generating a response.
=== Advisor Configuration in ChatClient
The ChatClient fluent API provides an `AdvisorSpec` interface for configuring advisors. This interface offers methods to add parameters, set multiple parameters at once, and add one or more advisors to the chain.
[source,java]
----
interface AdvisorSpec {
AdvisorSpec param(String k, Object v);
AdvisorSpec params(Map<String, Object> p);
AdvisorSpec advisors(Advisor... advisors);
AdvisorSpec advisors(List<Advisor> advisors);
}
----
IMPORTANT: The order in which advisors are added to the chain is crucial, as it determines the sequence of their execution. Each advisor modifies the prompt or the context in some way, and the changes made by one advisor are passed on to the next in the chain.
[source,java]
----
ChatClient.builder(chatModel)
.build()
.prompt()
.advisors(
new ChatMemoryAdvisor(chatMemory),
new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults())
)
.user(userText)
.call();
----
In this configuration, the `ChatMemoryAdvisor` will be executed first, adding the conversation history to the prompt. Then, the `QuestionAnswerAdvisor` will perform its search based on the user's question and the added conversation history, potentially providing more relevant results.
=== Retrieval Augmented Generation
A vector database stores data that the AI model is unaware of.
@@ -427,6 +472,8 @@ public class CustomerSupportAssistant {
}
----
=== Logging
The `SimpleLoggerAdvisor` is an advisor that logs the `request` and `response` data of the `ChatClient`.