Expected Behavior
The project should be fully configurable using both Spring Boot configuration file formats: properties and yaml.
There should not be the keys that serve as both scalar and a container for more keys/objects at the same time.
Current Behavior
Currently there are some keys that serve as both scalar and a container for more keys/objects at the same time.
E.g., if I have both spring-ai-starter-model-ollama and spring-ai-starter-model-vertex-ai-embedding, then I'm forced to use these properties together to disable one of the auto-configurations.
spring.ai.model.embedding=none # Disable Ollama embeddings
spring.ai.model.embedding.text=vertexai # Enable Vertex AI embeddings
Otherwise the DI container will have 2 beans of EmbeddingModel type that I don't want:
Parameter 0 of constructor in me.venn.ai.EmbeddingController required a single bean, but 2 were found:
- ollamaEmbeddingModel: defined by method 'ollamaEmbeddingModel' in class path resource [org/springframework/ai/model/ollama/autoconfigure/OllamaEmbeddingAutoConfiguration.class]
- textEmbedding: defined by method 'textEmbedding' in class path resource [org/springframework/ai/model/vertexai/autoconfigure/embedding/VertexAiTextEmbeddingAutoConfiguration.class]
But if I use application.yaml instead of application.properties I can't use these properties like this:
spring:
ai:
model:
embedding: none
text: vertexai # invalid!
It is invalid because embedding can't be both a value (none) and a container for further nesting.
The workaround is to flatten some keys like this:
spring:
ai:
model:
embedding: none
embedding.text: vertexai
This works because Spring Boot's Binder flattens the properties before binding them to the @ConfigurationProperties classes.
But it doesn't look like it is intended usage. I never seen similar clashes in any autoconfiguration of any Spring Boot related project.
I think, Spring AI should take it into account and never create configuration properties which have a value, but at the same time are objects themselves with sub-keys.
In this particular case the spring.ai.model.embedding could be renamed to spring.ai.model.embedding.model-name for example. Or spring.ai.model.embedding.text could be renamed to spring.ai.model.embedding-text (probaby will affect less projects, maybe only Vertex AI if only it uses these keys, I'm not sure).
But I seen other examples of such collisions in other parts of the docs (can't remember which exactly, unfortunately).
I suggest going through every property and collect if it clashes with any other property, and then take a decision. Renaming the properties will be backward incompatible in some cases, but it is better to do this sooner than later.