Skip to content

Commit 9b983a9

Browse files
authored
Merge pull request quarkiverse#981 from andreadimaio/improve_watsonx_model_provider
Enable /chat and /chat_stream in watsonx.ai
2 parents 0b94f8b + 6b3edf4 commit 9b983a9

File tree

45 files changed

+2953
-956
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2953
-956
lines changed

docs/modules/ROOT/pages/watsonx.adoc

Lines changed: 38 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -62,111 +62,75 @@ quarkus.langchain4j.watsonx.api-key=hG-...
6262

6363
NOTE: To determine the API key, go to https://cloud.ibm.com/iam/apikeys and generate it.
6464

65-
==== Writing prompts
65+
==== Interacting with Models
6666

67-
When creating prompts using watsonx.ai, it's important to follow the guidelines of the model you choose. Depending on the model, some special instructions may be required to ensure the desired output. For best results, always refer to the documentation provided for each model to maximize the effectiveness of your prompts.
67+
The `watsonx.ai` module provides two different modes for interacting with LLM models: `generation` and `chat`. These modes allow you to tailor the interaction based on the complexity of your use case and how much control you want to have over the prompt structure.
6868

69-
To simplify the process of prompt creation, you can use the `prompt-formatter` property to automatically handle the addition of tags to your prompts. This property allows you to avoid manually adding tags by letting the system handle the formatting based on the model's requirements. This functionality is particularly useful for models such as `ibm/granite-13b-chat-v2`, `meta-llama/llama-3-405b-instruct`, and other supported models, ensuring consistent and accurate prompt structures without additional effort.
69+
You can select the interaction mode using the property `quarkus.langchain4j.watsonx.chat-model.mode`.
7070

71-
To enable this functionality, configure the `prompt-formatter` property in your `application.properties` file as follows:
71+
* `generation`: In this mode, you must explicitly structure the prompts using the required model-specific tags. This provides full control over the format of the prompt, but requires in-depth knowledge of the model being used. For best results, always refer to the documentation provided of each model to maximize the effectiveness of your prompts.
72+
* `chat`: This mode abstracts the complexity of tagging by automatically formatting prompts so you can focus on the content (*default value*).
73+
74+
To choose between one of these two modes, add the `chat-model.mode` property to your `application.properties` file:
7275

7376
[source,properties,subs=attributes+]
7477
----
75-
quarkus.langchain4j.watsonx.chat-model.prompt-formatter=true
78+
quarkus.langchain4j.watsonx.chat-model.mode=chat // or 'generate'
7679
----
7780

78-
When this property is set to `true`, the system will automatically format prompts with the appropriate tags. This helps to maintain prompt clarity and improves interaction with the LLM by ensuring that prompts follow the required structure. If set to `false`, you'll need to manage the tags manually.
81+
==== Chat Mode
82+
83+
In `chat` mode, you can interact with models without having to manually manage the tags of a prompt.
84+
85+
You might choose this mode if you are looking for dynamic interactions where the model can build on previous messages and provide more contextually relevant responses. This mode simplifies the interaction by automatically managing the necessary tags, allowing you to focus on the content of your prompts rather than formatting.
7986

80-
For example, if you choose to use `ibm/granite-13b-chat-v2` without using the `prompt-formatter`, you will need to manually add the `<|system|>`, `<|user|>` and `<|assistant|>` instructions:
87+
Chat mode also supports the use of `tools`, allowing the model to perform specific actions or retrieve external data as part of its responses. This extends the capabilities of the model, allowing it to perform complex tasks dynamically and adapt to your needs. More information about tools is available on the xref:./agent-and-tools.adoc[Agent and Tools] page.
8188

8289
[source,properties,subs=attributes+]
8390
----
84-
quarkus.langchain4j.watsonx.api-key=hG-...
85-
quarkus.langchain4j.watsonx.base-url=https://us-south.ml.cloud.ibm.com
86-
quarkus.langchain4j.watsonx.chat-model.model-id=ibm/granite-13b-chat-v2
87-
quarkus.langchain4j.watsonx.chat-model.prompt-formatter=false
91+
quarkus.langchain4j.watsonx.base-url=${BASE_URL}
92+
quarkus.langchain4j.watsonx.api-key=${API_KEY}
93+
quarkus.langchain4j.watsonx.project-id=${PROJECT_ID}
94+
quarkus.langchain4j.watsonx.chat-model.model-id=mistralai/mistral-large
95+
quarkus.langchain4j.watsonx.chat-model.mode=chat
8896
----
8997

