OpenAI - GPT:
- xml pom
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-openai</artifactId>
</dependency>
<dependency>
<groupId>com.knuddels</groupId>
<artifactId>jtokkit</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies>
- properties
spring.application.name=ecomart
spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.openai.chat.options.model=gpt-4o-mini
spring.ai.retry.max-attempts=20
spring.ai.retry.backoff.initial-interval=10
spring.ai.retry.backoff.max-interval=300
logging.level.org.springframework.ai.chat.client.advisor=DEBUG
- CategorizadorDeProductosCOntroller
@RestController
@RequestMapping("/categorizador")
public class CategorizadorDeProductosController {
private final ChatClient chatClient;
public CategorizadorDeProductosController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder
.defaultOptions(ChatOptions.builder()
.model("gpt-4o-mini")
.build())
.build();
}
@GetMapping
public String categorizarProductos(String producto){
var system = """
Actúa como un categorizador de productos y debes responder solo el nombre de la categoría del producto informado
Escoge una categoría de la siguiente lista:
1. Higiene Personal
2. Electrónicos
3. Deportes
4. Otros
Ejemplo de uso:
Producto: Pelota de fútbol
Respuesta: Deportes
""";
var tokens = contadorDeTokens(system, producto);
System.out.println(tokens);
// implementación de la lógica para la implementación del modelo
return this.chatClient.prompt()
.system(system)
.user(producto)
.options(ChatOptions.builder()
.temperature(0.82).build())
.advisors(new SimpleLoggerAdvisor())
.call()
.content();
}
private int contadorDeTokens(String system, String user){
var registry = Encodings.newDefaultEncodingRegistry();
var enc = registry.getEncodingForModel(ModelType.GPT_4O_MINI);
return enc.countTokens(system + user);
}
}
Google - Gemini
- XML POM
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-google-genai</artifactId>
</dependency>
</dependencies>
- properties
spring.application.name=ecosmart
spring.ai.google.genai.api-key=${GOOGLE_API_KEY}
spring.ai.google.genai.chat.options.model=gemini-3-flash-preview
spring.ai.google.genai.chat.options.temperature=0.82
spring.ai.retry.max-attempts=20
spring.ai.retry.backoff.initial-interval=10
spring.ai.retry.backoff.max-interval=300
logging.level.org.springframework.ai.chat.client.advisor=DEBUG
- CategorizadorDeProductosController
@RestController
@RequestMapping("/categorizador")
public class CategorizadorDeProductosController {
private final ChatClient chatClient;
public CategorizadorDeProductosController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder
.defaultOptions(ChatOptions.builder()
.model("gemini-3-flash-preview")
.build())
.build();
}
@GetMapping
public String categorizarProductos(String producto){
var system = """
Actúa como un categorizador de productos y debes responder solo el nombre de la categoría del producto informado
Escoge una categoría de la siguiente lista:
1. Higiene Personal
2. Electrónicos
3. Deportes
4. Otros
Ejemplo de uso:
Producto: Pelota de fútbol
Respuesta: Deportes
""";
// 1. Calculamos tokens aproximados antes de la consulta
int tokensAproximados = contadorDeTokens(system + producto);
System.out.println("Tokens calculados antes de enviar: " + tokensAproximados);
// 2. Lógica de decisión de modelo basada en el tamaño
// Ejemplo: Si es muy largo usamos Pro, si es corto usamos Flash
String modeloElegido = (tokensAproximados > 1000) ? "gemini-3-flash-preview" : "gemini-2.5-flash";
System.out.println("Modelo seleccionado: " + modeloElegido);
return this.chatClient.prompt()
.system(system)
.user(producto)
.options(ChatOptions.builder()
.model(modeloElegido)
.temperature(0.82).build())
.advisors(new SimpleLoggerAdvisor())
.call()
.content();
}
/**
* Alternativa a JTokkit para Gemini.
* En Gemini, 1 token ≈ 4 caracteres en promedio.
*/
private int contadorDeTokens(String texto) {
if (texto == null) return 0;
// Estimación matemática sugerida por Google para validación previa rápida
return (int) Math.ceil(texto.length() / 4.0);
}
}