Parte 2: Approfondimento sul Foundry Local SDK

April 21, 2026 · View on GitHub

Foundry Local

Parte 2: Approfondimento sul Foundry Local SDK

Obiettivo: Padroneggiare il Foundry Local SDK per gestire modelli, servizi e caching in modo programmatico - e capire perché l’SDK è l'approccio consigliato rispetto alla CLI per costruire applicazioni.

Panoramica

Nella Parte 1 hai utilizzato il Foundry Local CLI per scaricare e far girare i modelli in modo interattivo. La CLI è ottima per l’esplorazione, ma quando costruisci applicazioni reali hai bisogno di un controllo programmatico. Il Foundry Local SDK ti offre proprio questo - gestisce il control plane (avvio del servizio, scoperta dei modelli, download, caricamento) così il codice della tua applicazione può concentrarsi sul data plane (invio prompt, ricezione completamenti).

Questo laboratorio ti insegna l’intera API dello SDK in Python, JavaScript e C#. Alla fine capirai ogni metodo disponibile e quando usarlo.

Obiettivi di Apprendimento

Al termine di questo laboratorio sarai in grado di:

  • Spiegare perché l’SDK è preferito rispetto alla CLI per lo sviluppo applicativo
  • Installare il Foundry Local SDK per Python, JavaScript o C#
  • Usare FoundryLocalManager per avviare il servizio, gestire modelli e interrogare il catalogo
  • Elencare, scaricare, caricare e scaricare modelli in modo programmatico
  • Ispezionare i metadati del modello utilizzando FoundryModelInfo
  • Comprendere la differenza tra modelli catalogati, in cache e caricati
  • Usare il bootstrap del costruttore (Python) e il pattern create() + catalogo (JavaScript)
  • Capire il redesign dello SDK C# e la sua API orientata agli oggetti

Prerequisiti

RequisitoDettagli
Foundry Local CLIInstallato e nel tuo PATH (Parte 1)
Runtime linguaggioPython 3.9+ e/o Node.js 18+ e/o .NET 9.0+

Concetto: SDK vs CLI - Perché usare l’SDK?