9098
[source,java]
9199
----
92100
@RegisterAiService
93-
public interface LLMService {
94-
95-
public record Result(Integer result) {}
96-
97-
@SystemMessage("""
98-
<|system|>
99-
You are a calculator and you must perform the mathematical operation
100-
{response_schema}
101-
""")
102-
@UserMessage("""
103-
<|user|>
104-
{firstNumber} + {secondNumber}
105-
<|assistant|>
106-
""")
107-
public Result calculator(int firstNumber, int secondNumber);
101+
public interface AiService {
102+
@SystemMessage("You are a helpful assistant")
103+
public String chat(@MemoryId String id, @UserMessage message);
108104
}
109105
----
110106

111-
Enabling the `prompt-formatter` will result in:
107+
NOTE: The availability of `chat` and `tools` is currently limited to certain models. Not all models support these features, so be sure to consult the documentation for the specific model you are using to confirm whether these features are available.
108+
109+
==== Generation Mode
110+
111+
In `generation` mode, you have complete control over the structure of your prompts by manually specifying tags for a specific model. This mode could be useful in scenarios where a single-response is desired.
112112

113113
[source,properties,subs=attributes+]
114114
----
115-
quarkus.langchain4j.watsonx.api-key=hG-...
116-
quarkus.langchain4j.watsonx.base-url=https://us-south.ml.cloud.ibm.com
117-
quarkus.langchain4j.watsonx.chat-model.model-id=ibm/granite-13b-chat-v2
118-
quarkus.langchain4j.watsonx.chat-model.prompt-formatter=true
115+
quarkus.langchain4j.watsonx.base-url=${BASE_URL}
116+
quarkus.langchain4j.watsonx.api-key=${API_KEY}
117+
quarkus.langchain4j.watsonx.project-id=${PROJECT_ID}
118+
quarkus.langchain4j.watsonx.chat-model.model-id=mistralai/mistral-large
119+
quarkus.langchain4j.watsonx.chat-model.mode=generation
119120
----
120121

121122
[source,java]
122123
----
123-
@RegisterAiService
124-
public interface LLMService {
125-
126-
public record Result(Integer result) {}
127-
128-
@SystemMessage("""
129-
You are a calculator and you must perform the mathematical operation
130-
{response_schema}
131-
""")
124+
@RegisterAiService(chatMemoryProviderSupplier = RegisterAiService.NoChatMemoryProviderSupplier.class)
125+
public interface AiService {
132126
@UserMessage("""
133-
{firstNumber} + {secondNumber}
134-
""")
135-
public Result calculator(int firstNumber, int secondNumber);
127+
<s>[INST] You are a helpful assistant [/INST]</s>\
128+
[INST] What is the capital of {capital}? [/INST]""")
129+
public String askCapital(String capital);
136130
}
137131
----
138132

139-
The `prompt-formatter` supports the following models:
140-
141-
* `mistralai/mistral-large`
142-
* `mistralai/mixtral-8x7b-instruct-v01`
143-
* `sdaia/allam-1-13b-instruct`
144-
* `meta-llama/llama-3-405b-instruct`
145-
* `meta-llama/llama-3-1-70b-instruct`
146-
* `meta-llama/llama-3-1-8b-instruct`
147-
* `meta-llama/llama-3-70b-instruct`
148-
* `meta-llama/llama-3-8b-instruct`
149-
* `ibm/granite-13b-chat-v2`
150-
* `ibm/granite-13b-instruct-v2`
151-
* `ibm/granite-7b-lab`
152-
* `ibm/granite-20b-code-instruct`
153-
* `ibm/granite-34b-code-instruct`
154-
* `ibm/granite-3b-code-instruct`
155-
* `ibm/granite-8b-code-instruct`
156-
157-
==== Tool Execution with Prompt Formatter
158-
159-
In addition to simplifying prompt creation, the `prompt-formatter` property also enables the execution of tools for specific models. Tools allow for dynamic interactions within the model, enabling the AI to perform specific actions or fetch data as part of its response.
160-
161-
When the `prompt-formatter` is enabled and a supported model is selected, the prompt will be automatically formatted to use the tools. More information about tools is available in the xref:./agent-and-tools.adoc[Agent and Tools] page.
162-
163-
Currently, the following model supports tool execution:
164-
165-
* `mistralai/mistral-large`
166-
* `meta-llama/llama-3-405b-instruct`
167-
* `meta-llama/llama-3-1-70b-instruct`
168-
169-
IMPORTANT: The `@SystemMessage` and `@UserMessage` annotations are joined by default with a new line. If you want to change this behavior, use the property `quarkus.langchain4j.watsonx.chat-model.prompt-joiner=<value>`. By adjusting this property, you can define your preferred way of joining messages and ensure that the prompt structure meets your specific needs. This customization option is available only when the `prompt-formatter` property is set to `false`. When the `prompt-formatter` is enabled (set to `true`), the prompt formatting, including the addition of tags and message joining, is automatically handled. In this case, the `prompt-joiner` property will be ignored, and you will not have the ability to customize how messages are joined.
133+
NOTE: The `@SystemMessage` and `@UserMessage` annotations are joined by default with a new line. If you want to change this behavior, use the property `quarkus.langchain4j.watsonx.chat-model.prompt-joiner=<value>`. By adjusting this property, you can define your preferred way of joining messages and ensure that the prompt structure meets your specific needs.
170134

171135
NOTE: Sometimes it may be useful to use the `quarkus.langchain4j.watsonx.chat-model.stop-sequences` property to prevent the LLM model from returning more results than desired.
172136

integration-tests/multiple-providers/src/main/resources/application.properties

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ quarkus.langchain4j.watsonx.c7.base-url=https://somecluster.somedomain.ai:443/ap
3333
quarkus.langchain4j.watsonx.c7.api-key=test8
3434
quarkus.langchain4j.watsonx.c7.project-id=proj
3535

36+
quarkus.langchain4j.c8.chat-model.provider=watsonx
37+
quarkus.langchain4j.watsonx.c8.base-url=https://somecluster.somedomain.ai:443/api
38+
quarkus.langchain4j.watsonx.c8.api-key=test9
39+
quarkus.langchain4j.watsonx.c8.project-id=proj
40+
quarkus.langchain4j.watsonx.c8.chat-model.mode=generation
41+
3642
quarkus.langchain4j.e1.embedding-model.provider=openai
3743
quarkus.langchain4j.openai.e1.api-key=test5
3844
quarkus.langchain4j.e2.embedding-model.provider=ollama

integration-tests/multiple-providers/src/test/java/org/acme/example/multiple/MultipleChatProvidersTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.quarkiverse.langchain4j.ollama.OllamaChatLanguageModel;
1515
import io.quarkiverse.langchain4j.openshiftai.OpenshiftAiChatModel;
1616
import io.quarkiverse.langchain4j.watsonx.WatsonxChatModel;
17+
import io.quarkiverse.langchain4j.watsonx.WatsonxGenerationModel;
1718
import io.quarkus.arc.ClientProxy;
1819
import io.quarkus.test.junit.QuarkusTest;
1920

@@ -47,6 +48,10 @@ public class MultipleChatProvidersTest {
4748
@ModelName("c7")
4849
ChatLanguageModel seventhNamedModel;
4950

51+
@Inject
52+
@ModelName("c8")
53+
ChatLanguageModel eighthNamedModel;
54+
5055
@Test
5156
void defaultModel() {
5257
assertThat(ClientProxy.unwrap(defaultModel)).isInstanceOf(OpenAiChatModel.class);
@@ -81,4 +86,9 @@ void sixthNamedModel() {
8186
void seventhNamedModel() {
8287
assertThat(ClientProxy.unwrap(seventhNamedModel)).isInstanceOf(WatsonxChatModel.class);
8388
}
89+
90+
@Test
91+
void eighthNamedModel() {
92+
assertThat(ClientProxy.unwrap(eighthNamedModel)).isInstanceOf(WatsonxGenerationModel.class);
93+
}
8494
}

0 commit comments

Comments
 (0)