In questa sezione

Cos’è una capacità

Quando fai click destro su un file e il menu Transmute mostra cosa il file può diventare, ogni voce è raggiungibile attraverso una o più capacità: operazioni tipizzate che una cartuccia sa eseguire su un input tipizzato per produrre un output tipizzato.

Una capacità è un contratto, non un pulsante nel codice di MachineFabric. Specifica:

  • Cosa accetta: un media URN di input (per esempio media:document;ext=pdf, media:audio;ext=wav, media:fmt=json;llm-generation-request;record).
  • Cosa produce: un media URN di output (per esempio media:enc=utf-8;page, media:fmt=ndjson;llm-text-stream).
  • Come è denominata: un cap URN nella forma cap:in="media:X";<tags>;out="media:Y" che identifica l’operazione con precisione sufficiente perché il planner possa instradarvi.
  • Quali argomenti accetta: parametri opzionali estratti da stdin, posizioni CLI o flag.

CapDAG, il protocollo aperto su cui MachineFabric è costruito, definisce come le capacità vengono denominate, confrontate e instradate. Questa pagina copre cosa significano le capacità all’interno di MachineFabric: cosa mostra il menu Transmute, quali sono le capacità standard e cosa dichiarano le cartucce. Per i dettagli a livello di protocollo:

Come il menu Transmute raggiunge una capacità

Prima che il menu si apra, FabricLoom esegue questi passaggi:

  1. Legge il media type del file. Un PDF diventa media:document;ext=pdf, un WAV diventa media:audio;ext=wav, e così via.
  2. Il planner percorre il grafo delle capacità. Ogni cap che accetta direttamente quell’input, più ogni cap raggiungibile attraverso una o più cartucce concatenate, contribuisce con una possibile destinazione.
  3. Il menu mostra destinazioni, non passaggi, come “renderizza in immagine”, “trascrivi” e “riassumi”. Tu scegli la destinazione e il planner sceglie il percorso.
  4. Il percorso viene mostrato prima di essere eseguito. Per le pipeline a più passaggi appare il grafo, così puoi vedere il percorso prima che venga spostato alcun dato.
  5. Le cartucce vengono invocate in ordine. Ognuna gira nell’host di piattaforma (il servizio XPC su macOS o il daemon host su Linux e Windows), con l’avanzamento trasmesso live e i risultati archiviati nella libreria.

Quando la stessa destinazione è raggiungibile da più di un percorso, il ranking sceglie la corrispondenza più specifica. Un estrattore specifico per PDF batte uno generico per documenti, e un cap LLM che nomina un modello specifico batte uno generico.

Capacità standard

CapDAG include un piccolo insieme di cap standard su cui ogni cartuccia può fare affidamento. CAP_IDENTITY è obbligatoria, e le altre sono operazioni comuni per cui il registro fornisce helper.

Obbligatoria

Cap URN Scopo
cap:effect=none (CAP_IDENTITY) Passa l’input invariato. Ogni cartuccia deve dichiararla. Il runtime registra automaticamente un handler, quindi basta includerla nel manifest.

Standard (opzionali)

Cap Scopo
CAP_DISCARD Accetta qualsiasi input, produce media:void. Implementazione di default fornita.
CAP_ADAPTER_SELECTION Ispeziona il contenuto e restituisce i media URN che lo descrivono. Usata per la rilevazione del tipo di file.

LLM, embedding, modelli

L’SDK delle cartucce espone costanti URN e builder per i cap LLM, embedding e gestione modelli che MachineFabric instrada abitualmente:

  • Inferenza LLM: CAP_LLM_INFERENCE_GGUF, CAP_LLM_INFERENCE_MLX, CAP_LLM_INFERENCE_CANDLE, CAP_LLM_INFERENCE_CONSTRAINED
  • Introspezione LLM: CAP_LLM_VOCAB, CAP_LLM_MODEL_INFO
  • Embedding: CAP_GENERATE_EMBEDDINGS, CAP_EMBEDDINGS_DIMENSIONS
  • Visione: CAP_DESCRIBE_IMAGE
  • Modelli: download, list, status, contents, availability, path (builder URN nella libreria standard)

I media URN dei payload associati:

Media URN Trasporta
media:fmt=json;llm-generation-request;record Una LlmGenerationRequest: prompt, model spec, parametri di sampling, vincoli opzionali
media:fmt=ndjson;llm-text-stream Uno stream di LlmStreamMessage: token, status, completamento, richieste di tool, errori
media:fmt=json;llm-vocab-response;record Una LlmVocabResponse
media:fmt=json;llm-model-info;record Una LlmModelInfo

Le forme complete di request, stream, vocab e info sono nel Riferimento degli SDK per cartucce. La regola di dispatch che instrada una richiesta di generazione al backend giusto (GGUF, MLX o Candle) segue la stessa logica di ranking di ogni altra richiesta: il model_spec della richiesta più i tag determinano il candidato.

Cap per documenti e contenuti

