Settimana di riferimento: 26 ottobre – 1 novembre 2026. Le novità datate di questo numero sono l'arrivo di GPT-6.1 Terra (26 ottobre) e l'annuncio Microsoft del Copilot harness in Foundry (28 ottobre). Gli approfondimenti su .NET 11 e ArcGIS riprendono documentazione tecnica pubblicata nelle settimane precedenti: non vengono presentati come rilasci dell'ultima settimana.
.NET 11 RC2: quando il confine di un Task non coincide più con un'allocazione
Il documento che vale la lettura integrale resta Performance Improvements in .NET 11, pubblicato da Stephen Toub il 15 settembre 2026. Non è un catalogo di percentuali da trasferire alle applicazioni: mostra come piccoli cambiamenti nella forma dell'IL, nella politica del JIT, nei percorsi del GC e nell'I/O compongano il costo effettivo di un servizio. Al 2 novembre 2026 .NET 11 è ancora nella fase RC2; la disponibilità generale è attesa nel mese di novembre, non va presunta già avvenuta. Fonti: Microsoft Learn, panoramica .NET 11, release notes del runtime.
Runtime Async: cambia il lowering, non il contratto pubblico
Nel lowering classico, Roslyn trasforma ogni metodo async in un entry point e una macchina a stati, con un MoveNext che salva i locali sopravvissuti ai punti di sospensione, registra le continuation e trasferisce il risultato a un AsyncTaskMethodBuilder<T>. Il JIT riceve questa rappresentazione già trasformata. Con Runtime Async V2 il compilatore può invece emettere un IL più compatto, marcato come asincrono, contenente primitive di sospensione riconosciute dal runtime. Il JIT decide la rappresentazione della continuation sulla base della liveness effettiva e può evitare di materializzare alcuni Task intermedi nei collegamenti diretti call → await.
È utile pensare a due identità dello stesso metodo: l'entry point pubblico che continua a rispettare il ritorno Task<T>, e la variante interna AsyncCall, che consente al chiamante runtime-async di ricevere direttamente il risultato o una sospensione. Il contratto di Task, eccezioni, cancellazione e ConfigureAwait rimane valido; l'ottimizzazione elimina confini intermedi non osservabili, non l'astrazione asincrona. Una Task conservata in una collezione, restituita a un consumer esterno o usata per una continuation esplicita può richiedere ancora materializzazione. Fonte primaria: spiegazione del lowering, MethodDesc e AsyncCall.
Compiler lowering classico
A() -> Task[A] -> MoveNext(A) -> Task[B] -> MoveNext(B) -> Task[C]
Runtime Async (caso ottimizzabile)
A() -> Task osservabile all'esterno
|
AsyncCall(B) -> AsyncCall(C) -> risultato / continuation
Obiettivo: togliere materializzazioni intermedie, NON eliminare ogni Task.
L'opt-in applicativo documentato resta esplicito e limitato a progetti net11.0:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net11.0</TargetFramework>
<Features>$(Features);runtime-async=on</Features>
</PropertyGroup>
</Project>
Le librerie del framework sono già in larga parte compilate con Runtime Async. Non occorre attivare LangVersion=preview o EnablePreviewFeatures solo per questa opzione. La documentazione indica che async void, gli iteratori asincroni e i task-like personalizzati con builder proprietari continuano a usare il lowering tradizionale. Se si disabilita, il percorso supportato è una proprietà di progetto (UseRuntimeAsync=false), non i vecchi interruttori d'ambiente rimossi. Fonti: blog sulle performance, Microsoft Learn, Runtime Async.
I benchmark pubblicati da Microsoft sono un buon esempio di lettura corretta dei numeri: nella specifica catena di due livelli mostrata nell'articolo, il caso con completamento sincrono passa da 21,221 ns / 144 B a 6,151 ns / 0 B; con Task.Yield() passa da 254,139 ns / 248 B a 116,927 ns / 168 B. Sono risultati del microbenchmark Microsoft, non un incremento stimabile per qualsiasi API ASP.NET Core, transazione SQL o chiamata remota. La differenza dipende da profondità dei livelli async, tasso di completamento sincrono, generazione JIT, CPU e combinazione delle librerie. Fonte e codice del benchmark.
Analisi architetturale. Le catene di middleware e adapter I/O diventano un candidato più interessante del semplice metodo business: autenticazione, tracing, retry, trasporto e serializzazione spesso si compongono in più wrapper asincroni. Proprio quei wrapper, prima potenzialmente costosi in oggetti intermedi, sono il territorio dell'ottimizzazione. La scelta Task versus ValueTask resta però una decisione di API design: ValueTask<T> ha vincoli di consumo e può essere più grande da trasportare; non è un sostituto sistematico di Task<T>.
JIT, hardware e deployment: una breaking change meno appariscente
C'è un cambiamento operativo più importante di molti microbenchmark: la baseline x86-64 del JIT/AOT passa da v1 a v2, mentre il target ReadyToRun precompilato per Windows e Linux sale a x86-64-v3. La v2 comprende fra gli altri SSE3, SSSE3, SSE4.1, SSE4.2 e POPCNT; la v3 aggiunge tra l'altro AVX, AVX2, FMA e BMI. Il runtime può quindi non avviarsi su CPU che non rispettano la nuova baseline; su CPU supportate ma prive del target R2R ideale può aumentare la quota di codice che deve essere JIT-compilata all'avvio. La matrice Arm64 è diversa per Windows, Linux e Apple: non va generalizzata. Fonte: requisiti hardware .NET 11.
Valutazione. Nelle infrastrutture on-premises e nelle VM con CPU feature masking, il test di compatibilità deve essere eseguito sul guest effettivo, non soltanto sulla scheda tecnica dell'host. Anche una pubblicazione Native AOT non aggira la necessità che il codice nativo sia compatibile con l'ISA disponibile. La migrazione da .NET 10 a .NET 11 non va quindi pianificata come semplice sostituzione di runtime in ambienti eterogenei.
Un secondo dettaglio sorprendentemente rilevante per i servizi è l'analyzer CA2027: identifica alcuni pattern Task.WhenAny(work, Task.Delay(timeout)) che lasciano timer inutilmente pendenti quando work finisce per primo. Il percorso raccomandato è WaitAsync, già disponibile da .NET 6. Nel seguente esempio il CancellationToken del chiamante resta distinto dal timeout locale:
// .NET 10/11: evitare un Task.Delay pendente dopo la risposta rapida.
static async Task<T> WithTimeout<T>(
Task<T> operation,
TimeSpan timeout,
CancellationToken cancellationToken)
{
return await operation.WaitAsync(timeout, cancellationToken);
}
WaitAsync termina l'attesa in modo più pulito ma non garantisce che l'operazione sottostante venga interrotta se non supporta o non riceve la cancellazione. In un servizio che apre richieste HTTP o query SQL il token deve essere propagato alle API I/O per evitare che un timeout del consumer lasci lavoro inutile sul server. Fonte: Performance Improvements in .NET 11, CA2027.
Diagnostica async: il profiling è parte della prestazione
Il nuovo stream leggero per l'async profiling usa registrazioni compatte con buffer per thread e informazioni che consentono di ricostruire lo stack logico a partire dalle continuation. L'articolo Microsoft segnala, in alcune misure, overhead sotto l'1% e dati di tracing ridotti di un ordine di grandezza; non è un SLA del profiler. Conta perché gli approcci molto verbosi basati sugli eventi per ogni transizione Task rischiano di perturbare il workload in produzione. Il problema che si risolve non è solo la velocità del codice: è osservare catene asincrone reali senza trasformare la misurazione in un secondo carico. Riferimenti: Microsoft, async profiler internals, PR dotnet/runtime #127238.
ArcGIS 3.7: prossimità spaziale e prossimità semantica non sono la stessa query
L'aggiornamento concettuale più sostanzioso di ArcGIS Pro 3.7 non è “aggiungere l'AI alla mappa”: è disporre di due diversi spazi di vicinanza. Un vicino geografico minimizza una distanza definita su geometrie e sistema di riferimento; un vicino semantico massimizza una somiglianza fra rappresentazioni apprese da un modello. Il toolset Embeddings Based Analysis introduce strumenti per generare, cercare, aggregare ed estrarre embedding, senza rendere equivalenti tali significati. Fonti: Novità ArcGIS Pro 3.7, toolset GeoAI.
Dalla feature class al vettore: schema, query, indice e licenza
Find Similar Features Using Embeddings costruisce il vettore di query come media degli embedding delle feature che intersecano i poligoni di ricerca; poi calcola cosine similarity rispetto agli embedding nello spazio di ricerca e applica una soglia. Non misura la distanza in metri tra feature né confronta direttamente i pixel dell'immagine originale: nel caso imagery lavora sulle celle dell'embedding grid. Il pannello interattivo Find Similar opera sull'estensione corrente della vista, mentre il tool di geoprocessing è dedicato alle analisi batch estese. Non è corretto confrontare il tempo del pannello con un job batch senza controllare il numero di candidati. Fonti: Funzionamento del tool batch, pannello interattivo.
Spatial retrieval Semantic retrieval
---------------- ------------------
query geometry query polygon -> mean embedding
| |
spatial index / extent embedding space
| |
ST_DWithin / buffer? cosine(query, candidate)
| |
distance in spatial units score without physical unit
Hybrid retrieval (analisi architetturale):
autorizzazione + filtro territoriale -> candidati
candidati -> similarità -> ranking -> controllo umano / validazione
Il BLOB di embedding generato dai tool ArcGIS può essere trasformato in dimensioni numeriche con Extract Embedding To Fields; non è una scelta gratuita sul piano fisico. Tabelle con centinaia di colonne allargano record e trasferimenti, possono penalizzare il query planner e rendere fragile lo schema di interoperabilità. La documentazione Esri raccomanda cautela su dataset molto grandi e segnala che il campo BLOB originale viene conservato. Il tool di ricerca batch richiede ArcGIS Pro Advanced; la generazione di image embeddings presenta ulteriori dipendenze di licenza e dei framework di deep learning. Fonti: estrazione BLOB verso campi, matrice licensing.
Analisi architetturale. Un servizio spatial-semantic per dati aziendali dovrebbe separare tre passaggi: restrizione geografica e autorizzativa dei candidati, recupero/ranking vettoriale, validazione delle regole di dominio. La geometria può fare da filtro obbligatorio o da feature di ranking, ma non è opportuno sommare banalmente metri e coseno in uno score senza una calibrazione statistica: hanno scale, distribuzioni e significati diversi. L'eventuale vettorializzazione in un database terzo richiede una politica esplicita di allineamento di model_id, versione, schema, metriche e normalization; embedding provenienti da modelli differenti non sono confrontabili per definizione.
256 dimensioni, quattro viste: cosa significa davvero interpretare un embedding
Nel post Esri del 6 ottobre 2026, le USA Geodemographic Embeddings sono descritte come quattro segmenti da 64 dimensioni: Housing & Household, Environment, American Community Survey, Age & Race Census, per 256 componenti in totale. La somma delle importanze globali assolute SHAP per segmento dà una misura utile della distribuzione dell'attribuzione del modello predittivo. Non corrisponde però né alla SHAP di un segmento trattato come gruppo né alla perdita di accuratezza eliminando quel segmento; inoltre una singola componente, ad esempio embedding_137, non diventa automaticamente “il reddito”. Fonte primaria: Esri, Interpret embeddings using AutoML and SHAP.
Per verificare il contributo incrementale di una vista occorre un esperimento diverso: ablation di un segmento con riaddestramento, oppure permutazione congiunta delle dimensioni del segmento, mantenendo una strategia di cross-validation adatta al territorio. Split casuali possono introdurre spatial leakage quando aree vicine o derivate dagli stessi dati appaiono contemporaneamente in train e test. Quest'ultima è una valutazione metodologica, non una proprietà dichiarata dal tool Esri. Un'analisi scientificamente utile esplicita metrica target, unità geografiche di split, dipendenza spaziale residua, periodo di riferimento e intervalli di confidenza.
Un'implementazione minima della similarità in C# è volutamente indipendente dallo storage; per dati reali occorre controllare provenienza e normalizzazione del vettore:
using System;
static double Cosine(ReadOnlySpan<float> a, ReadOnlySpan<float> b)
{
if (a.Length == 0 || a.Length != b.Length)
throw new ArgumentException("Dimensioni incompatibili.");
double dot = 0, aa = 0, bb = 0;
for (int i = 0; i < a.Length; i++)
{
if (!float.IsFinite(a[i]) || !float.IsFinite(b[i]))
throw new ArgumentException("Embedding non finito.");
dot += (double)a[i] * b[i];
aa += (double)a[i] * a[i];
bb += (double)b[i] * b[i];
}
if (aa == 0 || bb == 0) throw new ArgumentException("Vettore nullo.");
return Math.Clamp(dot / Math.Sqrt(aa * bb), -1.0, 1.0);
}
La funzione è un baseline CPU esatto O(d) per coppia e non implementa un indice ANN. Il costo di recupero su milioni di candidati si governa a livello di indice e piano di query; la formula del coseno, da sola, non dà un retrieval scalabile. Ancora più importante, non permette di attribuire semantica affidabile a un embedding numerico senza il modello che lo ha prodotto.
Experience Builder Agent Skill: dalla documentazione come testo al contratto verificabile di sviluppo
Il 14 settembre 2026 Esri ha pubblicato un Agent Skill per custom widget Experience Builder, disponibile nel repository ufficiale arcgis-experience-builder-sdk-resources, percorso skills/arcgis-exb-widget-dev. La struttura non contiene solo un prompt generico: include regole sul layout delle estensioni, file (manifest.json, config.json, runtime e settings), mapping delle API, selezione di mappe/layer, accessibilità e gestione dello stato. È pensato per agenti compatibili con il formato SKILL.md. Fonte: Esri, Building Custom Experience Builder Widgets with an Agent Skill.
La proprietà importante è che gli invarianti tecnologici diventano contesto specializzato caricato durante l'implementazione: meno spazio per indovinare path, import e convenzioni, ma nessuna garanzia automatica di correttezza. Il modello resta capace di generare codice sbagliato, in particolare quando l'API si è evoluta. Il skill va quindi affiancato a build, TypeScript checks, test, review del diff e verifica delle versioni.
Un breaking change concreto: 1.21, pnpm, componenti mappa e popup
Le note ufficiali della Developer Edition 1.21 stabiliscono che, da questa versione, per installare le dipendenze serve pnpm ci, non npm ci. Per jimu-arcgis, la migrazione ai componenti <arcgis-map> e <arcgis-scene> introduce jimuMapView.mapComponent. jimuMapView.view rimane accessibile, ma i componenti web devono riferirsi a mapComponent; il vecchio accesso jimuMapView.view.popup non è più disponibile e il popup si governa tramite mapComponent.popupElement, openPopup() e closePopup(). Non si tratta di una previsione di migrazione futura: sono indicazioni e breaking changes documentati per 1.21.
// Frammento illustrativo del nuovo accesso in Experience Builder 1.21.
// jimuMapView va acquisito dal lifecycle del widget; non persisterlo in config.
const mapElement = jimuMapView.mapComponent;
mapElement.openPopup();
const popupElement = mapElement.popupElement;
// I listener reali dipendono dagli eventi documentati del popupElement.
// Registrare i relativi handler nel lifecycle del widget e rimuoverli all'unmount.
Il frammento evidenzia il cambio di surface API, non rappresenta da solo un widget compilabile: non inventa un evento popup ufficiale. La guida dello skill Esri specifica inoltre che i riferimenti JimuMapView e LayerView vanno risolti a runtime, non serializzati in configurazione, e che cambi di vista richiedono pulizia di watcher, highlight, graphic, handle e layer temporanei. Questa disciplina è critica quando l'utente alterna mappe 2D/3D o la pagina ricarica il widget. Fonti: breaking changes 1.21, reference Map/Layer View nello skill.
Valutazione. Una CI credibile per custom widget verifica almeno la configurazione di useMapWidgetIds, il montaggio/smontaggio React, il passaggio fra viste, la liberazione di reactiveUtils handle, la presenza di fallback su dati e layer non pronti, e l'assenza di loop fra DataRecordsSelectionChangeMessage e azioni che cambiano a loro volta la selezione. L'ultima categoria è rilevante perché nella 1.21 i data source possono pubblicare eventi di filtro e selezione: la stessa documentazione avverte del rischio di loop se i callback rimodificano la sorgente.
La convergenza con il mondo degli agenti è evidente: uno skill è utile quando trasferisce all'agente regole con un valore di verifica, non quando pretende che la generazione di codice sia una sostituzione del test.
28 ottobre: Microsoft porta il Copilot harness in Foundry; il confine vero è fra gestione e controllo
La novità infrastrutturale della settimana arriva dal post Microsoft del 28 ottobre 2026: il Microsoft Copilot harness in Foundry Agent Service entra in public preview, mentre la resilienza per workflow lunghi degli hosted agents viene dichiarata generalmente disponibile. Queste sono due notizie diverse: la seconda non rende automaticamente GA il nuovo harness. Fonti: Microsoft Foundry, annuncio tecnico, documentazione operativa.
Un harness integra agent loop, scelta degli strumenti, gestione di file e contesto, skill, sandbox, subagent e delega. Un prompt agent con Copilot harness resta un prompt agent invocabile mediante Responses API; Foundry gestisce runtime e sandbox. Un hosted agent resta l'alternativa per chi ha bisogno di possedere framework, middleware, dipendenze, ciclo di esecuzione e policy di processo. La documentazione segnala che l'harness richiede un progetto/regione e un modello compatibili, che l'opzione si sceglie alla creazione e non si applica retroattivamente agli agenti esistenti nella preview, e che il bring-your-own-model non è attualmente supportato dal Copilot harness. Fonte Microsoft Learn.
ASP.NET Core / client C# / Web app
|
Identity + Authorization
|
Foundry project
/ \
Prompt Agent + Copilot harness Hosted Agent
loop/sandbox gestiti da Foundry framework/loop propri
| | |
skills MCP tools / approvals checkpoint applicativo
| | |
workspace per conversazione external systems
\_____________|_____________________________/
Audit, policy, idempotenza, eval
Per una prova con .NET, la documentazione Microsoft identifica esplicitamente i pacchetti preview Azure.AI.Projects.Agents e Azure.AI.Extensions.OpenAI alla versione 3.0.0-beta.5 nel percorso C#. L'API di creazione agente riportata nella guida usa MicrosoftCopilotHarness() e la feature preview indicata:
dotnet add package Azure.AI.Projects.Agents --version 3.0.0-beta.5
dotnet add package Azure.AI.Extensions.OpenAI --version 3.0.0-beta.5
#pragma warning disable AAIP001
using Azure.AI.Projects.Agents;
using Azure.Identity;
var endpoint = new Uri(Environment.GetEnvironmentVariable("FOUNDRY_PROJECT_ENDPOINT")!);
var model = Environment.GetEnvironmentVariable("FOUNDRY_MODEL_DEPLOYMENT")!;
var admin = new AgentAdministrationClient(
endpoint: endpoint,
tokenProvider: new DefaultAzureCredential());
ProjectsAgentDefinition definition = new DeclarativeAgentDefinition(model)
{
Instructions = "Produce a structured result; request approval for side effects.",
Harness = new MicrosoftCopilotHarness()
};
var created = admin.CreateAgentVersion(
"architecture-review-agent",
options: new(definition),
foundryFeatures: "MicrosoftCopilot=V1Preview");
Console.WriteLine($"{created.Name} / {created.Version}");
Il listato adatta l'esempio C# ufficiale; presuppone progetto, modello, permessi e preview disponibili nella regione scelta. Non sostituisce la configurazione di identity per un servizio di produzione; DefaultAzureCredential va legato a identità gestite, ruoli minimi e ambiente in cui il processo gira. Non è corretto esporre chiavi di servizio nel frontend. Fonte: istruzioni e snippet ufficiale Foundry C#.
Recovery non significa exactly-once: il test che un'architettura agentica deve superare
Per gli hosted agents, Microsoft indica che Foundry può rilevare un'interruzione e riavviare un'attività con l'input originario; il codice dell'applicazione deve salvare checkpoint e risultati intermedi per poter riprendere. Se un tool scrive su un sistema esterno, bisogna prevenire una seconda scrittura quando il processo riparte. Una conversazione salvata non equivale a un checkpoint transazionale. La semantica operativa descritta è quindi più vicina al retry con responsabilità applicativa sull'idempotenza che a un exactly-once distribuito. Fonte: Foundry, long-running resilience.
Analisi architetturale. Ogni tool con side effect dovrebbe ricevere una operation_id stabile derivata dal workflow, salvare lo stato in un datastore durabile, verificare se l'operazione è già stata eseguita e registrare esito e hash canonico della richiesta. Per email, acquisti, update GIS, scritture SQL o azioni MCP questo è più importante della formulazione del prompt. operation_id non deve diventare una stringa generata casualmente a ogni retry, altrimenti non deduplica nulla. Le autorizzazioni del tool rimangono indipendenti da quelle del modello; skill e prompt sono istruzioni, non confini di sicurezza.
Azure cost accounting: sandbox, modello e tool vanno fatturati su righe distinte
Il blog Microsoft dichiara che il costo di esercizio dell'harness scatterà il 1 dicembre 2026; fino a quel momento l'utilizzo del runtime harness è gratuito ma model inference e servizi/tool separatamente fatturati continuano a costare. La tariffa annunciata per il sandbox è USD 0,0994 per vCPU-ora + USD 0,0118 per GiB-ora, con possibili differenze per regione e contratto. Un esempio puramente aritmetico — 4 vCPU e 8 GiB mantenuti contabilmente per 720 ore — produce 720 × (4×0,0994 + 8×0,0118) = USD 354,24 di sole due componenti compute/memory. Non è una previsione di fattura né implica che una sessione venga fatturata per l'intero mese: scheduling, idle e unità di consumo effettive devono essere misurate. Fonte: pricing nell'annuncio Foundry del 28 ottobre.
Per una piattaforma con modelli open-weight sul proprio hardware o su GPU Azure, il costo ha una struttura diversa: VM GPU, dischi, networking, orchestrazione, capacità inattiva e personale operativo. La serie Azure NCads H100 v5 documenta configurazioni con una o due H100 NVL da 94 GB ciascuna, non una garanzia di disponibilità in ogni regione. Un modello ipotetico da 70 miliardi di parametri in BF16 richiede circa 140 GB decimali solo per i pesi (70e9 × 2 byte); una quantizzazione ideale a quattro bit ne richiede circa 35 GB decimali, prima di metadati, attivazioni, KV cache, riserva del framework e overhead del serving. Il fit di memoria non dimostra capacità di throughput o p99. Fonte SKU Azure, vLLM, struttura della KV cache e prefix caching.
Valutazione. Un confronto managed harness contro un orchestratore .NET su GPU propria è affidabile soltanto usando cost per accepted task e non solo dollari per token o dollari per ora GPU. Vanno inclusi timeout, retry, errori di tool, costi di licenza, tempo operativo e costo del controllo di qualità. In un'architettura ibrida il modello locale può occuparsi di classificazione e filtraggio a basso rischio, lasciando al modello hosted i task che giustificano il costo; la scelta va governata da eval su dati di dominio, non dal numero di parametri.
GPT-6.1 Terra: il costo per task comincia a contare più del prezzo per token
OpenAI ha documentato il rilascio di GPT-6.1 Terra il 26 ottobre 2026; l'identificatore API è gpt-6.1-terra. La comunicazione tecnica evidenzia attività con computer use e visual reasoning, insieme a una riduzione del prezzo rispetto ai modelli di confronto precedenti. I prezzi API standard annunciati sono USD 1 per milione di input token, USD 0,05 per milione di input cached, USD 5 per milione di output. Fonti: OpenAI, introduzione del modello, Model Release Notes, 26 ottobre.
Nel benchmark Terminal-Bench 4.0 riportato dal produttore, Terra risolve il 50,3% dei task al massimo effort, contro il 21,5% pubblicato per GPT-5.6 Terra. Il produttore riporta anche un miglioramento sul proprio set interno di prompt difficili. Sono metriche dichiarate dal fornitore e non un test indipendente sul software dell'organizzazione: non autorizzano inferenze sull'affidabilità di uno specifico agente che accede a CRM, GIS o DB. Fonte primaria: OpenAI.
Model routing ed economics: un esempio di costo che non confonde cache hit e qualità
Per un task ipotetico con 20.000 token input, di cui 16.000 effettivamente fatturati come cached, e 2.000 output, la sola componente token ai prezzi standard Terra vale:
input non cached: 4.000 × $1,00 / 1.000.000 = $0,0040
input cached: 16.000 × $0,05 / 1.000.000 = $0,0008
output: 2.000 × $5,00 / 1.000.000 = $0,0100
totale = $0,0148
Senza input cached, lo stesso conteggio teorico costerebbe $0,0300. Ma questo esempio presuppone che 16.000 token risultino davvero contabilizzati come cached: un prefisso simile non garantisce una cache hit, e non si possono trasferire acriticamente al modello hosted le regole del cache_salt documentate per vLLM. Il costo osservato deve provenire dai campi usage/billing reali e includere eventuali prezzi aggiuntivi dei tool. La qualità deve essere misurata con una metrica distinta:
C_accepted = (C_model + C_tools + C_retry + C_review) / N_task_accettati
Goodput_agent = N_task_accettati / tempo_totale
SLO = p95/p99 end-to-end, non il solo TTFT del modello.
Analisi architetturale. Un router di modelli ha almeno tre obiettivi in tensione: costo, tempo di completamento e probabilità di accettazione del risultato. Per richieste con effetti esterni servono anche un policy gate indipendente dal modello e il controllo umano dove previsto. Un modello più economico che fallisce spesso e richiede molte ripetizioni può essere più costoso di un modello superiore al primo tentativo. La comparazione va eseguita con lo stesso harness, stessi tool, stessa policy, stesso dataset e distribuzione identica delle difficoltà, altrimenti si attribuisce al modello ciò che è merito dell'orchestrazione.
Technical Takeaways
- Runtime Async non è un nuovo pattern C#: è una differente divisione del lavoro fra compilatore, runtime e JIT. Misurare le allocazioni e i percorsi di sospensione nel codice reale, senza trattare i microbenchmark come percentuali trasferibili.
- Il vero breaking change .NET può essere una CPU instruction baseline. Fare inventory dei guest e dei target di pubblicazione prima di modificare il runtime, specialmente in host virtualizzati o distribuiti.
- Similarity semantica ≠ prossimità geografica. Inserire esplicitamente confini di autorizzazione, filtro territoriale, versione degli embedding e validazione spatial-aware.
- Le Agent Skills trasferiscono convenzioni, non garanzie. In Experience Builder 1.21 le migrazioni a
mapComponentepnpmdevono entrare nella matrice automatica di compatibilità. - Managed harness e hosted agent hanno confini operativi differenti. Il recovery non sostituisce checkpoint, deduplicazione e controlli sui tool; in preview verificare regioni, modelli, SDK e assenza di SLA.
- Il KPI economico per gli agenti è il task accettato. Token price, cache discount e costo GPU sono solo componenti: tool, retry, audit e review determinano l'economia complessiva.
Lab della settimana
Lab 1 — Runtime Async A/B: due lowering nello stesso processo
Obiettivo. Misurare differenze di latenza e allocazioni fra compiler-lowered async e Runtime Async nello stesso processo .NET 11 RC2, evitando che due VM, due versioni di runtime o due scheduler interferiscano nel confronto. Il metodo segue l'esperimento pubblicato da Stephen Toub, che usa un attributo riconosciuto dal compilatore per forzare il lowering classico soltanto sui metodi di controllo. Nota: l'attributo impiegato da Toub è dichiaratamente sperimentale e non rappresenta un'API pubblica della BCL.
dotnet new console -n AsyncProbe -f net11.0
cd AsyncProbe
dotnet add package BenchmarkDotNet
Nel file .csproj aggiungere l'opt-in, mantenendo tutte le proprietà e il PackageReference esistente:
<PropertyGroup>
<Features>$(Features);runtime-async=on</Features>
</PropertyGroup>
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
BenchmarkRunner.Run<AsyncProbe>();
[MemoryDiagnoser]
public class AsyncProbe
{
private static readonly Task<int> Completed = Task.FromResult(42);
[Benchmark(Baseline = true)]
public Task<int> ClassicSync() => ClassicA();
[Benchmark]
public Task<int> RuntimeSync() => RuntimeA();
[System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)]
private static async Task<int> ClassicA() => await ClassicB();
[System.Runtime.CompilerServices.RuntimeAsyncMethodGeneration(false)]
private static async Task<int> ClassicB() => await Completed;
private static async Task<int> RuntimeA() => await RuntimeB();
private static async Task<int> RuntimeB() => await Completed;
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Method)]
internal sealed class RuntimeAsyncMethodGenerationAttribute(bool runtimeAsync)
: Attribute
{
public bool RuntimeAsync => runtimeAsync;
}
}
dotnet run -c Release -- --filter '*'
Il progetto usa intenzionalmente una superficie sperimentale del compilatore; se una SDK successiva ne modifica il contratto, utilizzare in alternativa due progetti identici che differiscono solo nella feature e verificare in IL il lowering. Ripetere con una seconda coppia di metodi che fa await Task.Yield() per distinguere completion sincrona e sospensione reale, come nell'articolo originale. Conservare dotnet --info, log BDN, parametri CPU, dimensioni assembly e numero di allocazioni. In un servizio reale la riduzione delle allocazioni va inoltre correlata a Gen0/Gen1, throughput e tail latency sotto carico, non soltanto al Mean del microbenchmark.
Lab 2 — Spatial versus semantic proximity con ArcGIS Pro 3.7
Obiettivo. Usare un dataset con embedding generati e due poligoni di query per confrontare un buffer geografico e una soglia cosine. In ArcGIS Pro 3.7 Advanced, usare il pannello interattivo per determinare la query e poi il batch Find Similar Features Using Embeddings su un'estensione più ampia. Il seguente comando ArcPy usa percorsi da sostituire con dati già disponibili; non genera embedding da zero:
import arcpy
embedding_features = r"C:\GIS\Lab.gdb\location_embeddings"
query_polygons = r"C:\GIS\Lab.gdb\query_areas"
output_features = r"C:\GIS\Lab.gdb\semantic_matches"
arcpy.geoai.FindSimilarFeaturesUsingEmbeddings(
embedding_features,
query_polygons,
output_features,
0.80
)
Confrontare i risultati con un filtro di distanza geodetica appropriato al sistema di coordinate e riportare precision@k, recall@k, overlap@k, oltre alla distanza geografica dei match. Il valore 0.80 è una soglia di laboratorio, non una soglia raccomandata universalmente: deve essere calibrata sul modello e sul dataset. Per i geodemographic embedding aggiungere un secondo esperimento con split territoriali a blocchi, ripetendo il training con e senza il segmento da 64 dimensioni più importante secondo SHAP. Documentazione: Funzionamento del batch, licenze, interpretazione SHAP dei segmenti.
Lab 3 — Agent Skills e harness: test di failure, non demo di prompting
Obiettivo. Preparare una suite A/B con stesso task, stesso modello, stessi strumenti, variando solo disponibilità dello skill Experience Builder. Il task proposto al lettore è un custom widget che reagisce alla selezione di feature e si ripulisce correttamente quando cambia la MapView. Richiedere l'implementazione compatibile con Developer Edition 1.21, eseguire pnpm ci e la build prevista dal progetto, quindi valutare: errori TypeScript, accessi residui a view.popup, riferimenti a viste non rilasciati, loop di selezione/filtro e diff non intenzionali. Fonte: skill ufficiale Esri, breaking changes 1.21.
Per chi dispone della preview Foundry in una regione supportata, affiancare un test di recovery degli hosted agents che simuli un riavvio dopo una scrittura su un servizio fittizio: il contatore degli effetti collaterali deve restare 1 dopo il retry, grazie a una operation_id persistente. Separare i risultati dello skill (qualità del codice) da quelli del harness (recovery e orchestrazione) e registrare il costo per task accettato. Documentazione: Microsoft Copilot harness, prerequisiti e C#, resilienza dei hosted agents.
Nessun commento:
Posta un commento