Support keep-alive and format options in Ollama chat requests
- add support for the advanced parameter 'template'. - add docs for the advanced parameters.
This commit is contained in:
committed by
Christian Tzolov
parent
ae6a019ad1
commit
aca8ffd400
@@ -161,11 +161,22 @@ public class OllamaChatClient implements ChatClient, StreamingChatClient {
|
||||
}
|
||||
|
||||
String model = mergedOptions.getModel();
|
||||
return OllamaApi.ChatRequest.builder(model)
|
||||
OllamaApi.ChatRequest.Builder requestBuilder = OllamaApi.ChatRequest.builder(model)
|
||||
.withStream(stream)
|
||||
.withMessages(ollamaMessages)
|
||||
.withOptions(mergedOptions)
|
||||
.build();
|
||||
.withOptions(mergedOptions);
|
||||
|
||||
if (mergedOptions.getFormat() != null) {
|
||||
requestBuilder.withFormat(mergedOptions.getFormat());
|
||||
}
|
||||
|
||||
if (mergedOptions.getKeepAlive() != null) {
|
||||
requestBuilder.withKeepAlive(mergedOptions.getKeepAlive());
|
||||
}
|
||||
|
||||
if (mergedOptions.getTemp)
|
||||
|
||||
return requestBuilder.build();
|
||||
}
|
||||
|
||||
private String fromMediaData(Object mediaData) {
|
||||
|
||||
@@ -399,8 +399,9 @@ public class OllamaApi {
|
||||
* @param model The model to use for completion.
|
||||
* @param messages The list of messages to chat with.
|
||||
* @param stream Whether to stream the response.
|
||||
* @param format The format to return the response in. Currently the only accepted
|
||||
* @param format The format to return the response in. Currently, the only accepted
|
||||
* value is "json".
|
||||
* @param keepAlive The duration to keep the model loaded in ollama while idle. https://pkg.go.dev/time#ParseDuration
|
||||
* @param options Additional model parameters. You can use the {@link OllamaOptions} builder
|
||||
* to create the options then {@link OllamaOptions#toMap()} to convert the options into a
|
||||
* map.
|
||||
@@ -411,6 +412,7 @@ public class OllamaApi {
|
||||
@JsonProperty("messages") List<Message> messages,
|
||||
@JsonProperty("stream") Boolean stream,
|
||||
@JsonProperty("format") String format,
|
||||
@JsonProperty("keep_alive") String keepAlive,
|
||||
@JsonProperty("options") Map<String, Object> options) {
|
||||
|
||||
public static Builder builder(String model) {
|
||||
@@ -423,6 +425,7 @@ public class OllamaApi {
|
||||
private List<Message> messages = List.of();
|
||||
private boolean stream = false;
|
||||
private String format;
|
||||
private String keepAlive;
|
||||
private Map<String, Object> options = Map.of();
|
||||
|
||||
public Builder(String model) {
|
||||
@@ -445,6 +448,11 @@ public class OllamaApi {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withKeepAlive(String keepAlive) {
|
||||
this.keepAlive = keepAlive;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withOptions(Map<String, Object> options) {
|
||||
Objects.requireNonNullElse(options, "The options can not be null.");
|
||||
|
||||
@@ -459,7 +467,7 @@ public class OllamaApi {
|
||||
}
|
||||
|
||||
public ChatRequest build() {
|
||||
return new ChatRequest(model, messages, stream, format, options);
|
||||
return new ChatRequest(model, messages, stream, format, keepAlive, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
|
||||
public static final String DEFAULT_MODEL = OllamaModel.MISTRAL.id();
|
||||
|
||||
private static final List<String> NON_SUPPORTED_FIELDS = List.of("model", "format", "keep_alive", "template");
|
||||
|
||||
// @formatter:off
|
||||
/**
|
||||
* useNUMA Whether to use NUMA.
|
||||
@@ -232,12 +234,34 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
@JsonProperty("stop") private List<String> stop;
|
||||
|
||||
|
||||
// Following fields are not part of the Ollama Options API but part of the Request.
|
||||
/**
|
||||
* NOTE: Synthetic field not part of the official Ollama API.
|
||||
* Used to allow overriding the model name with prompt options.
|
||||
* Part of Chat completion <a href="https://github.com/ollama/ollama/blob/main/docs/api.md#parameters-1">parameters</a>.
|
||||
*/
|
||||
@JsonProperty("model") private String model;
|
||||
|
||||
/**
|
||||
* Sets the desired format of output from the LLM. The only valid values are null or "json".
|
||||
* Part of Chat completion <a href="https://github.com/ollama/ollama/blob/main/docs/api.md#parameters-1">advanced parameters</a>.
|
||||
*/
|
||||
@JsonProperty("format") private String format;
|
||||
|
||||
/**
|
||||
* Sets the length of time for Ollama to keep the model loaded. Valid values for this
|
||||
* setting are parsed by <a href="https://pkg.go.dev/time#ParseDuration">ParseDuration in Go</a>.
|
||||
* Part of Chat completion <a href="https://github.com/ollama/ollama/blob/main/docs/api.md#parameters-1">advanced parameters</a>.
|
||||
*/
|
||||
@JsonProperty("keep_alive") private String keepAlive;
|
||||
|
||||
/**
|
||||
* The prompt template to use (overrides what is defined in the Modelfile).
|
||||
* Part of Chat completion <a href="https://github.com/ollama/ollama/blob/main/docs/api.md#parameters-1">advanced parameters</a>.
|
||||
*/
|
||||
@JsonProperty("template") private String template;
|
||||
|
||||
|
||||
/**
|
||||
* @param model The ollama model names to use. See the {@link OllamaModel} for the common models.
|
||||
*/
|
||||
@@ -254,6 +278,21 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public OllamaOptions withFormat(String format) {
|
||||
this.format = format;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OllamaOptions withKeepAlive(String keepAlive) {
|
||||
this.keepAlive = keepAlive;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OllamaOptions withTemplate(String template) {
|
||||
this.template = template;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OllamaOptions withUseNUMA(Boolean useNUMA) {
|
||||
this.useNUMA = useNUMA;
|
||||
return this;
|
||||
@@ -414,8 +453,32 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getFormat() {
|
||||
return this.format;
|
||||
}
|
||||
|
||||
public void setFormat(String format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public String getKeepAlive() {
|
||||
return this.keepAlive;
|
||||
}
|
||||
|
||||
public void setKeepAlive(String keepAlive) {
|
||||
this.keepAlive = keepAlive;
|
||||
}
|
||||
|
||||
public String getTemplate() {
|
||||
return this.template;
|
||||
}
|
||||
|
||||
public void setTemplate(String template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public Boolean getUseNUMA() {
|
||||
return useNUMA;
|
||||
return this.useNUMA;
|
||||
}
|
||||
|
||||
public void setUseNUMA(Boolean useNUMA) {
|
||||
@@ -423,7 +486,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Integer getNumCtx() {
|
||||
return numCtx;
|
||||
return this.numCtx;
|
||||
}
|
||||
|
||||
public void setNumCtx(Integer numCtx) {
|
||||
@@ -431,7 +494,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Integer getNumBatch() {
|
||||
return numBatch;
|
||||
return this.numBatch;
|
||||
}
|
||||
|
||||
public void setNumBatch(Integer numBatch) {
|
||||
@@ -439,7 +502,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Integer getNumGQA() {
|
||||
return numGQA;
|
||||
return this.numGQA;
|
||||
}
|
||||
|
||||
public void setNumGQA(Integer numGQA) {
|
||||
@@ -447,7 +510,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Integer getNumGPU() {
|
||||
return numGPU;
|
||||
return this.numGPU;
|
||||
}
|
||||
|
||||
public void setNumGPU(Integer numGPU) {
|
||||
@@ -455,7 +518,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Integer getMainGPU() {
|
||||
return mainGPU;
|
||||
return this.mainGPU;
|
||||
}
|
||||
|
||||
public void setMainGPU(Integer mainGPU) {
|
||||
@@ -463,7 +526,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Boolean getLowVRAM() {
|
||||
return lowVRAM;
|
||||
return this.lowVRAM;
|
||||
}
|
||||
|
||||
public void setLowVRAM(Boolean lowVRAM) {
|
||||
@@ -471,15 +534,15 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Boolean getF16KV() {
|
||||
return f16KV;
|
||||
return this.f16KV;
|
||||
}
|
||||
|
||||
public void setF16KV(Boolean f16kv) {
|
||||
f16KV = f16kv;
|
||||
this.f16KV = f16kv;
|
||||
}
|
||||
|
||||
public Boolean getLogitsAll() {
|
||||
return logitsAll;
|
||||
return this.logitsAll;
|
||||
}
|
||||
|
||||
public void setLogitsAll(Boolean logitsAll) {
|
||||
@@ -487,7 +550,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Boolean getVocabOnly() {
|
||||
return vocabOnly;
|
||||
return this.vocabOnly;
|
||||
}
|
||||
|
||||
public void setVocabOnly(Boolean vocabOnly) {
|
||||
@@ -495,7 +558,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Boolean getUseMMap() {
|
||||
return useMMap;
|
||||
return this.useMMap;
|
||||
}
|
||||
|
||||
public void setUseMMap(Boolean useMMap) {
|
||||
@@ -503,7 +566,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Boolean getUseMLock() {
|
||||
return useMLock;
|
||||
return this.useMLock;
|
||||
}
|
||||
|
||||
public void setUseMLock(Boolean useMLock) {
|
||||
@@ -511,7 +574,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Float getRopeFrequencyBase() {
|
||||
return ropeFrequencyBase;
|
||||
return this.ropeFrequencyBase;
|
||||
}
|
||||
|
||||
public void setRopeFrequencyBase(Float ropeFrequencyBase) {
|
||||
@@ -519,7 +582,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Float getRopeFrequencyScale() {
|
||||
return ropeFrequencyScale;
|
||||
return this.ropeFrequencyScale;
|
||||
}
|
||||
|
||||
public void setRopeFrequencyScale(Float ropeFrequencyScale) {
|
||||
@@ -527,7 +590,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Integer getNumThread() {
|
||||
return numThread;
|
||||
return this.numThread;
|
||||
}
|
||||
|
||||
public void setNumThread(Integer numThread) {
|
||||
@@ -535,7 +598,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Integer getNumKeep() {
|
||||
return numKeep;
|
||||
return this.numKeep;
|
||||
}
|
||||
|
||||
public void setNumKeep(Integer numKeep) {
|
||||
@@ -543,7 +606,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Integer getSeed() {
|
||||
return seed;
|
||||
return this.seed;
|
||||
}
|
||||
|
||||
public void setSeed(Integer seed) {
|
||||
@@ -551,7 +614,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Integer getNumPredict() {
|
||||
return numPredict;
|
||||
return this.numPredict;
|
||||
}
|
||||
|
||||
public void setNumPredict(Integer numPredict) {
|
||||
@@ -559,7 +622,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Integer getTopK() {
|
||||
return topK;
|
||||
return this.topK;
|
||||
}
|
||||
|
||||
public void setTopK(Integer topK) {
|
||||
@@ -567,7 +630,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Float getTopP() {
|
||||
return topP;
|
||||
return this.topP;
|
||||
}
|
||||
|
||||
public void setTopP(Float topP) {
|
||||
@@ -575,7 +638,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Float getTfsZ() {
|
||||
return tfsZ;
|
||||
return this.tfsZ;
|
||||
}
|
||||
|
||||
public void setTfsZ(Float tfsZ) {
|
||||
@@ -583,7 +646,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Float getTypicalP() {
|
||||
return typicalP;
|
||||
return this.typicalP;
|
||||
}
|
||||
|
||||
public void setTypicalP(Float typicalP) {
|
||||
@@ -591,7 +654,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Integer getRepeatLastN() {
|
||||
return repeatLastN;
|
||||
return this.repeatLastN;
|
||||
}
|
||||
|
||||
public void setRepeatLastN(Integer repeatLastN) {
|
||||
@@ -599,7 +662,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Float getTemperature() {
|
||||
return temperature;
|
||||
return this.temperature;
|
||||
}
|
||||
|
||||
public void setTemperature(Float temperature) {
|
||||
@@ -607,7 +670,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Float getRepeatPenalty() {
|
||||
return repeatPenalty;
|
||||
return this.repeatPenalty;
|
||||
}
|
||||
|
||||
public void setRepeatPenalty(Float repeatPenalty) {
|
||||
@@ -615,7 +678,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Float getPresencePenalty() {
|
||||
return presencePenalty;
|
||||
return this.presencePenalty;
|
||||
}
|
||||
|
||||
public void setPresencePenalty(Float presencePenalty) {
|
||||
@@ -623,7 +686,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Float getFrequencyPenalty() {
|
||||
return frequencyPenalty;
|
||||
return this.frequencyPenalty;
|
||||
}
|
||||
|
||||
public void setFrequencyPenalty(Float frequencyPenalty) {
|
||||
@@ -631,7 +694,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Integer getMirostat() {
|
||||
return mirostat;
|
||||
return this.mirostat;
|
||||
}
|
||||
|
||||
public void setMirostat(Integer mirostat) {
|
||||
@@ -639,7 +702,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Float getMirostatTau() {
|
||||
return mirostatTau;
|
||||
return this.mirostatTau;
|
||||
}
|
||||
|
||||
public void setMirostatTau(Float mirostatTau) {
|
||||
@@ -647,7 +710,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Float getMirostatEta() {
|
||||
return mirostatEta;
|
||||
return this.mirostatEta;
|
||||
}
|
||||
|
||||
public void setMirostatEta(Float mirostatEta) {
|
||||
@@ -655,7 +718,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public Boolean getPenalizeNewline() {
|
||||
return penalizeNewline;
|
||||
return this.penalizeNewline;
|
||||
}
|
||||
|
||||
public void setPenalizeNewline(Boolean penalizeNewline) {
|
||||
@@ -663,7 +726,7 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
public List<String> getStop() {
|
||||
return stop;
|
||||
return this.stop;
|
||||
}
|
||||
|
||||
public void setStop(List<String> stop) {
|
||||
@@ -694,13 +757,13 @@ public class OllamaOptions implements ChatOptions, EmbeddingOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out the non supported fields from the options.
|
||||
* Filter out the non-supported fields from the options.
|
||||
* @param options The options to filter.
|
||||
* @return The filtered options.
|
||||
*/
|
||||
public static Map<String, Object> filterNonSupportedFields(Map<String, Object> options) {
|
||||
return options.entrySet().stream()
|
||||
.filter(e -> !e.getKey().equals("model"))
|
||||
.filter(e -> !NON_SUPPORTED_FIELDS.contains(e.getKey()))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
||||
}
|
||||
|
||||
|
||||
@@ -52,9 +52,10 @@ The prefix `spring.ai.ollama` is the property prefix to configure the connection
|
||||
| spring.ai.ollama.base-url | Base URL where Ollama API server is running. | `http://localhost:11434`
|
||||
|====
|
||||
|
||||
The prefix `spring.ai.ollama.chat.options` is the property prefix that configures the chat client implementation for Ollama.
|
||||
The prefix `spring.ai.ollama.chat.options` is the property prefix that configures the Ollama chat client .
|
||||
It includes the Ollama request (advanced) parameters such as the `model`, `keep-alive`, `format` and `template` as well as the Ollama model `options` properties.
|
||||
|
||||
NOTE: The `options` properties are based on the link:https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md#valid-parameters-and-values[Ollama Valid Parameters and Values] and link:https://github.com/jmorganca/ollama/blob/main/api/types.go[Ollama Types]. The default values are based on: link:https://github.com/ollama/ollama/blob/b538dc3858014f94b099730a592751a5454cab0a/api/types.go#L364[Ollama type defaults].
|
||||
Here are the advanced request parameter for the Ollama chat client:
|
||||
|
||||
[cols="3,6,1"]
|
||||
|====
|
||||
@@ -62,6 +63,15 @@ NOTE: The `options` properties are based on the link:https://github.com/jmorganc
|
||||
|
||||
| spring.ai.ollama.chat.enabled | Enable Ollama chat client. | true
|
||||
| spring.ai.ollama.chat.options.model | The name of the https://github.com/ollama/ollama?tab=readme-ov-file#model-library[supported models] to use. | mistral
|
||||
| spring.ai.ollama.chat.options.format | The format to return a response in. Currently the only accepted value is `json` | -
|
||||
| spring.ai.ollama.chat.options.keep_alive | controls how long the model will stay loaded into memory following the request | 5m
|
||||
|====
|
||||
|
||||
The `options` properties are based on the link:https://github.com/jmorganca/ollama/blob/main/docs/modelfile.md#valid-parameters-and-values[Ollama Valid Parameters and Values] and link:https://github.com/jmorganca/ollama/blob/main/api/types.go[Ollama Types]. The default values are based on: link:https://github.com/ollama/ollama/blob/b538dc3858014f94b099730a592751a5454cab0a/api/types.go#L364[Ollama type defaults].
|
||||
|
||||
[cols="3,6,1"]
|
||||
|====
|
||||
| Property | Description | Default
|
||||
| spring.ai.ollama.chat.options.numa | Whether to use NUMA. | false
|
||||
| spring.ai.ollama.chat.options.num-ctx | Sets the size of the context window used to generate the next token. | 2048
|
||||
| spring.ai.ollama.chat.options.num-batch | ??? | 512
|
||||
@@ -79,7 +89,6 @@ NOTE: The `options` properties are based on the link:https://github.com/jmorganc
|
||||
| spring.ai.ollama.chat.options.num-thread | Sets the number of threads to use during computation. By default, Ollama will detect this for optimal performance. It is recommended to set this value to the number of physical CPU cores your system has (as opposed to the logical number of cores). 0 = let the runtime decide | 0
|
||||
| spring.ai.ollama.chat.options.num-keep | ??? | 0
|
||||
| spring.ai.ollama.chat.options.seed | Sets the random number seed to use for generation. Setting this to a specific number will make the model generate the same text for the same prompt. | -1
|
||||
|
||||
| spring.ai.ollama.chat.options.num-predict | Maximum number of tokens to predict when generating text. (-1 = infinite generation, -2 = fill context) | -1
|
||||
| spring.ai.ollama.chat.options.top-k | Reduces the probability of generating nonsense. A higher value (e.g., 100) will give more diverse answers, while a lower value (e.g., 10) will be more conservative. | 40
|
||||
| spring.ai.ollama.chat.options.top-p | Works together with top-k. A higher value (e.g., 0.95) will lead to more diverse text, while a lower value (e.g., 0.5) will generate more focused and conservative text. | 0.9
|
||||
|
||||
Reference in New Issue
Block a user