I builder URN standard nella libreria CapDAG coprono le operazioni comuni sui documenti:

  • disbind_urn(input_media): scompone un documento in pagine con contenuto testuale
  • render_page_image_urn(input_media): renderizza le pagine di un documento come immagini
  • coercion_urn(source_type, target_type): coercizione di formato generica
  • format_conversion_urn(in_media, out_media): interconversione JSON / YAML / CSV
  • generate_json_urn(lang_code), make_decision_urn(lang_code), make_multiple_decisions_urn(lang_code): cap LLM con output strutturato

Per tutto il resto (estrazione personalizzata, sentiment tagging, OCR, traslitterazione), le cartucce definiscono i propri cap. L’URN deve essere analizzabile (secondo la sintassi URN CapDAG), e i media URN di input e output a cui fa riferimento devono esistere nel registro o essere proposti insieme alla cartuccia (Contribuire).

# Esempi di cap personalizzati validi
cap:in="media:enc=utf-8;sentiment-input";out="media:sentiment-tag;enc=utf-8";tag-sentiment
cap:in="media:ext=png;image";analyze;target=faces;out="media:fmt=json;record"
cap:in="media:audio;ext=wav;speech";ml-model;out="media:enc=utf-8;record;transcription";transcribe

Cosa dichiara una cartuccia

Le cartucce dichiarano le proprie capacità in un CapManifest restituito all’avvio. L’host legge il manifest al momento dell’installazione per registrare la cartuccia presso il router.

La forma minima in Python è riportata sotto. Il tutorial Costruisci la tua prima cartuccia costruisce questa cartuccia a partire dallo scaffold.

from capdag.bifaci.manifest import CapManifest, default_group
from capdag.cap.definition import Cap, CapArg, CapOutput, PositionSource, StdinSource
from capdag.standard.caps import CAP_IDENTITY
from capdag.urn.cap_urn import CapUrn, CapUrnBuilder

def build_manifest() -> CapManifest:
    tag_sentiment = Cap(
        urn=(
            CapUrnBuilder()
            .marker("tag-sentiment")
            .in_spec("media:enc=utf-8;sentiment-input")
            .out_spec("media:sentiment-tag;enc=utf-8")
            .build()
        ),
        title="Tag sentiment",
        aliases=["tag-sentiment"],
    )
    tag_sentiment.args = [
        CapArg(
            media_urn="media:enc=utf-8;sentiment-input",
            required=True,
            sources=[
                StdinSource("media:enc=utf-8;sentiment-input"),
                PositionSource(0),
            ],
            arg_description="UTF-8 text to classify.",
        )
    ]
    tag_sentiment.output = CapOutput(
        media_urn="media:sentiment-tag;enc=utf-8",
        output_description="One of 'positive', 'neutral', 'negative'.",
    )

    identity = Cap(
        urn=CapUrn.from_string(CAP_IDENTITY),
        title="Identity",
        aliases=["identity"],
    )

    return CapManifest(
        name="sentiment-tagger",
        version="0.1.0",
        channel="nightly",
        registry_url=None,
        description="Classify text as positive, neutral, or negative.",
        cap_groups=[default_group([identity, tag_sentiment])],
    )

L’host applica queste regole:

  • CAP_IDENTITY è obbligatoria. Il manifest di ogni cartuccia deve elencarla. Il runtime Python registra automaticamente un handler, quindi basta dichiarare la cap.
  • channel e registry_url sono fissati al momento della compilazione. Devono concordare con la configurazione di compile-time del motore e con il record di installazione su disco (cartridge.json). Una discrepanza viene rifiutata al momento della discovery.
  • I cap_groups sono unità atomiche di registrazione. Un gruppo riesce o fallisce nel suo insieme, il che mantiene consistenti le cap correlate.

Costruisci un cap URN con l’API del builder (CapUrnBuilder().marker().in_spec().out_spec().build()) e non con una stringa scritta a mano. Il runtime canonicalizza i tag in ordine alfabetico, quindi una stringa URN scritta a mano quasi certamente non corrisponderà alla forma canonica. Vedi il tutorial Costruisci la tua prima cartuccia per il pattern che costruisce l’URN una volta e ne conserva la stringa.

Routing in pratica

Quando MachineFabric ha bisogno di una capacità:

  1. Costruisce una richiesta, ovvero un cap URN che descrive cosa serve.
  2. Il router esegue il predicato di dispatch contro ogni candidato registrato e raccoglie quelli idonei.
  3. Tra i candidati idonei, il ranking sceglie il più specifico.
  4. La cartuccia selezionata viene avviata se non è già in esecuzione, la richiesta viene inviata sul protocollo Bifaci (il protocollo binario a frame di CapDAG tra host e cartuccia) e la risposta viene restituita in streaming.
  5. Per le richieste multi-step, il planner trova il percorso attraverso il grafo delle capacità e l’executor esegue ogni passaggio in ordine, in parallelo dove il grafo lo consente.

Se due candidati corrispondono con uguale specificità, vince il primo registrato. Una cartuccia specializzata per un tipo di file specifico sovrascrive quindi in modo affidabile una più generale per quel tipo, mentre la cartuccia generale resta disponibile per tutto il resto.