Comment From: tzolov
@cponfick i've checked current implementation it seems correct to me. Currently the run-time options (e.g. those in the prompt request) are used to override the start time (e.g. default) options. The Chat Options section in https://docs.spring.io/spring-ai/reference/api/chatmodel.html provides some information about the expected life cycle.
Comment From: cponfick
@tzolov Yes, that is correct, but you can also set the options in the chat model constructor (see the test case):
final MistralAiChatOptions.Builder optionsBuilder = MistralAiChatOptions.builder()
.withModel("model-name")
.withTemperature(0);
new MistralAiChatModel(new MistralAiApi(mistralAiApiKey), optionsBuilder.build());
In that case the default value of temperature is used and not 0. I would expect following priority when overwriting:
- Prompt Options overwrite Chat Model Options
- Chat Model Options overwrite Default Options
This is also how the OpenAiChatModel
handles it. Currently, the default value is used even if I set the temperature
in the Model options. I think this is a bug and should be fixed.
The documentation seems to not mention the ChatModel-Options
. Maybe the documentation needs extension?
Comment From: tzolov
@cponfick the
but you can also set the options in the chat model constructor are the the default options.
There are only 2 set of options. Startup (or default) options you pass via the constructor and Runtime options you can pass via the Prompt.
The Runtime options should override the Startup/Default options.
The Chat Model Options
you are referring above are in fact the Default Options
.
If you use auto-configuration, later will converts the application properties into default options passed via the OpenAiChatModel constructor.
What is particular application use case that the current merging model can not cover?
Comment From: cponfick
What is particular application use case that the current merging model can not cover?
In the current implementation, the test I provided fails. The same test with an OpenAPIChatModel
passes!
@Test
void buildCorrectRequestFromChatModelWithOptions() {
var options = MistralAiChatOptions.builder()
.withModel(MistralAiApi.ChatModel.SMALL.getValue())
.withTemperature(0.0f)
.withTopP(0.0f)
.withMaxTokens(1)
.build();
var chatModelWithOptions = new MistralAiChatModel(new MistralAiApi("test"), options);
var request = chatModelWithOptions.createRequest(new Prompt("test content"), false);
assertThat(request.messages()).hasSize(1);
assertThat(request.topP()).isEqualTo(options.getTopP());
assertThat(request.temperature()).isEqualTo(options.getTemperature());
}
Taking a look at MistralAiChatModel.java
and how merge(Object source, Object target, Class<T> clazz)
is used.
Currently:
request = ModelOptionsUtils.merge(request, this.defaultOptions, MistralAiApi.ChatCompletionRequest.class);
Why is the request
the source and defaultOptions
the target? This seems wrong to me. The request
should not be the source.
The merge flow should be as follows:
- The request is created.
- If there are
defaultOptions
, they are merged into request. - If there are
prompt options
, they are merged into the request and possible overwrite the prev. mergeddefaultOptions
.
Hence, I proposed following change:
request = ModelOptionsUtils.merge(this.defaultOptions, request, MistralAiApi.ChatCompletionRequest.class);