Tutorial de Foundry Local con Spring Boot
April 15, 2026 · View on GitHub
Tabla de Contenidos
- Prerequisitos
- Resumen del Proyecto
- Entendiendo el Código
- Cómo Funciona Todo Junto
- Configurando Foundry Local
- Ejecutando la Aplicación
- Salida Esperada
- Próximos Pasos
- Solución de Problemas
Prerequisitos
Antes de comenzar este tutorial, asegúrate de tener:
- Java 21 o superior instalado en tu sistema
- Maven 3.6+ para compilar el proyecto
- Foundry Local instalado y en ejecución
Instalar Foundry Local:
Nota: La CLI de Foundry Local está disponible solo en Windows y macOS. Linux está soportado a través de los Foundry Local SDKs (Python, JavaScript, C#, Rust).
# Windows
winget install Microsoft.FoundryLocal
# macOS
brew tap microsoft/foundrylocal
brew install foundrylocal
Verifica la instalación:
foundry --version
Resumen del Proyecto
Este proyecto consta de cuatro componentes principales:
- Application.java - Punto de entrada principal de la aplicación Spring Boot
- FoundryLocalService.java - Capa de servicio que maneja la comunicación con la IA
- application.properties - Configuración para la conexión a Foundry Local
- pom.xml - Dependencias de Maven y configuración del proyecto
Entendiendo el Código
1. Configuración de la Aplicación (application.properties)
Archivo: src/main/resources/application.properties
foundry.local.base-url=http://localhost:5273/v1
# foundry.local.model is auto-detected from Foundry Local. Set it here to override:
# foundry.local.model=Phi-4-mini-instruct-cuda-gpu:5
Qué hace esto:
- base-url: Especifica dónde está ejecutándose Foundry Local, incluyendo la ruta
/v1para compatibilidad con la API OpenAI. El puerto por defecto es5273. Si el puerto es diferente, verifícalo confoundry service status. - model (opcional): Nombra el modelo de IA que se utilizará para generación de texto. Por defecto, la aplicación detecta automáticamente el modelo consultando el endpoint
/v1/modelsde Foundry Local al inicio, así que no es necesario configurarlo. Aún puedes configurarlo explícitamente para sobrescribir la detección automática si lo deseas.
Concepto clave: Spring Boot carga automáticamente estas propiedades y las pone a disposición de tu aplicación mediante la anotación @Value.
2. Clase Principal de la Aplicación (Application.java)
Archivo: src/main/java/com/example/Application.java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
app.setWebApplicationType(WebApplicationType.NONE); // No se necesita servidor web
app.run(args);
}
Qué hace esto:
@SpringBootApplicationhabilita la autoconfiguración de Spring BootWebApplicationType.NONEindica a Spring que esta es una aplicación de línea de comandos, no un servidor web- El método main inicia la aplicación Spring
El Demo Runner:
@Bean
public CommandLineRunner foundryLocalRunner(FoundryLocalService foundryLocalService) {
return args -> {
System.out.println("=== Foundry Local Demo ===");
System.out.println("Calling Foundry Local service...");
String testMessage = "Hello! Can you tell me what you are and what model you're running?";
System.out.println("Sending message: " + testMessage);
String response = foundryLocalService.chat(testMessage);
System.out.println("Response from Foundry Local:");
System.out.println(response);
System.out.println("=========================");
};
}
Qué hace esto:
@Beancrea un componente que Spring manejaCommandLineRunnerejecuta código después de que Spring Boot iniciafoundryLocalServicese inyecta automáticamente por Spring (inyección de dependencias)- Envía un mensaje de prueba a la IA y muestra la respuesta
3. Capa de Servicio AI (FoundryLocalService.java)
Archivo: src/main/java/com/example/FoundryLocalService.java
Inyección de Configuración:
@Service
public class FoundryLocalService {
@Value("${foundry.local.base-url:http://localhost:5273/v1}")
private String baseUrl;
@Value("${foundry.local.model:}")
private String model; // Detectado automáticamente si está vacío
Qué hace esto:
@Serviceindica a Spring que esta clase proporciona lógica de negocio@Valueinyecta valores de configuración desde application.properties- El modelo por defecto es vacío, lo que activa la detección automática desde Foundry Local al inicio. Esto permite que la app funcione con cualquier modelo cargado en Foundry Local sin configuración manual.
Inicialización del Cliente:
@PostConstruct
public void init() {
// Detectar automáticamente el modelo desde Foundry Local si no está configurado explícitamente
if (model == null || model.isBlank()) {
model = detectModel();
}
this.openAIClient = OpenAIOkHttpClient.builder()
.baseUrl(baseUrl) // La URL base ya incluye /v1 de la configuración
.apiKey("not-needed") // El servidor local no necesita una clave API real
.build();
}
Qué hace esto:
@PostConstructejecuta este método tras crear el servicio Spring- Si no hay modelo configurado, consulta el endpoint
/v1/modelsde Foundry Local y toma el primer modelo cargado - Crea un cliente OpenAI que apunta a tu instancia local de Foundry Local
- La URL base de
application.propertiesya incluye/v1para compatibilidad con la API OpenAI - La clave API es "not-needed" porque el desarrollo local no requiere autenticación
Método de Chat:
public String chat(String message) {
try {
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.model(model) // Qué modelo de IA utilizar
.addUserMessage(message) // Tu pregunta/sugerencia
.maxCompletionTokens(150) // Limitar la longitud de la respuesta
.temperature(0.7) // Controlar la creatividad (0.0-1.0)
.build();
ChatCompletion chatCompletion = openAIClient.chat().completions().create(params);
// Extraer la respuesta de la IA del resultado de la API
if (chatCompletion.choices() != null && !chatCompletion.choices().isEmpty()) {
return chatCompletion.choices().get(0).message().content().orElse("No response found");
}
return "No response content found";
} catch (Exception e) {
throw new RuntimeException("Error calling chat completion: " + e.getMessage(), e);
}
}
Qué hace esto:
- ChatCompletionCreateParams: Configura la solicitud a la IA
model: Especifica qué modelo de IA usar (debe coincidir con el ID exacto defoundry model list)addUserMessage: Añade tu mensaje a la conversaciónmaxCompletionTokens: Limita la longitud de la respuesta (ahorra recursos)temperature: Controla la aleatoriedad (0.0 = determinista, 1.0 = creativo)
- Llamada API: Envía la solicitud a Foundry Local
- Manejo de Respuesta: Extrae la respuesta textual de la IA de forma segura
- Manejo de Errores: Envuelve excepciones con mensajes de error claros
4. Dependencias del Proyecto (pom.xml)
Dependencias Clave:
<!-- Spring Boot - Application framework -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- OpenAI Java SDK - For AI API calls -->
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>2.12.0</version>
</dependency>
<!-- Jackson - JSON processing -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
Qué hacen estas:
- spring-boot-starter: Proporciona funcionalidad básica de Spring Boot
- openai-java: SDK oficial de OpenAI para Java para comunicación con la API
- jackson-databind: Maneja la serialización/deserialización JSON para llamadas API
Cómo Funciona Todo Junto
Este es el flujo completo cuando ejecutas la aplicación:
- Inicio: Spring Boot arranca y lee
application.properties - Creación del Servicio: Spring crea
FoundryLocalServicee inyecta los valores de configuración - Detección de Modelo: Si no hay modelo configurado, el servicio consulta
/v1/modelsde Foundry Local y usa automáticamente el primer modelo disponible - Configuración del Cliente:
@PostConstructinicializa el cliente OpenAI para conectar con Foundry Local - Ejecución del Demo:
CommandLineRunnerse ejecuta después del inicio - Llamada IA: El demo llama a
foundryLocalService.chat()con un mensaje de prueba - Solicitud API: El servicio construye y envía una solicitud compatible con OpenAI a Foundry Local
- Procesamiento de Respuesta: El servicio extrae y devuelve la respuesta de la IA
- Visualización: La aplicación imprime la respuesta y finaliza
Configurando Foundry Local
-
Instala Foundry Local siguiendo las instrucciones en la sección de Prerequisitos.
-
Inicia el servicio (si no está corriendo):
foundry service start -
Verifica el estado del servicio para confirmar que está ejecutándose y anota el puerto:
foundry service status -
Descarga y ejecuta un modelo (se descarga la primera vez y se guarda en caché para futuras ejecuciones):
foundry model run phi-4-miniEsto abre una sesión de chat interactiva. Puedes salir con
Ctrl+C. El modelo permanece cargado en el servicio.Consejo: Ejecuta
foundry model listpara ver todos los modelos disponibles. Reemplazaphi-4-minicon cualquier alias del catálogo (ej.,qwen2.5-0.5bpara un modelo más pequeño/rápido). -
Verifica que el modelo esté cargado:
foundry service ps -
Actualiza
application.propertiessi es necesario:- La
base-urlpor defecto (http://localhost:5273/v1) coincide con el puerto por defecto de la CLI. Actualízala solo sifoundry service statusmuestra un puerto diferente. - El modelo es detectado automáticamente al inicio — no requiere configuración.
foundry.local.base-url=http://localhost:5273/v1 # Model is auto-detected. Uncomment below to override: # foundry.local.model=Phi-4-mini-instruct-cuda-gpu:5 - La
Ejecutando la Aplicación
Paso 1: Asegúrate de que un modelo esté cargado en Foundry Local
foundry service ps
Si no hay modelos listados, carga uno:
foundry model run phi-4-mini
Paso 2: Compila y Ejecuta la Aplicación
En una terminal separada:
cd 04-PracticalSamples/foundrylocal
mvn spring-boot:run
O compílala y ejecútala como JAR:
mvn clean package
java -jar target/foundry-local-spring-boot-0.0.1-SNAPSHOT.jar
Salida Esperada
=== Foundry Local Demo ===
Calling Foundry Local service...
Sending message: Hello! Can you tell me what you are and what model you're running?
Response from Foundry Local:
Hello! I'm Phi, an AI developed by Microsoft. I can assist with a wide variety of
tasks including answering questions, helping with analysis, creative writing, coding,
and general conversation. How can I help you today?
=========================
Próximos Pasos
Para más ejemplos, consulta Capítulo 04: Ejemplos prácticos
Solución de Problemas
Problemas Comunes
"Conexión rechazada" o "Servicio no disponible"
- Verifica el servicio:
foundry service status - Reinicia si es necesario:
foundry service restart - Asegúrate que el puerto en
application.propertiescoincida con la salida defoundry service status - Verifica que la URL termine con
/v1:http://localhost:5273/v1
"No se encontró modelo" al iniciar
- La aplicación detecta el modelo automáticamente. Asegúrate que haya al menos un modelo cargado:
foundry service ps - Si no hay modelos cargados:
foundry model run phi-4-mini - Si sobreescribiste el nombre del modelo en
application.properties, verifica que coincida confoundry model list
Errores "400 Bad Request"
- Verifica que la URL base incluya
/v1:http://localhost:5273/v1 - Asegúrate de usar
maxCompletionTokens()en tu código (no el obsoletomaxTokens())
Errores de compilación en Maven
- Asegúrate de tener Java 21 o superior:
java -version - Limpia y recompila:
mvn clean compile - Verifica la conexión a internet para descargar dependencias
Problemas de conexión al servicio
- Si ves
Request to local service failed, ejecuta:foundry service restart - Revisa los modelos cargados:
foundry service ps - Consulta los logs del servicio:
foundry service diag
Descargo de responsabilidad:
Este documento ha sido traducido utilizando el servicio de traducción automática Co-op Translator. Aunque nos esforzamos por la precisión, tenga en cuenta que las traducciones automáticas pueden contener errores o inexactitudes. El documento original en su idioma nativo debe considerarse la fuente autorizada. Para información crítica, se recomienda una traducción profesional realizada por humanos. No nos hacemos responsables de ningún malentendido o interpretación errónea derivada del uso de esta traducción.