AspettoCLI (comando foundry)SDK (foundry-local-sdk)
Caso d’usoEsplorazione, test manualeIntegrazione applicativa
Gestione del servizioManuale: foundry service startAutomatica: manager.start_service() (Python) / manager.startWebService() (JS/C#)
Scoperta della portaLettura dall’output CLImanager.endpoint (Python) / manager.urls[0] (JS/C#)
Download modellofoundry model download aliasmanager.download_model(alias) (Python) / model.download() (JS/C#)
Gestione erroriCodici di uscita, stderrEccezioni, errori tipizzati
AutomazioneScript shellIntegrazione nativa nel linguaggio
DeploymentRichiede CLI sulla macchina utenteSDK C# può essere standalone (senza CLI)

Insight chiave: L’SDK gestisce l’intero ciclo di vita: avvia il servizio, controlla la cache, scarica i modelli mancanti, li carica e scopre l’endpoint, in poche righe di codice. La tua applicazione non deve parsare output della CLI o gestire sottoprocessi.


Esercizi di laboratorio

Esercizio 1: Installare l’SDK

🐍 Python

pip install foundry-local-sdk

Verifica l’installazione:

from foundry_local import FoundryLocalManager
print("SDK installed successfully")

📘 JavaScript

npm install foundry-local-sdk

Verifica l’installazione:

import { FoundryLocalManager } from "foundry-local-sdk";
console.log("SDK installed successfully");

💜 C#

Ci sono due pacchetti NuGet:

PacchettoPiattaformaDescrizione
Microsoft.AI.Foundry.LocalCross-platformFunziona su Windows, Linux, macOS
Microsoft.AI.Foundry.Local.WinMLSolo WindowsAggiunge accelerazione hardware WinML; scarica e installa plugin per esecuzione (es. QNN per Qualcomm NPU)

Setup Windows:

dotnet new console -n foundry-sdk-demo
cd foundry-sdk-demo

Modifica il file .csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <!-- Windows: windows-specific TFM so WinML (QNN EP plugin) can load -->
    <TargetFramework Condition="$([MSBuild]::IsOSPlatform('Windows'))">net9.0-windows10.0.26100</TargetFramework>
    <!-- Non-Windows: plain TFM (WinML is not available) -->
    <TargetFramework Condition="!$([MSBuild]::IsOSPlatform('Windows'))">net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <!-- WinML requires these properties on Windows -->
  <PropertyGroup Condition="$([MSBuild]::IsOSPlatform('Windows'))">
    <WindowsAppSDKSelfContained>false</WindowsAppSDKSelfContained>
    <WindowsPackageType>None</WindowsPackageType>
    <EnableCoreMrtTooling>false</EnableCoreMrtTooling>
  </PropertyGroup>

  <!-- Windows: WinML is a superset (base SDK + QNN EP plugin) -->
  <ItemGroup Condition="$([MSBuild]::IsOSPlatform('Windows'))">
    <PackageReference Include="Microsoft.AI.Foundry.Local.WinML" Version="[0.9.0,1.0.0)" />
  </ItemGroup>

  <!-- Non-Windows: base SDK only -->
  <ItemGroup Condition="!$([MSBuild]::IsOSPlatform('Windows'))">
    <PackageReference Include="Microsoft.AI.Foundry.Local" Version="[0.9.0,1.0.0)" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.10" />
  </ItemGroup>
</Project>

Nota: Su Windows, il pacchetto WinML è un superset che include l’SDK base più il provider di esecuzione QNN. Su Linux/macOS si usa l’SDK base. La condizione TFM e i riferimenti al pacchetto rendono il progetto completamente cross-platform.

Crea un nuget.config nella radice del progetto:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    <add key="ORT" value="https://aiinfra.pkgs.visualstudio.com/PublicPackages/_packaging/ORT/nuget/v3/index.json" />
  </packageSources>
  <packageSourceMapping>
    <packageSource key="nuget.org">
      <package pattern="*" />
    </packageSource>
    <packageSource key="ORT">
      <package pattern="*Foundry*" />
    </packageSource>
  </packageSourceMapping>
</configuration>

Ripristina i pacchetti:

dotnet restore

La prima cosa che fa un’applicazione è avviare il servizio Foundry Local e scoprire quali modelli sono disponibili.

🐍 Python

from foundry_local import FoundryLocalManager

# Crea un gestore e avvia il servizio
manager = FoundryLocalManager()
manager.start_service()

# Elenca tutti i modelli disponibili nel catalogo
catalog = manager.list_catalog_models()
print(f"Models available in catalog: {len(catalog)}")

for model in catalog:
    print(f"  - {model.alias} ({model.id})")
    print(f"    Task: {model.task}, Size: {model.file_size_mb} MB")
    print(f"    Device: {model.device_type}, Provider: {model.publisher}")

Python SDK - Metodi di gestione del servizio

MetodoFirmaDescrizione
is_service_running()() -> boolControlla se il servizio è in esecuzione
start_service()() -> NoneAvvia il servizio Foundry Local
service_uri@property -> strURI base del servizio
endpoint@property -> strEndpoint API (URI servizio + /v1)
api_key@property -> strChiave API (da env o valore di default)
MetodoFirmaDescrizione
list_catalog_models()() -> list[FoundryModelInfo]Elenca tutti i modelli nel catalogo
refresh_catalog()() -> NoneAggiorna il catalogo dal servizio
get_model_info()(alias_or_model_id: str, raise_on_not_found=False) -> FoundryModelInfo | NoneOttiene info per un modello specifico

📘 JavaScript

import { FoundryLocalManager } from "foundry-local-sdk";

// Crea un manager e avvia il servizio
FoundryLocalManager.create({ appName: "SDKDemo" });
const manager = FoundryLocalManager.instance;
await manager.startWebService();

// Sfoglia il catalogo
const catalog = manager.catalog;
const model = await catalog.getModel("phi-3.5-mini");
console.log(`Model alias: ${model.alias}`);
console.log(`Model ID:    ${model.id}`);
console.log(`Cached:      ${model.isCached}`);

JavaScript SDK - Metodi del Manager

MetodoFirmaDescrizione
FoundryLocalManager.create()(options: { appName: string }) => voidInizializza il singleton dello SDK
FoundryLocalManager.instanceFoundryLocalManagerAccesso al manager singleton
manager.startWebService()() => Promise<void>Avvia il servizio web Foundry Local
manager.urlsstring[]Array degli URL base del servizio

JavaScript SDK - Metodi del catalogo e modelli

MetodoFirmaDescrizione
manager.catalogCatalogAccede al catalogo modelli
catalog.getModel()(alias: string) => Promise<Model>Ottiene un oggetto modello tramite alias

💜 C#

Il C# SDK v0.8.0+ usa un’architettura orientata agli oggetti con Configuration, Catalog e Model:

using Microsoft.AI.Foundry.Local;
using Microsoft.Extensions.Logging.Abstractions;

// Step 1: Configure
var config = new Configuration
{
    AppName = "SDKDemo",
    Web = new Configuration.WebService { Urls = "http://127.0.0.1:0" }
};

// Step 2: Create the manager
await FoundryLocalManager.CreateAsync(config, NullLogger.Instance, default);
var manager = FoundryLocalManager.Instance;
await manager.StartWebServiceAsync(default);

// Step 3: Browse the catalog
var catalog = await manager.GetCatalogAsync(default);
var models = await catalog.ListModelsAsync(default);

Console.WriteLine($"Models available in catalog: {models.Count()}");

foreach (var model in models)
{
    Console.WriteLine($"  - {model.Alias} ({model.ModelId})");
}

C# SDK - Classi chiave

ClasseScopo
ConfigurationImposta nome app, livello log, directory cache, URL del server web
FoundryLocalManagerEntry point principale - creato tramite CreateAsync(), accessibile via .Instance
CatalogNaviga, cerca e ottiene modelli dal catalogo
ModelRappresenta un modello specifico - scarica, carica, ottiene client
MetodoDescrizione
FoundryLocalManager.CreateAsync(config, logger)Inizializza il manager
FoundryLocalManager.InstanceAccesso al manager singleton
manager.GetCatalogAsync()Ottiene il catalogo modelli
catalog.ListModelsAsync()Elenca tutti i modelli disponibili
catalog.GetModelAsync(alias: "alias")Ottiene un modello specifico per alias
catalog.GetCachedModelsAsync()Elenca modelli scaricati
catalog.GetLoadedModelsAsync()Elenca modelli attualmente caricati

Nota architetturale C#: Il redesign dello SDK v0.8.0+ rende l’applicazione autosufficiente; non richiede il Foundry Local CLI sulla macchina dell’utente finale. Lo SDK gestisce nativamente la gestione modello e l’inferenza.


Esercizio 3: Scaricare e Caricare un Modello

Lo SDK separa il download (su disco) dal caricamento (in memoria). Questo ti permette di pre-scaricare modelli in fase di setup e caricarli su richiesta.

🐍 Python

from foundry_local import FoundryLocalManager

alias = "phi-3.5-mini"

# Opzione A: Passo manuale passo dopo passo
manager = FoundryLocalManager()
manager.start_service()

# Controlla prima la cache
cached = manager.list_cached_models()
model_info = manager.get_model_info(alias)
is_cached = any(m.id == model_info.id for m in cached) if model_info else False

if not is_cached:
    print(f"Downloading {alias}...")
    manager.download_model(alias)

print(f"Loading {alias}...")
loaded = manager.load_model(alias)
print(f"Loaded: {loaded.id}")
print(f"Endpoint: {manager.endpoint}")

# Opzione B: Bootstrap in una riga (consigliato)
# Passa l'alias al costruttore - avvia il servizio, scarica e carica automaticamente
manager = FoundryLocalManager(alias)
print(f"Ready! Endpoint: {manager.endpoint}")

Python - Metodi di gestione modello

MetodoFirmaDescrizione
download_model()(alias_or_model_id, token=None, force=False) -> FoundryModelInfoScarica un modello nella cache locale
load_model()(alias_or_model_id, ttl=600) -> FoundryModelInfoCarica un modello nel server di inferenza
unload_model()(alias_or_model_id, force=False) -> NoneScarica un modello dal server
list_loaded_models()() -> list[FoundryModelInfo]Elenca tutti i modelli attualmente caricati

Python - Metodi di gestione cache

MetodoFirmaDescrizione
get_cache_location()() -> strOttiene il percorso della directory cache
list_cached_models()() -> list[FoundryModelInfo]Elenca tutti i modelli scaricati

📘 JavaScript

import { FoundryLocalManager } from "foundry-local-sdk";

const alias = "phi-3.5-mini";

// Approccio passo-passo
FoundryLocalManager.create({ appName: "SDKDemo" });
const manager = FoundryLocalManager.instance;
await manager.startWebService();

const catalog = manager.catalog;
const model = await catalog.getModel(alias);

if (!model.isCached) {
  console.log(`Downloading ${alias}...`);
  await model.download();
}

console.log(`Loading ${alias}...`);
await model.load();
console.log(`Loaded: ${model.id}`);
console.log(`Endpoint: ${manager.urls[0]}/v1`);

JavaScript - Metodi modello

MetodoFirmaDescrizione
model.isCachedbooleanIndica se il modello è già scaricato
model.download()() => Promise<void>Scarica il modello nella cache locale
model.load()() => Promise<void>Carica nel server di inferenza
model.unload()() => Promise<void>Scarica dal server di inferenza
model.idstringIdentificativo univoco del modello

💜 C#

using Microsoft.AI.Foundry.Local;
using Microsoft.Extensions.Logging.Abstractions;

var alias = "phi-3.5-mini";

var config = new Configuration
{
    AppName = "SDKDemo",
    Web = new Configuration.WebService { Urls = "http://127.0.0.1:0" }
};

await FoundryLocalManager.CreateAsync(config, NullLogger.Instance, default);
var manager = FoundryLocalManager.Instance;
await manager.StartWebServiceAsync(default);

// Get model from catalog
var catalog = await manager.GetCatalogAsync(default);
var model = await catalog.GetModelAsync(alias, default);

// View available variants
Console.WriteLine($"Model: {model.Alias}");
foreach (var variant in model.Variants)
{
    Console.WriteLine($"  Variant: {variant.Info.ModelId}");
    Console.WriteLine($"    Device: {variant.Info.Runtime?.DeviceType}");
}

// Download if needed
var isCached = await model.IsCachedAsync(default);
if (!isCached)
{
    Console.WriteLine("Downloading...");
    await model.DownloadAsync(null, default);
}

// Load into memory
Console.WriteLine("Loading...");
await model.LoadAsync(default);
Console.WriteLine($"Model loaded: {model.Id}");

C# - Metodi modello

MetodoDescrizione
model.DownloadAsync(progress?)Scarica la variante selezionata
model.LoadAsync()Carica il modello in memoria
model.UnloadAsync()Scarica il modello
model.SelectVariant(variant)Seleziona una variante specifica (CPU/GPU/NPU)
model.SelectedVariantLa variante attualmente selezionata
model.VariantsTutte le varianti disponibili per questo modello
model.GetPathAsync()Ottiene il percorso locale del file
model.GetChatClientAsync()Ottiene un client chat nativo (senza OpenAI SDK)
model.GetAudioClientAsync()Ottiene un client audio per trascrizione

Esercizio 4: Ispezionare i Metadati del Modello

L’oggetto FoundryModelInfo contiene metadati ricchi su ogni modello. Capire questi campi ti aiuta a scegliere il modello giusto per la tua applicazione.

🐍 Python

from foundry_local import FoundryLocalManager

manager = FoundryLocalManager()
manager.start_service()

# Ottieni informazioni dettagliate su un modello specifico
info = manager.get_model_info("phi-3.5-mini")
if info:
    print(f"Alias:              {info.alias}")
    print(f"Model ID:           {info.id}")
    print(f"Version:            {info.version}")
    print(f"Task:               {info.task}")
    print(f"Device Type:        {info.device_type}")
    print(f"Execution Provider: {info.execution_provider}")
    print(f"File Size (MB):     {info.file_size_mb}")
    print(f"Publisher:          {info.publisher}")
    print(f"License:            {info.license}")
    print(f"Tool Calling:       {info.supports_tool_calling}")

📘 JavaScript

import { FoundryLocalManager } from "foundry-local-sdk";

FoundryLocalManager.create({ appName: "SDKDemo" });
const manager = FoundryLocalManager.instance;
await manager.startWebService();

const catalog = manager.catalog;
const model = await catalog.getModel("phi-3.5-mini");
console.log(`Alias:              ${model.alias}`);
console.log(`Model ID:           ${model.id}`);
console.log(`Cached:             ${model.isCached}`);

Campi di FoundryModelInfo

CampoTipoDescrizione
aliasstringaNome breve (es. phi-3.5-mini)
idstringaIdentificativo univoco del modello
versionstringaVersione del modello
taskstringachat-completions o automatic-speech-recognition
device_typeDeviceTypeCPU, GPU o NPU
execution_providerstringaBackend runtime (CUDA, CPU, QNN, WebGPU, ecc.)
file_size_mbintDimensione su disco in MB
supports_tool_callingboolSe il modello supporta funzioni/chiamate a tool
publisherstringaChi ha pubblicato il modello
licensestringaNome della licenza
uristringaURI del modello
prompt_templatedict/nullTemplate del prompt, se presente

Esercizio 5: Gestire il Ciclo di Vita del Modello

Esercitati con il ciclo completo: elenco → download → carica → usa → scarica.

🐍 Python

from foundry_local import FoundryLocalManager

alias = "qwen2.5-0.5b"  # Modello piccolo per test rapidi

manager = FoundryLocalManager()
manager.start_service()

# 1. Controlla cosa c'è nel catalogo
catalog = manager.list_catalog_models()
print(f"Catalog: {len(catalog)} models")

# 2. Controlla cosa è già scaricato
cached = manager.list_cached_models()
print(f"Cached: {len(cached)} models")
for m in cached:
    print(f"  - {m.alias} ({m.file_size_mb} MB)")

# 3. Scarica un modello
print(f"\nDownloading {alias}...")
manager.download_model(alias)
print("Download complete")

# 4. Verifica che sia ora nella cache
cached = manager.list_cached_models()
print(f"Cached after download: {len(cached)} models")

# 5. Caricalo
print(f"\nLoading {alias}...")
loaded_info = manager.load_model(alias)
print(f"Loaded: {loaded_info.id}")

# 6. Controlla cosa è caricato
loaded = manager.list_loaded_models()
print(f"\nLoaded models: {len(loaded)}")
for m in loaded:
    print(f"  - {m.alias} ({m.id})")

# 7. Scaricalo
print(f"\nUnloading {alias}...")
manager.unload_model(alias)
loaded = manager.list_loaded_models()
print(f"Loaded models after unload: {len(loaded)}")

📘 JavaScript

import { FoundryLocalManager } from "foundry-local-sdk";

const alias = "qwen2.5-0.5b"; // Modello piccolo per test veloci

FoundryLocalManager.create({ appName: "SDKDemo" });
const manager = FoundryLocalManager.instance;
await manager.startWebService();

// 1. Prendere il modello dal catalogo
const catalog = manager.catalog;
const model = await catalog.getModel(alias);
console.log(`Model: ${model.alias} (${model.id})`);
console.log(`Cached: ${model.isCached}`);

// 2. Scaricare se necessario
if (!model.isCached) {
  console.log(`\nDownloading ${alias}...`);
  await model.download();
  console.log("Download complete");
}

// 3. Caricarlo
console.log(`\nLoading ${alias}...`);
await model.load();
console.log(`Loaded: ${model.id}`);

// 4. Scaricarlo
console.log(`\nUnloading ${alias}...`);
await model.unload();
console.log("Unloaded");

Esercizio 6: I Modelli Quick-Start

Ogni linguaggio fornisce una scorciatoia per avviare il servizio e caricare un modello in una sola chiamata. Questi sono i modelli consigliati per la maggior parte delle applicazioni.

🐍 Python - Constructor Bootstrap

from foundry_local import FoundryLocalManager

# Passa un alias al costruttore - gestisce tutto:
# 1. Avvia il servizio se non è in esecuzione
# 2. Scarica il modello se non è in cache
# 3. Carica il modello nel server di inferenza
manager = FoundryLocalManager("phi-3.5-mini")

# Pronto all'uso immediatamente
print(f"Endpoint: {manager.endpoint}")
print(f"Model ID: {manager.get_model_info('phi-3.5-mini').id}")

Il parametro bootstrap (predefinito True) controlla questo comportamento. Imposta bootstrap=False se desideri il controllo manuale:

# Modalità manuale - nulla accade automaticamente
manager = FoundryLocalManager(bootstrap=False)

📘 JavaScript - `create()` + Catalog

import { FoundryLocalManager } from "foundry-local-sdk";

// create() + startWebService() + catalog.getModel() gestisce tutto:
// 1. Avvia il servizio
// 2. Ottiene il modello dal catalogo
// 3. Scarica se necessario e carica il modello
FoundryLocalManager.create({ appName: "QuickStart" });
const manager = FoundryLocalManager.instance;
await manager.startWebService();

const model = await manager.catalog.getModel("phi-3.5-mini");
if (!model.isCached) await model.download();
await model.load();

// Pronto per l'uso immediatamente
console.log(`Endpoint: ${manager.urls[0]}/v1`);
console.log(`Model ID: ${model.id}`);

💜 C# - `CreateAsync()` + Catalog

using Microsoft.AI.Foundry.Local;
using Microsoft.Extensions.Logging.Abstractions;

var config = new Configuration
{
    AppName = "QuickStart",
    Web = new Configuration.WebService { Urls = "http://127.0.0.1:0" }
};

await FoundryLocalManager.CreateAsync(config, NullLogger.Instance, default);
var manager = FoundryLocalManager.Instance;
await manager.StartWebServiceAsync(default);

var catalog = await manager.GetCatalogAsync(default);
var model = await catalog.GetModelAsync("phi-3.5-mini", default);

var isCached = await model.IsCachedAsync(default);
if (!isCached)
    await model.DownloadAsync(null, default);
await model.LoadAsync(default);

Console.WriteLine($"Model loaded: {model.Id}");

Nota C#: L’SDK C# utilizza Configuration per controllare il nome dell’app, il logging, le directory cache e persino per fissare una porta specifica del server web. Questo lo rende il più configurabile dei tre SDK.


Esercizio 7: Il ChatClient Nativo (Non Serve l’OpenAI SDK)

Gli SDK JavaScript e C# forniscono un metodo comodo createChatClient() che restituisce un client chat nativo — non è necessario installare o configurare separatamente l’OpenAI SDK.

📘 JavaScript - model.createChatClient()

import { FoundryLocalManager } from "foundry-local-sdk";

FoundryLocalManager.create({ appName: "ChatClientDemo" });
const manager = FoundryLocalManager.instance;
await manager.startWebService();

const model = await manager.catalog.getModel("phi-3.5-mini");
if (!model.isCached) await model.download();
await model.load();

// Crea un ChatClient direttamente dal modello — nessuna importazione OpenAI necessaria
const chatClient = model.createChatClient();

// completeChat restituisce un oggetto di risposta compatibile con OpenAI
const response = await chatClient.completeChat([
  { role: "user", content: "What is the golden ratio?" }
]);
console.log(response.choices[0].message.content);

// Lo streaming utilizza un modello di callback
await chatClient.completeStreamingChat(
  [{ role: "user", content: "Explain quantum computing briefly." }],
  (chunk) => {
    if (chunk.choices?.[0]?.delta?.content) {
      process.stdout.write(chunk.choices[0].delta.content);
    }
  }
);

Il ChatClient supporta anche le chiamate agli strumenti — passa gli strumenti come secondo argomento:

const response = await chatClient.completeChat(messages, tools);

💜 C# - model.GetChatClientAsync()

var catalog = await manager.GetCatalogAsync(default);
var model = await catalog.GetModelAsync("phi-3.5-mini", default);
if (!await model.IsCachedAsync(default))
    await model.DownloadAsync(null, default);
await model.LoadAsync(default);

// Get a native chat client — no OpenAI NuGet package needed
var chatClient = await model.GetChatClientAsync(default);

// Use it exactly like the OpenAI ChatClient
var response = chatClient.CompleteChat("What is the golden ratio?");
Console.WriteLine(response.Value.Content[0].Text);

Quando usare quale modello:

  • createChatClient() — Prototipazione rapida, meno dipendenze, codice più semplice
  • OpenAI SDK — Controllo completo sui parametri (temperature, top_p, token di stop, ecc.), migliore per applicazioni in produzione

Esercizio 8: Varianti dei Modelli e Selezione Hardware

I modelli possono avere diverse varianti ottimizzate per hardware differenti. L’SDK seleziona automaticamente la variante migliore, ma puoi anche ispezionare e scegliere manualmente.

📘 JavaScript

import { FoundryLocalManager } from "foundry-local-sdk";

FoundryLocalManager.create({ appName: "VariantDemo" });
const manager = FoundryLocalManager.instance;
await manager.startWebService();

const model = await manager.catalog.getModel("phi-3.5-mini");

// Elenca tutte le varianti disponibili
console.log(`Model: ${model.alias}`);
console.log(`Variants: ${model.variants.length}`);
for (const variant of model.variants) {
  console.log(`  - ${variant.modelId}`);
  console.log(`    Device: ${variant.deviceType}, Provider: ${variant.executionProvider}`);
}

// L'SDK seleziona automaticamente la migliore variante per il tuo hardware
// Per sovrascrivere, usa selectVariant():
// model.selectVariant(model.variants[0]);

💜 C#

var model = await catalog.GetModelAsync("phi-3.5-mini", default);

Console.WriteLine($"Model: {model.Alias}");
Console.WriteLine($"Selected variant: {model.SelectedVariant?.Info.ModelId}");
Console.WriteLine($"All variants:");
foreach (var variant in model.Variants)
{
    Console.WriteLine($"  - {variant.Info.ModelId}");
    Console.WriteLine($"    Device: {variant.Info.Runtime?.DeviceType}");
}

// To select a specific variant:
// model.SelectVariant(model.Variants.First());

🐍 Python

In Python, l’SDK seleziona automaticamente la variante migliore in base all’hardware. Usa get_model_info() per vedere qual è stata selezionata:

from foundry_local import FoundryLocalManager

manager = FoundryLocalManager()
manager.start_service()

info = manager.get_model_info("phi-3.5-mini")
print(f"Selected model: {info.id}")
print(f"Device: {info.device_type}")
print(f"Provider: {info.execution_provider}")

Modelli con Varianti NPU

Alcuni modelli hanno varianti ottimizzate per NPU (Neural Processing Units) in dispositivi come Qualcomm Snapdragon, Intel Core Ultra:

ModelloVariante NPU Disponibile
phi-3.5-mini
phi-3-mini-128k
phi-3-mini-4k
deepseek-r1-14b
deepseek-r1-7b
qwen2.5-1.5b
qwen2.5-7b

Suggerimento: Su hardware con NPU, l’SDK seleziona automaticamente la variante NPU quando disponibile. Non è necessario modificare il codice. Per progetti C# su Windows, aggiungi il pacchetto NuGet Microsoft.AI.Foundry.Local.WinML per abilitare il provider di esecuzione QNN — QNN è fornito come plugin EP tramite WinML.


Il catalogo dei modelli viene aggiornato periodicamente. Usa questi metodi per controllare e applicare gli aggiornamenti.

🐍 Python

from foundry_local import FoundryLocalManager

manager = FoundryLocalManager()
manager.start_service()

alias = "phi-3.5-mini"

# Aggiorna il catalogo per ottenere l'ultima lista dei modelli
manager.refresh_catalog()

# Verifica se un modello memorizzato nella cache ha una versione più recente disponibile
if manager.is_model_upgradeable(alias):
    print(f"{alias} has a newer version available!")
    manager.upgrade_model(alias)
    print("Upgrade complete")
else:
    print(f"{alias} is up to date")

📘 JavaScript

import { FoundryLocalManager } from "foundry-local-sdk";

FoundryLocalManager.create({ appName: "UpgradeDemo" });
const manager = FoundryLocalManager.instance;
await manager.startWebService();

// Aggiorna il catalogo per ottenere l'ultima lista dei modelli
await manager.catalog.updateModels();
console.log("Catalog refreshed");

// Elenca tutti i modelli disponibili dopo l'aggiornamento
const models = await manager.catalog.getModels();
console.log(`${models.length} models available`);

Esercizio 10: Lavorare con i Modelli di Ragionamento

Il modello phi-4-mini-reasoning include ragionamento a catena di pensiero (chain-of-thought). Incapsula il suo ragionamento interno in tag <think>...</think> prima di produrre la risposta finale. Questo è utile per compiti che richiedono logica multi-step, matematica o problem solving.

🐍 Python

import openai
from foundry_local import FoundryLocalManager

# phi-4-mini-reasoning è circa 4,6 GB
manager = FoundryLocalManager("phi-4-mini-reasoning")

client = openai.OpenAI(base_url=manager.endpoint, api_key=manager.api_key)
model_id = manager.get_model_info("phi-4-mini-reasoning").id

response = client.chat.completions.create(
    model=model_id,
    messages=[{"role": "user", "content": "What is 17 × 23?"}],
)

content = response.choices[0].message.content

# Il modello incapsula il suo pensiero nei tag <think>...</think>
if "<think>" in content and "</think>" in content:
    think_start = content.index("<think>") + len("<think>")
    think_end = content.index("</think>")
    thinking = content[think_start:think_end].strip()
    answer = content[think_end + len("</think>"):].strip()
    print(f"Thinking: {thinking}")
    print(f"Answer: {answer}")
else:
    print(content)

📘 JavaScript

import { OpenAI } from "openai";
import { FoundryLocalManager } from "foundry-local-sdk";

FoundryLocalManager.create({ appName: "ReasoningDemo" });
const manager = FoundryLocalManager.instance;
await manager.startWebService();

const model = await manager.catalog.getModel("phi-4-mini-reasoning");
if (!model.isCached) await model.download();
await model.load();

const client = new OpenAI({
  baseURL: manager.urls[0] + "/v1",
  apiKey: "foundry-local",
});

const response = await client.chat.completions.create({
  model: model.id,
  messages: [{ role: "user", content: "What is 17 × 23?" }],
});

const content = response.choices[0].message.content;

// Analizza il pensiero a catena
const thinkMatch = content.match(/<think>([\s\S]*?)<\/think>/);
if (thinkMatch) {
  console.log(`Thinking: ${thinkMatch[1].trim()}`);
  console.log(`Answer: ${content.replace(/<think>[\s\S]*?<\/think>/, "").trim()}`);
} else {
  console.log(content);
}

Quando usare modelli di ragionamento:

  • Problemi di matematica e logica
  • Compiti di pianificazione a più passaggi
  • Generazione codice complessa
  • Attività in cui mostrare il processo migliora la precisione

Contro: I modelli di ragionamento producono più token (la sezione <think>) e sono più lenti. Per Q&A semplici, un modello standard come phi-3.5-mini è più veloce.


Esercizio 11: Comprendere Alias e Selezione Hardware

Quando passi un alias (come phi-3.5-mini) invece di un ID modello completo, l’SDK seleziona automaticamente la variante migliore per il tuo hardware:

HardwareProvider di Esecuzione Selezionato
GPU NVIDIA (CUDA)CUDAExecutionProvider
NPU QualcommQNNExecutionProvider (tramite plugin WinML)
NPU IntelOpenVINOExecutionProvider
GPU AMDVitisAIExecutionProvider
NVIDIA RTXNvTensorRTRTXExecutionProvider
Qualsiasi dispositivo (fallback)CPUExecutionProvider o WebGpuExecutionProvider
from foundry_local import FoundryLocalManager

manager = FoundryLocalManager()
manager.start_service()

# L'alias risolve nella variante migliore per IL TUO hardware
info = manager.get_model_info("phi-3.5-mini")
print(f"Selected variant: {info.id}")
print(f"Execution provider: {info.execution_provider}")
print(f"Device type: {info.device_type}")

Suggerimento: Usa sempre gli alias nel codice della tua applicazione. Quando distribuisci sulla macchina di un utente, l’SDK sceglie la variante ottimale al runtime - CUDA su NVIDIA, QNN su Qualcomm, CPU altrove.


Esercizio 12: Opzioni di Configurazione C#

La classe Configuration dell’SDK C# offre un controllo granulare sul runtime:

var config = new Configuration
{
    AppName = "MyApp",
    LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information,

    // Pin a specific port (useful for debugging)
    Web = new Configuration.WebService
    {
        Urls = "http://127.0.0.1:55588"
    },

    // Custom directories
    AppDataDir = "./foundry_local_data",
    ModelCacheDir = "{AppDataDir}/model_cache",
    LogsDir = "{AppDataDir}/logs"
};
ProprietàPredefinitoDescrizione
AppName(richiesto)Nome della tua applicazione
LogLevelInformationVerbosità del logging
Web.Urls(dinamico)Fissa una porta specifica per il server web
AppDataDirDefault OSDirectory base per i dati dell’app
ModelCacheDir{AppDataDir}/model_cacheDove sono archiviati i modelli
LogsDir{AppDataDir}/logsDove vengono scritti i log

Esercizio 13: Uso nel Browser (Solo JavaScript)

L’SDK JavaScript include una versione compatibile con il browser. Nel browser, devi avviare manualmente il servizio via CLI e specificare l’URL host:

import { FoundryLocalManager } from "foundry-local-sdk/browser";

// Avviare il servizio manualmente prima:
//   foundry service start
// Quindi utilizzare l'URL dall'output della CLI
FoundryLocalManager.create({ appName: "BrowserDemo" });
const manager = FoundryLocalManager.instance;

// Navigare nel catalogo
const catalog = manager.catalog;
const model = await catalog.getModel("phi-3.5-mini");

if (!model.isCached) {
  await model.download();
}
await model.load();

Limitazioni del browser: La versione browser non supporta startWebService(). Devi assicurarti che il servizio Foundry Local sia già in esecuzione prima di usare l’SDK nel browser.


Riferimento Completo API

Python

CategoriaMetodoDescrizione
InitFoundryLocalManager(alias?, bootstrap=True)Crea il manager; opzionalmente fai bootstrap con un modello
Serviceis_service_running()Verifica se il servizio è in esecuzione
Servicestart_service()Avvia il servizio
ServiceendpointURL endpoint API
Serviceapi_keyChiave API
Cataloglist_catalog_models()Elenca tutti i modelli disponibili
Catalogrefresh_catalog()Aggiorna il catalogo
Catalogget_model_info(alias_or_model_id)Ottieni metadati del modello
Cacheget_cache_location()Percorso directory cache
Cachelist_cached_models()Elenca modelli scaricati
Modeldownload_model(alias_or_model_id)Scarica un modello
Modelload_model(alias_or_model_id, ttl=600)Carica un modello
Modelunload_model(alias_or_model_id)Scarica un modello dalla memoria
Modellist_loaded_models()Elenca modelli caricati
Modelis_model_upgradeable(alias_or_model_id)Verifica se è disponibile una versione più nuova
Modelupgrade_model(alias_or_model_id)Aggiorna un modello all’ultima versione
Servicehttpx_clientClient HTTPX preconfigurato per chiamate API dirette

JavaScript

CategoriaMetodoDescrizione
InitFoundryLocalManager.create(options)Inizializza il singleton SDK
InitFoundryLocalManager.instanceAccesso al manager singleton
Servicemanager.startWebService()Avvia il servizio web
Servicemanager.urlsArray di URL base del servizio
Catalogmanager.catalogAccesso al catalogo modelli
Catalogcatalog.getModel(alias)Ottieni un oggetto modello per alias (ritorna Promise)
Modelmodel.isCachedIndica se il modello è scaricato
Modelmodel.download()Scarica il modello
Modelmodel.load()Carica il modello
Modelmodel.unload()Scarica il modello dalla memoria
Modelmodel.idIdentificatore univoco del modello
Modelmodel.aliasAlias del modello
Modelmodel.createChatClient()Ottieni un client chat nativo (non serve OpenAI SDK)
Modelmodel.createAudioClient()Ottieni un client audio per trascrizione
Modelmodel.removeFromCache()Rimuovi il modello dalla cache locale
Modelmodel.selectVariant(variant)Seleziona una variante hardware specifica
Modelmodel.variantsArray delle varianti disponibili per questo modello
Modelmodel.isLoaded()Verifica se il modello è attualmente caricato
Catalogcatalog.getModels()Elenca tutti i modelli disponibili
Catalogcatalog.getCachedModels()Elenca i modelli scaricati
Catalogcatalog.getLoadedModels()Elenca i modelli attualmente caricati
Catalogcatalog.updateModels()Aggiorna il catalogo dal servizio
Servicemanager.stopWebService()Ferma il servizio web Foundry Local

C# (v0.8.0+)

CategoriaMetodoDescrizione
InitFoundryLocalManager.CreateAsync(config, logger)Inizializza il manager
InitFoundryLocalManager.InstanceAccesso al singleton
Catalogmanager.GetCatalogAsync()Ottieni il catalogo
Catalogcatalog.ListModelsAsync()Elenca tutti i modelli
Catalogcatalog.GetModelAsync(alias)Ottieni un modello specifico
Catalogcatalog.GetCachedModelsAsync()Elenca i modelli in cache
Catalogcatalog.GetLoadedModelsAsync()Elenca i modelli caricati
Modelmodel.DownloadAsync(progress?)Scarica un modello
Modelmodel.LoadAsync()Carica un modello
Modelmodel.UnloadAsync()Scarica un modello dalla memoria
Modelmodel.SelectVariant(variant)Scegli una variante hardware
Modelmodel.GetChatClientAsync()Ottieni client chat nativo
Modelmodel.GetAudioClientAsync()Ottieni client audio per trascrizione
Modelmodel.GetPathAsync()Ottieni percorso file locale
Catalogcatalog.GetModelVariantAsync(alias, variant)Ottieni una variante hardware specifica
Catalogcatalog.UpdateModelsAsync()Aggiorna il catalogo
Servermanager.StartWebServerAsync()Avvia il server web REST
Servermanager.StopWebServerAsync()Ferma il server web REST
Configconfig.ModelCacheDirDirectory cache

Punti Chiave

ConcettoCosa Hai Imparato
SDK vs CLIL’SDK offre controllo programmatico – essenziale per le applicazioni
Piano di controlloL’SDK gestisce servizi, modelli e caching
Porte dinamicheUsa sempre manager.endpoint (Python) o manager.urls[0] (JS/C#) – mai una porta hardcoded
AliasUsa alias per la selezione automatica della variante hardware ottimale
Avvio rapidoPython: FoundryLocalManager(alias), JS: FoundryLocalManager.create() + await catalog.getModel(alias)
Ridisegno C#La versione 0.8.0+ è autonoma - non serve CLI sui computer degli utenti finali
Ciclo di vita del modelloCatalogo → Download → Caricamento → Uso → Scaricamento
FoundryModelInfoMetadati ricchi: task, dispositivo, dimensione, licenza, supporto per richiamo da tool
ChatClientcreateChatClient() (JS) / GetChatClientAsync() (C#) per utilizzo senza OpenAI
VariantiI modelli hanno varianti specifiche per hardware (CPU, GPU, NPU); selezionate automaticamente
AggiornamentiPython: is_model_upgradeable() + upgrade_model() per mantenere i modelli aggiornati
Aggiornamento catalogorefresh_catalog() (Python) / updateModels() (JS) per scoprire nuovi modelli

Risorse

RisorsaLink
Riferimento SDK (tutte le lingue)Microsoft Learn - Foundry Local SDK Reference
Integrazione con SDK di inferenzaMicrosoft Learn - Inference SDK Integration
Riferimento API SDK C#Foundry Local C# API Reference
Esempi SDK C#GitHub - Foundry Local SDK Samples
Sito di Foundry Localfoundrylocal.ai

Passi successivi

Continua con Parte 3: Uso dello SDK con OpenAI per collegare lo SDK alla libreria client OpenAI e costruire la tua prima applicazione di completamento di chat.


Disclaimer:
Questo documento è stato tradotto utilizzando il servizio di traduzione AI Co-op Translator. Pur impegnandoci per garantire l'accuratezza, si prega di notare che le traduzioni automatiche possono contenere errori o inesattezze. Il documento originale nella sua lingua madre deve essere considerato la fonte autorevole. Per informazioni critiche, si consiglia una traduzione professionale effettuata da un umano. Non siamo responsabili per eventuali fraintendimenti o interpretazioni errate derivanti dall'uso di questa traduzione.