Llama Stack: framework pro tvorbu aplikací s generativní AI (2. část)

2. 10. 2025
Doba čtení: 34 minut

Sdílet

Humanoidní roboti pracují u počítače
Autor: Root.cz s využitím Zoner AI
Ukážeme si některé další možnosti použití Llama Stacku, a to (opět) v oblasti velkých jazykových modelů. Například bude popsáno, jak může systém získávat informace z vektorizovaných dokumentů (znalostní databáze).

Obsah

1. Llama Stack: framework pro tvorbu aplikací s generativní AI (2. část)

2. Základní konfigurace Llama Stacku

3. Spuštění Llama Stacku v režimu serveru

4. Komunikace s LLM přes Llama Stack

5. Nové rozhraní pro komunikaci s LLM

6. Složitější konfigurace Llama Stacku

7. Výpis všech dostupných API

8. Poskytovatelé (providers)

9. Výpis všech dostupných poskytovatelů

10. Přidání závislostí do projektového souboru a úprava konfiguračního souboru Llama Stacku

11. Pomocné tabulky vytvářené a používané při běhu Llama Stacku

12. Příklad: úložiště používané poskytovatelem meta-reference

13. Složitější příklad klienta pro Llama Stack: získávání informací v zadaných dokumentech

14. Vektorizace dokumentu

15. Provedení dotazu se získáním informací z dokumentu

16. Úplný zdrojový kód klienta, který bude odpovídat na základě dokumentů určených k prohledávání

17. Výsledky dotazů s doplněním informací získaných z předaného dokumentu

18. Vrácení části zdrojového kódu na základě položeného dotazu

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Llama Stack: framework pro tvorbu aplikací s generativní AI (2. část)

Na úvodní článek o frameworku Llama Stack dnes navážeme. Ukážeme si některé další možnosti jeho použití, a to (opět) v oblasti velkých jazykových modelů. Všechny demonstrační příklady uvedené v navazujících kapitolách, které volají Llama Stack běžící ve vlastním procesu (viz další text) jsou naprogramovány v Pythonu a využívají projektový soubor pyproject.toml, jenž obsahuje pouze jedinou závislost, a to konkrétně závislost na balíčku llama-stack-client verze 0.2.20 až 0.2.23 (i když první z těchto příkladů poběží i s tak starou verzí, jako je 0.2.8:

[project]
name = "llama-stack-demo"
version = "0.1.0"
description = "Simple Llama Stack demo"
authors = [
    {name = "Pavel Tisnovsky", email = "ptisnovs@redhat.com"},
]
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
    "llama-stack-client>=0.2.20",
]

Pokud má být Llama Stack spuštěn v režimu knihovny, bude konfigurace projektu nepatrně složitější, protože budeme muset přidat další přímé závislosti. Pro jednoduchého klienta, který pouze zavolá vybraný LLM (například gpt-4-turbo) budou postačovat následující závislosti:

[project]
name = "llama-stack-demo"
version = "0.1.0"
description = "Simple Llama Stack demo"
authors = [
    {name = "Pavel Tisnovsky", email = "ptisnovs@redhat.com"},
]
dependencies = [
    "llama-stack==0.2.23",
    "fastapi>=0.115.12",
    "opentelemetry-sdk>=1.34.0",
    "opentelemetry-exporter-otlp>=1.34.0",
    "opentelemetry-instrumentation>=0.55b0",
    "aiosqlite>=0.21.0",
    "litellm>=1.72.1",
    "uvicorn>=0.34.3",
    "blobfile>=3.0.0"
]
requires-python = "==3.12.*"
readme = "README.md"
license = {text = "MIT"}
 
 
[tool.pdm]
distribution = false

2. Základní konfigurace Llama Stacku

V úvodním článku jsme si kromě dalších informací uvedli i minimální (ale stále plně funkční) konfiguraci Llama Stacku. Tato konfigurace by měla být uložena v souboru s názvem run.yaml vypadá následovně:

version: '2'
image_name: simplest-llama-stack-configuration
container_image: null
 
distribution_spec:
  local:
    services:
      - inference
      - telemetry
 
apis:
  - inference
  - telemetry
 
providers:
  inference:
    - provider_id: openai
      provider_type: remote::openai
      config:
        api_key: ${env.OPENAI_API_KEY}
  telemetry:
    - provider_id: meta-reference
      provider_type: inline::meta-reference
      config:
        sinks: ['console']
 
models:
  - model_id: gpt-4-turbo
    provider_id: openai
    model_type: llm
    provider_model_id: gpt-4-turbo
 
server:
  port: 8321

Důležité je, že je nakonfigurován LLM server, který se má volat (v tomto kontextu se setkáme s pojmem poskytovatel a v tomto případě se jedná o společnosti OpenAI). Tuto konfiguraci nalezneme v sekci providers, protože LLM servery jsou z pohledu Llama Stacku skutečně považovány za jeden (z mnoha typů) poskytovatelů:

providers:
  inference:
    - provider_id: openai
      provider_type: remote::openai
      config:
        api_key: ${env.OPENAI_API_KEY}

Druhým nakonfigurovaným poskytovatelem je poskytovatel telemetrie. Současná verze Llama Stacku vyžaduje, aby byl nakonfigurován, i když telemetrii nepoužijete.

To však není postačující, protože kromě LLM serveru je nutné nakonfigurovat i model, který bude volán. Poskytovatel OpenAI nabízí relativně velké množství LLM modelů, mezi než patří i gpt-4-turbo. Konfigurace tohoto modelu je uvedena v samostatné sekci models a vypadá následovně:

models:
  - model_id: gpt-4-turbo
    provider_id: openai
    model_type: llm
    provider_model_id: gpt-4-turbo

Tato konfigurace předpokládá, že ještě před vlastním spuštěním serveru dojde k nastavení klíče pro OpenAI do proměnné prostředí nazvané OPENAI_API_KEY. Toto nastavení bude vypadat následovně:

$ export OPENAI_API_KEY="sk-xyzzy1234567890xyzzy1234567890xyzzy1234567890..."
Poznámka: v sekci server je uvedeno, že Llama Stack po svém spuštění bude dostupný na portu číslo 8321. Přes tento port budeme k běžícímu Llama Stacku přistupovat.

3. Spuštění Llama Stacku v režimu serveru

V adresáři, ve kterém je uložen projektový soubor pyproject.toml i konfigurační soubor run.yaml zmíněný v předchozí kapitole, spustíme Llama Stack v režimu serveru. Pro tento účel je možné použít například nástroj PDM nebo uv (oba tyto nástroje provádí shodnou činnost, ovšem uv je značně rychlejší). Při použití PDM vypadá spuštění Llama Stacku následovně:

$ pdm run llama stack run run.yaml

Naopak při použití nástroje uv se změní použitý příkaz (ovšem jeho parametry zůstanou stejné):

$ uv run llama stack run run.yaml

Llama Stack by měl po svém spuštění vypsat aktuální konfiguraci načtenou ze souboru run.yaml, a na konci taktéž port, na které běží:

INFO     2025-09-27 16:28:11,355 llama_stack.cli.stack.run:125 server: Using run configuration: run.yaml
INFO     2025-09-27 16:28:11,362 llama_stack.cli.stack.run:146 server: No image type or image name provided. Assuming
         environment packages.
INFO     2025-09-27 16:28:11,924 llama_stack.distribution.server.server:422 server: Using config file: run.yaml
INFO     2025-09-27 16:28:11,925 llama_stack.distribution.server.server:424 server: Run configuration:
INFO     2025-09-27 16:28:11,928 llama_stack.distribution.server.server:426 server: apis:
         - inference
         - telemetry
         benchmarks: []
         container_image: null
         datasets: []
         external_providers_dir: null
         image_name: simplest-llama-stack-configuration
         inference_store: null
         logging: null
         metadata_store: null
         models:
         - metadata: {}
           model_id: gpt-4-turbo
           model_type: !!python/object/apply:llama_stack.apis.models.models.ModelType
           - llm
           provider_id: openai
           provider_model_id: gpt-4-turbo
         providers:
           inference:
           - config:
               api_key: '********'
             provider_id: openai
             provider_type: remote::openai
           telemetry:
           - config:
               sinks:
               - console
             provider_id: meta-reference
             provider_type: inline::meta-reference
         scoring_fns: []
         server:
           auth: null
           host: null
           port: 8321
           quota: null
           tls_cafile: null
           tls_certfile: null
           tls_keyfile: null
         shields: []
         tool_groups: []
         vector_dbs: []
         version: '2'
 
INFO     2025-09-27 16:28:13,560 llama_stack.distribution.server.server:564 server: Listening on ['::', '0.0.0.0']:8321
INFO     2025-09-27 16:28:13,568 llama_stack.distribution.server.server:156 server: Starting up

Pro jistotu si přímo z příkazové řádky (pochopitelně z jiného terminálu) ověříme, že Llama Stack skutečně běží na portu 8321 a současně má nakonfigurován LLM model gpt-4-turbo nabízený OpenAI (provider_id):

$ curl localhost:8321/v1/models | jq .
 
{
  "data": [
    {
      "identifier": "gpt-4-turbo",
      "provider_resource_id": "gpt-4-turbo",
      "provider_id": "openai",
      "type": "model",
      "metadata": {},
      "model_type": "llm"
    }
  ]
}

Novější verze Llama Stacku vrátí všechny nabízené modely, nikoli pouze model nakonfigurovaný (pozor – podobných nekompatibilit nalezneme celou řadu!):

{
  "data": [
    {
      "identifier": "gpt-4-turbo",
      "provider_resource_id": "gpt-4-turbo",
      "provider_id": "openai",
      "type": "model",
      "metadata": {},
      "model_type": "llm"
    },
    {
      "identifier": "openai/gpt-4-turbo",
      "provider_resource_id": "gpt-4-turbo",
      "provider_id": "openai",
      "type": "model",
      "metadata": {},
      "model_type": "llm"
    },
    {
      "identifier": "openai/gpt-3.5-turbo-0125",
      "provider_resource_id": "gpt-3.5-turbo-0125",
      "provider_id": "openai",
      "type": "model",
      "metadata": {},
      "model_type": "llm"
    },
    {
      "identifier": "openai/gpt-3.5-turbo",
      "provider_resource_id": "gpt-3.5-turbo",
      "provider_id": "openai",
      "type": "model",
      "metadata": {},
      "model_type": "llm"
    },
    {
      "identifier": "openai/gpt-3.5-turbo-instruct",
      "provider_resource_id": "gpt-3.5-turbo-instruct",
      "provider_id": "openai",
      "type": "model",
      "metadata": {},
      "model_type": "llm"
    },
    {
      "identifier": "openai/gpt-4",
      "provider_resource_id": "gpt-4",
      "provider_id": "openai",
      "type": "model",
      "metadata": {},
      "model_type": "llm"
    },
    {
      "identifier": "openai/gpt-4o",
      "provider_resource_id": "gpt-4o",
      "provider_id": "openai",
      "type": "model",
      "metadata": {},
      "model_type": "llm"
    },
    {
      "identifier": "openai/gpt-4o-2024-08-06",
      "provider_resource_id": "gpt-4o-2024-08-06",
      "provider_id": "openai",
      "type": "model",
      "metadata": {},
      "model_type": "llm"
    },
    {
      "identifier": "openai/gpt-4o-mini",
      "provider_resource_id": "gpt-4o-mini",
      "provider_id": "openai",
      "type": "model",
      "metadata": {},
      "model_type": "llm"
    },
    {
      "identifier": "openai/gpt-4o-audio-preview",
      "provider_resource_id": "gpt-4o-audio-preview",
      "provider_id": "openai",
      "type": "model",
      "metadata": {},
      "model_type": "llm"
    },
    {
      "identifier": "openai/chatgpt-4o-latest",
      "provider_resource_id": "chatgpt-4o-latest",
      "provider_id": "openai",
      "type": "model",
      "metadata": {},
      "model_type": "llm"
    },

4. Komunikace s LLM přes Llama Stack

Připomeňme si ještě, jak vypadá program (skript) naprogramovaný v Pythonu, který přes Llama Stack zavolá LLM (nakonfigurovaný v souboru run.yaml), předá zvolenému jazykovému modelu otázku a nakonec zobrazí jeho odpověď:

from llama_stack_client import LlamaStackClient
 
PROMPT = "Say Hello in Czech"
 
client = LlamaStackClient(base_url="http://localhost:8321")
 
print(f"Using Llama Stack version {client._version}")
 
response = client.inference.chat_completion(
    messages=[{"role": "user", "content": PROMPT}],
    model_id=client.models.list()[0].identifier,
)
 
text = response.completion_message.content
print(f"LLM response: {text}")

Spuštění tohoto skriptu se opět provede přes nástroje PDM nebo uv:

$ pdm run client1.py

Alternativně:

$ uv run client1.py

Po spuštění skriptu se zobrazí informace o verzi Llama Stacku, dále informace o tom, které koncové body Llama Stacku se volají, následuje varování o použití staršího API (viz další kapitolu) a posléze se již zobrazí odpověď získaná z LLM:

Using Llama Stack version 0.2.23
INFO:httpx:HTTP Request: GET http://localhost:8321/v1/models "HTTP/1.1 200 OK"
/tmp/ramdisk/yyyy/client1.py:9: DeprecationWarning: /v1/inference/chat-completion is deprecated. Please use /v1/openai/v1/chat/completions.
  response = client.inference.chat_completion(
INFO:httpx:HTTP Request: POST http://localhost:8321/v1/inference/chat-completion "HTTP/1.1 200 OK"
LLM response: Hello in Czech is "Ahoj" for informal situations or "Dobrý den" for more formal occasions.

5. Nové rozhraní pro komunikaci s LLM

Skript uvedený z předchozí kapitole je sice funkční, ovšem vypisuje varování o tom, že se volá nepodporovaný REST API endpoint (sice nepřímo, ale je tomu tak). Llama Stack se totiž poměrně rychle vyvíjí a proto je nutné v aplikacích, které ho využívají, provádět mnohdy i poměrně razantní změny (což je na tak mladý projekt dosti nepříjemné).

Úprava skriptu tak, aby používal novější (snad již stabilní) REST API endpoint, by mohla vypadat následovně:

from llama_stack_client import LlamaStackClient
 
client = LlamaStackClient(base_url="http://localhost:8321")
 
print(f"Using Llama Stack version {client._version}")
 
models = client.models.list()
model_id = models[0].identifier
 
print(f"Using model {model_id}")
 
response = client.chat.completions.create(
    model=model_id,
    messages=[{"role": "user", "content": "What is the capital of France?"}]
)
 
print(response.to_json())

Aby bylo zřejmé, že odpověď LLM serveru obsahuje i mnohé další (meta)informace, necháme si celou odpověď zobrazit ve formátu JSON. Samotná informace o hlavním městě Francie je zvýrazněna:

{
  "id": "chatcmpl-CJPFSGyinwPahGe7s2y2FWtI9fqAZ",
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "The capital of France is Paris.",
        "tool_calls": null,
        "refusal": null,
        "annotations": [],
        "audio": null,
        "function_call": null
      },
      "logprobs": null
    }
  ],
  "created": 1758741322,
  "model": "gpt-4-turbo-2024-04-09",
  "object": "chat.completion",
  "service_tier": "default",
  "system_fingerprint": "fp_de235176ee",
  "usage": {
    "completion_tokens": 7,
    "prompt_tokens": 14,
    "total_tokens": 21,
    "completion_tokens_details": {
      "accepted_prediction_tokens": 0,
      "audio_tokens": 0,
      "reasoning_tokens": 0,
      "rejected_prediction_tokens": 0
    },
    "prompt_tokens_details": {
      "audio_tokens": 0,
      "cached_tokens": 0
    }
  },
  "metrics": [
    {
      "trace_id": "494b4862ce1339456957d19b46224579",
      "span_id": "664de9d2c854e534",
      "timestamp": "2025-09-24T19:15:23.602894Z",
      "attributes": {
        "model_id": "openai/gpt-4-turbo",
        "provider_id": "openai"
      },
      "type": "metric",
      "metric": "prompt_tokens",
      "value": 14,
      "unit": "tokens"
    },
    {
      "trace_id": "494b4862ce1339456957d19b46224579",
      "span_id": "664de9d2c854e534",
      "timestamp": "2025-09-24T19:15:23.602943Z",
      "attributes": {
        "model_id": "openai/gpt-4-turbo",
        "provider_id": "openai"
      },
      "type": "metric",
      "metric": "completion_tokens",
      "value": 7,
      "unit": "tokens"
    },
    {
      "trace_id": "494b4862ce1339456957d19b46224579",
      "span_id": "664de9d2c854e534",
      "timestamp": "2025-09-24T19:15:23.602961Z",
      "attributes": {
        "model_id": "openai/gpt-4-turbo",
        "provider_id": "openai"
      },
      "type": "metric",
      "metric": "total_tokens",
      "value": 21,
      "unit": "tokens"
    }
  ]
}

6. Složitější konfigurace Llama Stacku

Samotná konfigurace Llama Stacku, která byla ukázána ve druhé kapitole, je pochopitelně modifikovatelná a rozšiřitelná. Změna či rozšíření konfigurace se týká dvou hlavních oblastí: API (lze povolit či zakázat jednotlivé skupiny API Llama Stacku) a takzvaných poskytovatelů (providers). V následujících kapitolách si alespoň ve stručnosti ukážeme, jak může taková konfigurace vypadat.

Poznámka: na tomto místě je vhodné upozornit na to, že samotná dokumentace Llama Stacku je (prozatím) neúplná a zejména informace o dostupných poskytovatelích by mohla být mnohem lepší a přehlednější.

7. Výpis všech dostupných API

Ve druhé kapitole jsme povolili pouze dvě skupiny API:

apis:
  - inference
  - telemetry

Ve skutečnosti je možné pracovat s více skupinami API. O které skupiny se jedná, lze zjistit na příkazové řádce zadáním příkazu:

$ uv run llama stack list-apis

nebo:

$ pdm run llama stack list-apis

Výsledný seznam dostupných API bude v Llama Stacku verze 0.2.22 vypadat následovně:

┏━━━━━━━━━━━━━━━━━━━┓
┃ API               ┃
┡━━━━━━━━━━━━━━━━━━━┩
│ providers         │
├───────────────────┤
│ inference         │
├───────────────────┤
│ safety            │
├───────────────────┤
│ agents            │
├───────────────────┤
│ batches           │
├───────────────────┤
│ vector_io         │
├───────────────────┤
│ datasetio         │
├───────────────────┤
│ scoring           │
├───────────────────┤
│ eval              │
├───────────────────┤
│ post_training     │
├───────────────────┤
│ tool_runtime      │
├───────────────────┤
│ telemetry         │
├───────────────────┤
│ models            │
├───────────────────┤
│ shields           │
├───────────────────┤
│ vector_dbs        │
├───────────────────┤
│ datasets          │
├───────────────────┤
│ scoring_functions │
├───────────────────┤
│ benchmarks        │
├───────────────────┤
│ tool_groups       │
├───────────────────┤
│ files             │
├───────────────────┤
│ prompts           │
├───────────────────┤
│ inspect           │
└───────────────────┘
Poznámka: v navazujících kapitolách využijeme pouze některé z těchto API.

8. Poskytovatelé (providers)

V praxi je mnohdy nutné kromě LLM serveru přímo či nepřímo používat i další poskytovatele (providers). Těch existuje celá řada a dělí se do několika skupin:

Označení Stručný popis
Agents interakce se systémem agentů (samotní agenti mohou provádět různé operace)
Inference rozhraní k LLM modelům i k embedding modelům
VectorIO původně rozhraní k vektorovým databázím (hledání podobných vektorů), nyní i fulltext hledání
Safety detekce dotazů s nevhodným či nepovoleným obsahem apod.
Telemetry telemetrie (OpenTelemetry ale i další)
Eval vyhodnocení odpovědí LLM modelů atd. (způsoby použití se různí)
DatasetIO čtení a zápisy datových sad z/do zvoleného systému (může být i lokální souborový systém)

9. Výpis všech dostupných poskytovatelů

Podobně jako dokáže Llama Stack vypsat seznam dostupných API, může vypsat i dostupné poskytovatele. Postačuje použít příkaz:

$ uv run llama stack list-providers

nebo:

$ pdm run llama stack list-providers

Opět by se měla zobrazit tabulka, ve které je u každého poskytovatele vypsána jak jeho skupina (například VectorIO), tak i vyžadované závislosti:

┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ API Type      ┃ Provider Type                  ┃ PIP Package Dependencies                               ┃
┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ batches       │ inline::reference              │ openai                                                 │
├───────────────┼────────────────────────────────┼────────────────────────────────────────────────────────┤
│ datasetio     │ inline::localfs                │ pandas                                                 │
├───────────────┼────────────────────────────────┼────────────────────────────────────────────────────────┤
│ datasetio     │ remote::huggingface            │ datasets                                               │
├───────────────┼────────────────────────────────┼────────────────────────────────────────────────────────┤
│ datasetio     │ remote::nvidia                 │ datasets                                               │
├───────────────┼────────────────────────────────┼────────────────────────────────────────────────────────┤
│ eval          │ inline::meta-reference         │ tree_sitter,pythainlp,langdetect,emoji,nltk            │
├───────────────┼────────────────────────────────┼────────────────────────────────────────────────────────┤
│ eval          │ remote::nvidia                 │ requests                                               │
├───────────────┼────────────────────────────────┼────────────────────────────────────────────────────────┤
│ files         │ inline::localfs                │ sqlalchemy,aiosqlite,asyncpg                           │
├───────────────┼────────────────────────────────┼────────────────────────────────────────────────────────┤
│ files         │ remote::s3                     │ boto3,sqlalchemy,aiosqlite,asyncpg                     │
├───────────────┼────────────────────────────────┼────────────────────────────────────────────────────────┤
│ inference     │ inline::meta-reference         │ accelerate,fairscale,torch,torchvision,transformers,z… │
├───────────────┼────────────────────────────────┼────────────────────────────────────────────────────────┤
│ inference     │ remote::anthropic              │ litellm                                                │
├───────────────┼────────────────────────────────┼────────────────────────────────────────────────────────┤
│ inference     │ remote::bedrock                │ boto3                                                  │
├───────────────┼────────────────────────────────┼────────────────────────────────────────────────────────┤
Poznámka: tabulka je zkrácena, protože její celková velikost v poslední oficiální verzi Llama Stacku (0.2.23) přesahuje třicet kilobajtů.

10. Přidání závislostí do projektového souboru a úprava konfiguračního souboru Llama Stacku

Abychom mohli do Llama Stacku zaregistrovat další poskytovatele, je nutné do projektového souboru používaného pro spuštění Llama Stacku přidat všechny potřebné závislosti. Ty se přidávají buď ručně nebo příkazem uv add balíček popř. pdm add balíček. Pro ukázku přidáme následující závislosti:

blobfile>=3.0.0
datasets>=3.6.0
sqlalchemy>=2.0.41
faiss-cpu>=1.11.0
mcp>=1.9.4
autoevals>=0.0.129
psutil>=7.0.0
torch>=2.7.1
peft>=0.15.2
trl>=0.18.2

Výsledný obsah projektového souboru pyproject.toml může vypadat následovně:

[project]
name = "llama-stack-demo"
version = "0.1.0"
description = "Default template for PDM package"
authors = [
    {name = "Pavel Tisnovsky", email = "ptisnovs@redhat.com"},
]
dependencies = [
    "llama-stack==0.2.14",
    "fastapi>=0.115.12",
    "opentelemetry-sdk>=1.34.0",
    "opentelemetry-exporter-otlp>=1.34.0",
    "opentelemetry-instrumentation>=0.55b0",
    "aiosqlite>=0.21.0",
    "litellm>=1.72.1",
    "uvicorn>=0.34.3",
    "blobfile>=3.0.0",
    "datasets>=3.6.0",
    "sqlalchemy>=2.0.41",
    "faiss-cpu>=1.11.0",
    "mcp>=1.9.4",
    "autoevals>=0.0.129",
    "psutil>=7.0.0",
    "torch>=2.7.1",
    "peft>=0.15.2",
    "trl>=0.18.2"]
requires-python = "==3.12.*"
readme = "README.md"
license = {text = "MIT"}
 
 
[tool.pdm]
distribution = false

Nyní již můžeme rozšířit i konfiguraci Llama Stacku, a to konkrétně do této podoby:

version: '2'
image_name: minimal-viable-llama-stack-configuration
 
apis:
  - agents
  - datasetio
  - eval
  - inference
  - post_training
  - safety
  - scoring
  - telemetry
  - tool_runtime
  - vector_io
benchmarks: []
container_image: null
datasets: []
external_providers_dir: null
inference_store:
  db_path: .llama/distributions/ollama/inference_store.db
  type: sqlite
logging: null
metadata_store:
  db_path: .llama/distributions/ollama/registry.db
  namespace: null
  type: sqlite
providers:
  agents:
  - config:
      persistence_store:
        db_path: .llama/distributions/ollama/agents_store.db
        namespace: null
        type: sqlite
      responses_store:
        db_path: .llama/distributions/ollama/responses_store.db
        type: sqlite
    provider_id: meta-reference
    provider_type: inline::meta-reference
  datasetio:
  - config:
      kvstore:
        db_path: .llama/distributions/ollama/huggingface_datasetio.db
        namespace: null
        type: sqlite
    provider_id: huggingface
    provider_type: remote::huggingface
  - config:
      kvstore:
        db_path: .llama/distributions/ollama/localfs_datasetio.db
        namespace: null
        type: sqlite
    provider_id: localfs
    provider_type: inline::localfs
  eval:
  - config:
      kvstore:
        db_path: .llama/distributions/ollama/meta_reference_eval.db
        namespace: null
        type: sqlite
    provider_id: meta-reference
    provider_type: inline::meta-reference
  inference:
    - provider_id: openai
      provider_type: remote::openai
      config:
        api_key: ${env.OPENAI_API_KEY}
  post_training:
  - config:
      checkpoint_format: huggingface
      device: cpu
      distributed_backend: null
    provider_id: huggingface
    provider_type: inline::huggingface
  safety:
  - config:
      excluded_categories: []
    provider_id: llama-guard
    provider_type: inline::llama-guard
  scoring:
  - config: {}
    provider_id: basic
    provider_type: inline::basic
  - config: {}
    provider_id: llm-as-judge
    provider_type: inline::llm-as-judge
  - config:
      openai_api_key: '********'
    provider_id: braintrust
    provider_type: inline::braintrust
  telemetry:
  - config:
      service_name: ''
      sinks: sqlite
      sqlite_db_path: .llama/distributions/ollama/trace_store.db
    provider_id: meta-reference
    provider_type: inline::meta-reference
  tool_runtime:
    - provider_id: model-context-protocol
      provider_type: remote::model-context-protocol
      config: {}
  vector_io:
  - config:
      kvstore:
        db_path: .llama/distributions/ollama/faiss_store.db
        namespace: null
        type: sqlite
    provider_id: faiss
    provider_type: inline::faiss
scoring_fns: []
server:
  auth: null
  host: null
  port: 8321
  quota: null
  tls_cafile: null
  tls_certfile: null
  tls_keyfile: null
shields: []
vector_dbs: []
 
models:
  - model_id: gpt-4-turbo
    provider_id: openai
    model_type: llm
    provider_model_id: gpt-4-turbo

Jednotlivé části tohoto konfiguračního souboru mají následující význam:

Sekce Stručný popis
apis povolená API Llama Stacku, která lze volat z klientů
inference_store databáze dotazů a odpovědí LLM serverů
metadata_store různé informace o modelech atd.
providers konfigurace jednotlivých poskytovatelů podle skupin (my jich zde máme celou řadu)
server již jsme používali – nastavení samotného Llama Stack serveru (port, TLS atd.)
shields popíšeme si příště
vector_dbs popíšeme si později
models konfigurace jednotlivých modelů (typicky LLM modelů atd.)

11. Pomocné tabulky vytvářené a používané při běhu Llama Stacku

V konfiguračním souboru run.yaml vypsaného v desáté kapitole je hned u několika poskytovatelů nastavena cesta k souborům databáze SQLite. Příkladem je následující část konfigurace:

  - config:
      service_name: ''
      sinks: sqlite
      sqlite_db_path: .llama/distributions/ollama/trace_store.db
    provider_id: meta-reference
    provider_type: inline::meta-reference

V praxi lze mnohdy použít i jiné databáze a pochopitelně i cesta může být odlišná (v článku jsme se snažil zachovat cesty tak, aby to odpovídalo dokumentaci Llama Stacku, i když pojmenování ollama může být zavádějící).

Nicméně se vraťme k naší konfiguraci. Po spuštění Llama Stacku a provedení dotazu klienta na LLM server by se na uvedené cestě .llama/distributions/ollama měly objevit následující soubory:

agents_store.db
faiss_store.db
files_metadata.db
huggingface_datasetio.db
inference_store.db
localfs_datasetio.db
meta_reference_eval.db
registry.db
responses_store.db
trace_store.db

Tyto soubory jsou spravovány samotným Llama Stackem a jeho poskytovateli, takže s nimi (většinou) není zapotřebí nijak manipulovat.

12. Příklad: úložiště používané poskytovatelem meta-reference

V případě poskytovatele meta-reference lze zvolit i další typy úložišť. Kromě zde zmíněného SQLite lze nakonfigurovat uložení informací do Redisu, PostgreSQL či do MongoDB. Podobné volby jsou většinou dostupné i pro konfiguraci úložišť dalších poskytovatelů. Nicméně my jsme jako úložiště nakonfigurovali SQLite, takže se pokusme prozkoumat, jaké informace jsou zde vlastně uloženy.

Připojíme se k databázi agents_store.db:

$ sqlite3 agents_store.db
 
SQLite version 3.45.1 2024-01-30 16:01:20
Enter ".help" for usage hints.

Zjistíme, jaké tabulky jsou zde uloženy a jakou mají strukturu:

sqlite> .tables
kvstore
 
sqlite> PRAGMA table_info(kvstore);
0|key|TEXT|0||1
1|value|TEXT|0||0
2|expiration|TIMESTAMP|0||0

Kolik záznamů je zde uloženo? (platí pro konverzaci s LLM se dvěma otázkami a dvěma odpověďmi):

sqlite> select key from kvstore;
agent:18dc140f-bc78-496a-8cd2-d37a518ee56f
num_infer_iters_in_turn:18dc140f-bc78-496a-8cd2-d37a518ee56f:0171d680-8dcf-4c80-b612-2a0ee40e1a33:e6c3bccc-3174-4ea1-ad9e-227944bfed87
num_infer_iters_in_turn:18dc140f-bc78-496a-8cd2-d37a518ee56f:0171d680-8dcf-4c80-b612-2a0ee40e1a33:f7342a56-bc63-47d3-bf2b-f4946ad34285
session:18dc140f-bc78-496a-8cd2-d37a518ee56f:0171d680-8dcf-4c80-b612-2a0ee40e1a33
session:18dc140f-bc78-496a-8cd2-d37a518ee56f:0171d680-8dcf-4c80-b612-2a0ee40e1a33:e6c3bccc-3174-4ea1-ad9e-227944bfed87
session:18dc140f-bc78-496a-8cd2-d37a518ee56f:0171d680-8dcf-4c80-b612-2a0ee40e1a33:f7342a56-bc63-47d3-bf2b-f4946ad34285

Jak vypadají uložená data?

sqlite> select value from kvstore where key='session:18dc140f-bc78-496a-8cd2-d37a518ee56f:0171d680-8dcf-4c80-b612-2a0ee40e1a33';
{"session_id":"0171d680-8dcf-4c80-b612-2a0ee40e1a33","session_name":"830e5c42-9422-4fa3-b0d8-f072e88eb5cb","turns":[],"started_at":"2025-09-30T15:34:59.808900Z","vector_db_id":null,"owner":null,"identifier":"830e5c42-9422-4fa3-b0d8-f072e88eb5cb","type":"session"}
 
sqlite> select value from kvstore where key='session:18dc140f-bc78-496a-8cd2-d37a518ee56f:0171d680-8dcf-4c80-b612-2a0ee40e1a33:e6c3bccc-3174-4ea1-ad9e-227944bfed87';
{"turn_id":"e6c3bccc-3174-4ea1-ad9e-227944bfed87","session_id":"0171d680-8dcf-4c80-b612-2a0ee40e1a33","input_messages":[{"role":"user","content":"Say Hello in Czech","context":null}],"steps":[{"turn_id":"e6c3bccc-3174-4ea1-ad9e-227944bfed87","step_id":"c2534750-4cea-4f98-a1db-69ce7aa22e2b","started_at":"2025-09-30T15:34:59.867311Z","completed_at":"2025-09-30T15:35:02.306269Z","step_type":"inference","model_response":{"role":"assistant","content":"Hello in Czech is \"Ahoj\" (informal) or \"Dobrý den\" (formal).","stop_reason":"end_of_turn","tool_calls":[]}}],"output_message":{"role":"assistant","content":"Hello in Czech is \"Ahoj\" (informal) or \"Dobrý den\" (formal).","stop_reason":"end_of_turn","tool_calls":[]},"output_attachments":[],"started_at":"2025-09-30T15:34:59.861412Z","completed_at":"2025-09-30T15:35:02.307082Z"}

Po naformátování přes filtr jq dostaneme čitelnou část konverzace i se všemi metadaty:

{
  "turn_id": "e6c3bccc-3174-4ea1-ad9e-227944bfed87",
  "session_id": "0171d680-8dcf-4c80-b612-2a0ee40e1a33",
  "input_messages": [
    {
      "role": "user",
      "content": "Say Hello in Czech",
      "context": null
    }
  ],
  "steps": [
    {
      "turn_id": "e6c3bccc-3174-4ea1-ad9e-227944bfed87",
      "step_id": "c2534750-4cea-4f98-a1db-69ce7aa22e2b",
      "started_at": "2025-09-30T15:34:59.867311Z",
      "completed_at": "2025-09-30T15:35:02.306269Z",
      "step_type": "inference",
      "model_response": {
        "role": "assistant",
        "content": "Hello in Czech is \"Ahoj\" (informal) or \"Dobrý den\" (formal).",
        "stop_reason": "end_of_turn",
        "tool_calls": []
      }
    }
  ],
  "output_message": {
    "role": "assistant",
    "content": "Hello in Czech is \"Ahoj\" (informal) or \"Dobrý den\" (formal).",
    "stop_reason": "end_of_turn",
    "tool_calls": []
  },
  "output_attachments": [],
  "started_at": "2025-09-30T15:34:59.861412Z",
  "completed_at": "2025-09-30T15:35:02.307082Z"
}

13. Složitější příklad klienta pro Llama Stack: získávání informací v zadaných dokumentech

Llama Stack je možné využít i pro složitější operace, než je pouhé volání LLM se zpracováním odpovědí, které model vrací. Jedním z velmi častých požadavků je vyhledávání informací v dokumentech, které jsou systému předány a většinou i nějakým způsobem předzpracovány. Odpověď LLM bude v takovém případě postavena na informacích přečtených z těchto dokumentů – LLM tedy bude realizovat „porozumění otázce“ a vygenerování čitelné odpovědi, ovšem skutečným zdrojem informací budou předané dokumenty. V rámci navazujících kapitol se pokusíme podobný systém vytvořit.

Vzhledem k tomu, že budeme muset dokumenty „vektorizovat“ do vhodné formy, je nutná i úprava konfiguračního souboru run.yaml používaného Llama Stackem:

  • Povolí se API files
  • Nastaví se provider sentence-transformers
  • Nastaví se skupina nástrojů rag-runtime
  • Přidá se model ibm-granite/granite-embedding-125m-english typu embedding (ten jsme používali v jiných článcích)

Nový konfigurační soubor vypadá následovně:

version: '2'
image_name: minimal-viable-llama-stack-configuration
 
apis:
  - agents
  - datasetio
  - eval
  - files
  - inference
  - post_training
  - safety
  - scoring
  - telemetry
  - tool_runtime
  - vector_io
benchmarks: []
container_image: null
datasets: []
external_providers_dir: null
inference_store:
  db_path: .llama/distributions/ollama/inference_store.db
  type: sqlite
logging: null
metadata_store:
  db_path: .llama/distributions/ollama/registry.db
  namespace: null
  type: sqlite
providers:
  agents:
  - config:
      persistence_store:
        db_path: .llama/distributions/ollama/agents_store.db
        namespace: null
        type: sqlite
      responses_store:
        db_path: .llama/distributions/ollama/responses_store.db
        type: sqlite
    provider_id: meta-reference
    provider_type: inline::meta-reference
  datasetio:
  - config:
      kvstore:
        db_path: .llama/distributions/ollama/huggingface_datasetio.db
        namespace: null
        type: sqlite
    provider_id: huggingface
    provider_type: remote::huggingface
  - config:
      kvstore:
        db_path: .llama/distributions/ollama/localfs_datasetio.db
        namespace: null
        type: sqlite
    provider_id: localfs
    provider_type: inline::localfs
 
  eval:
  - config:
      kvstore:
        db_path: .llama/distributions/ollama/meta_reference_eval.db
        namespace: null
        type: sqlite
    provider_id: meta-reference
    provider_type: inline::meta-reference
  inference:
    - provider_id: openai
      provider_type: remote::openai
      config:
         api_key: ${env.OPENAI_API_KEY}
    - provider_id: sentence-transformers
      provider_type: inline::sentence-transformers
      config: {}
  post_training:
  - config:
      checkpoint_format: huggingface
      device: cpu
      distributed_backend: null
      dpo_output_dir: "."
    provider_id: huggingface
    provider_type: inline::huggingface-gpu
  safety:
  - config:
      excluded_categories: []
    provider_id: llama-guard
    provider_type: inline::llama-guard
  scoring:
  - config: {}
    provider_id: basic
    provider_type: inline::basic
  - config: {}
    provider_id: llm-as-judge

14. Vektorizace dokumentu

Prvním krokem k vyhledávání informací v zadaných dokumentech je jejich vektorizace. Vektorizovaný dokument bude (v našem případě) uložený do SQLite databáze; vektorizaci a embedding provede knihovna FAISS, s níž jsme se již na stránkách Roota seznámili. V dalším skriptu budeme zpracovávat (vektorizovat) soubor README.TXT. Necháme si vygenerovat ID dokumentu, dokument načteme, necháme provést jeho vektorizaci a následné uložení do formátu FAISS :

from pathlib import Path
import uuid
from llama_stack_client import LlamaStackClient
 
client = LlamaStackClient(base_url="http://localhost:8321")
print(f"Using Llama Stack version {client._version}")
 
vector_store_name= f"vec_{str(uuid.uuid4())[0:8]}"
print(f"Vector store name: {vector_store_name}")
 
vector_store = client.vector_stores.create(name=vector_store_name)
vector_store_id = vector_store.id
 
print(f"Vector store ID: {vector_store_id}")
 
path=Path("README.TXT")
print(f"File path: {path}")
 
file_create_response = client.files.create(file=path, purpose="assistants")
print(f"File create response: {file_create_response}")
 
file_ingest_response = client.vector_stores.files.create(
    vector_store_id=vector_store_id,
    file_id=file_create_response.id,
)
print(f"File ingest response: {file_ingest_response}")

Samotné zpracování může vypadat takto:

Using Llama Stack version 0.2.23
Vector store name: vec_731ad72e
INFO:httpx:HTTP Request: POST http://localhost:8321/v1/openai/v1/vector_stores "HTTP/1.1 200 OK"
Vector store ID: vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79
File path: README.TXT
INFO:httpx:HTTP Request: POST http://localhost:8321/v1/openai/v1/files "HTTP/1.1 200 OK"
File create response: File(id='file-98262421c3f1439d8c6236abc6287785', bytes=13773, created_at=1759332995, expires_at=1790868995, filename='README.TXT', object='file', purpose='assistants')
INFO:httpx:HTTP Request: POST http://localhost:8321/v1/openai/v1/vector_stores/vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79/files "HTTP/1.1 200 OK"
File ingest response: VectorStoreFile(id='file-98262421c3f1439d8c6236abc6287785', attributes={}, chunking_strategy=ChunkingStrategyVectorStoreChunkingStrategyAuto(type='auto'), created_at=1759332995, object='vector_store.file', status='completed', usage_bytes=0, vector_store_id='vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79', last_error=None)

Výsledek bude uložen v SQLite databázi, konkrétně v souboru nazvaném faiss_store.db (ten jsme specifikovali v run.yaml). Můžeme se na strukturu této databáze podívat:

$ sqlite3 faiss_store.db 
SQLite version 3.45.1 2024-01-30 16:01:20
Enter ".help" for usage hints.
 
sqlite> .tables
kvstore
 
sqlite> pragma table_info(kvstore);
0|key|TEXT|0||1
1|value|TEXT|0||0
2|expiration|TIMESTAMP|0||0

V tabulce kvstore je uloženo několik řádků, přičemž všechny z nich souvisí s naším zpracovaným dokumentem s ID vs_a5c84463–0fc0–4aa3-a5c1–6f04de6e9b79. To je dobře patrné při pohledu na klíče této tabulky:

sqlite> select key from kvstore;
 
faiss_index:v3::vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79
openai_vector_stores:v3::vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79
openai_vector_stores_files:v3::vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79:file-98262421c3f1439d8c6236abc6287785
openai_vector_stores_files_contents:v3::vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79:file-98262421c3f1439d8c6236abc6287785:0
openai_vector_stores_files_contents:v3::vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79:file-98262421c3f1439d8c6236abc6287785:1
openai_vector_stores_files_contents:v3::vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79:file-98262421c3f1439d8c6236abc6287785:2
openai_vector_stores_files_contents:v3::vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79:file-98262421c3f1439d8c6236abc6287785:3
openai_vector_stores_files_contents:v3::vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79:file-98262421c3f1439d8c6236abc6287785:4
openai_vector_stores_files_contents:v3::vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79:file-98262421c3f1439d8c6236abc6287785:5
openai_vector_stores_files_contents:v3::vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79:file-98262421c3f1439d8c6236abc6287785:6
openai_vector_stores_files_contents:v3::vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79:file-98262421c3f1439d8c6236abc6287785:7
vector_dbs:v3::vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79

„Důkaz“, že byl embedding skutečně proveden s využitím zvoleného modelu a výsledkem je sada vektorů s délkou 768 prvků:

sqlite> select value from kvstore limit 1;
 
{"identifier":"vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79","provider_resource_id":"vs_a5c84463-0fc0-4aa3-a5c1-6f04de6e9b79","provider_id":"faiss","type":"vector_db","embedding_model":"granite-embedding-125m","embedding_dimension":768,"vector_db_name":"vec_731ad72e"}

Příklad vektorizace (zkráceno):

"embedding": [-0.03943336009979248, -0.01908390410244465,
-0.034633487462997437, -0.029541026800870895, -0.012101504020392895,
0.008838939480483532, -0.013992378488183022, -0.03574834391474724,
-0.008313454687595367, 0.03812386095523834, -0.03949115052819252,
-0.01364347618073225, 0.019146878272294998, -0.02332368865609169,
0.022262772545218468, -0.014989514835178852, -0.024517007172107697,
0.003984575625509024, 0.06360703706741333, -0.0027450593188405037,
0.019605254754424095, -0.04282861948013306, -0.002660290105268359,
-0.0033418613020330667, -0.02703104540705681, 0.007085749879479408,
-0.025961343199014664, -0.005607941187918186, 0.0013212861958891153,
0.021539753302931786, -0.009276880882680416, 0.03668196499347687,
0.008254827000200748, -0.014407715760171413, 0.083653025329113,
-0.011135507375001907, -0.02412128821015358, -0.010947308503091335,
-0.009556970559060574, 0.02783835679292679, 0.001607213169336319,
0.027288049459457397, 0.0036381920799613, -0.03964642062783241,
-0.004188301041722298, -0.009024555794894695, -0.01408500224351883,
-0.008081816136837006, -0.000776242814026773, 0.03358744457364082,
0.056703999638557434, 0.009532158263027668, -0.0077535128220915794,
0.001604839344508946, -0.01480758935213089, -0.016446800902485847,
0.03730686753988266, 0.026151947677135468, -0.022170282900333405,
-0.012036912143230438, 0.017871132120490074, 0.05530891194939613,
0.021827947348356247, -0.009660700336098671, 0.04853382334113121,
0.0053733158856630325, -0.0041849869303405285, -0.03651648014783859,
-0.04091021418571472, 0.02955329231917858, 0.008832980878651142,
-0.02227284014225006, 0.016374535858631134, 0.0013979984214529395,
0.00859660841524601, 0.023964019492268562, -0.04963831230998039,
-0.0016858188901096582, -0.0374150313436985, 0.023536663502454758,
0.0008030434837564826, -0.04901596158742905, -0.003732183249667287,
-0.0011841172818094492, 0.008876342326402664, -0.02876201830804348,
0.021032467484474182, -0.031778112053871155, -0.05480746552348137,
-0.046331148594617844, 0.01832522451877594, -0.02780357375741005,
0.02628582902252674, -0.01693951152265072, 0.04124580696225166,
-0.016992267221212387, 0.01953108049929142, -0.06444697827100754,
-0.032282277941703796, -0.043638166040182114, 0.0039009766187518835,
0.01508582755923

15. Provedení dotazu se získáním informací z dokumentu

Nyní původní skript doplníme o volání LLM, ovšem s předáním informací o tom, že model může volat nástroj (tool) určený pro čtení vět (či jiných celků) z vektorizovaného dokumentu s provedením vyhledání podle podobnosti vektorů. Skript dále obsahuje pomocnou funkci print_rag_response, která vypíše podrobnější informace o provedené operaci:

models = client.models.list()
model_id = models[0].identifier
 
print(f"Using model {model_id}")
 
MODEL_ID="openai/gpt-4-turbo"
 
def print_rag_response(response):
    print(f"ID: {response.id}")
    print(f"Status: {response.status}")
    print(f"Model: {response.model}")
    print(f"Created at: {response.created_at}")
    print(f"Output items: {len(response.output)}")
 
    for i, output_item in enumerate(response.output):
        if len(response.output) > 1:
            print(f"\n--- Output Item {i+1} ---")
        print(f"Output type: {output_item.type}")
 
        if output_item.type in ("text", "message"):
            print(f"Response content: {output_item.content[0].text}")
        elif output_item.type == "file_search_call":
            print(f"  Tool Call ID: {output_item.id}")
            print(f"  Tool Status: {output_item.status}")
            print(f"  Queries: {', '.join(output_item.queries)}")
            print(f"  Results: {output_item.results if output_item.results else 'None'}")
        else:
            print(f"Response content: {output_item.content}")
 
 
response = client.responses.create(
    model=MODEL_ID,
    input="zadaný dotaz",
    tools=[
        {
            "type": "file_search",
            "vector_store_ids": [vector_store_id],
        }
    ]
)
 
print_rag_response(response)

16. Úplný zdrojový kód klienta, který bude odpovídat na základě dokumentů určených k prohledávání

Zdrojový kód klienta, který komunikuje s Llama Stackem a dokáže provést získání informací z dokumentu nebo sady dokumentů, ve skutečnosti není příliš dlouhý. Provádí se zde veškeré operace; od prvotního zpracování dokumentu až po dotaz do LLM a získání odpovědí, včetně podobnostního vyhledávání v předzpracovaných dokumentech:

import uuid
from llama_stack_client import LlamaStackClient
 
client = LlamaStackClient(base_url="http://localhost:8321")
print(f"Using Llama Stack version {client._version}")
 
vector_store_name= f"vec_{str(uuid.uuid4())[0:8]}"
print(f"Vector store name: {vector_store_name}")
 
vector_store = client.vector_stores.create(name=vector_store_name)
vector_store_id = vector_store.id
 
print(f"Vector store ID: {vector_store_id}")
 
models = client.models.list()
model_id = models[0].identifier
 
print(f"Using model {model_id}")
 
from pathlib import Path
 
path=Path("05_05_variance.md")
print(f"File path: {path}")
 
file_create_response = client.files.create(file=path, purpose="assistants")
print(f"File create response: {file_create_response}")
 
file_ingest_response = client.vector_stores.files.create(
    vector_store_id=vector_store_id,
    file_id=file_create_response.id,
)
print(f"File ingest response: {file_ingest_response}")
 
MODEL_ID="openai/gpt-4-turbo"
 
def print_rag_response(response):
    print(f"ID: {response.id}")
    print(f"Status: {response.status}")
    print(f"Model: {response.model}")
    print(f"Created at: {response.created_at}")
    print(f"Output items: {len(response.output)}")
 
    for i, output_item in enumerate(response.output):
        if len(response.output) > 1:
            print(f"\n--- Output Item {i+1} ---")
        print(f"Output type: {output_item.type}")
 
        if output_item.type in ("text", "message"):
            print(f"Response content: {output_item.content[0].text}")
        elif output_item.type == "file_search_call":
            print(f"  Tool Call ID: {output_item.id}")
            print(f"  Tool Status: {output_item.status}")
            # 'queries' is a list, so we join it for clean printing
            print(f"  Queries: {', '.join(output_item.queries)}")
            # Display results if they exist, otherwise note they are empty
            print(f"  Results: {output_item.results if output_item.results else 'None'}")
        else:
            print(f"Response content: {output_item.content}")
 
 
response = client.responses.create(
    model=MODEL_ID,
    input="Display class Ovoce",
    tools=[
        {
            "type": "file_search",
            "vector_store_ids": [vector_store_id],
        }
    ]
)
 
print_rag_response(response)
Poznámka: modifikovatelné části jsou zvýrazněny. Můžete si je uložit do globálních proměnných, přidat podporu pro interaktivní dotazy nebo celý příklad předělat na klienta dostupného přes REST API atd. atd.

17. Výsledky dotazů s doplněním informací získaných z předaného dokumentu

Jako dokument ke zpracování jsem zvolil dokument obsahující popisek známé (starší, nicméně pořád dobré) hry Supaplex. Ten naleznete na adrese https://github.com/sergiou87/open-supaplex/blob/73df867bc9c147­90a23b8d66c86388e09b7e5312/re­sources/README.TXT.

Dotaz zněl následovně:

What is Zonk?

Odpověď námi naprogramovaného systému:

Output type: message
Response content: "ZONK" refers to an element in the videogame Supaplex. In the
game, a Zonk is depicted as a round rock, and it is a common and typically
unpleasant obstacle. Zonks tend to fall downwards whenever possible, for
instance, if there is a void directly underneath them. Players must be cautious
as a Zonk falling on the character (Murphy) results in an explosion and
game-over for the player. Murphy can push Zonks laterally (but not vertically)
if there is space for them to move, but can only push one Zonk at a time. Good
timing is needed to use Zonks strategically, such as dropping them on top of
enemies (like Snik-snaks) to eliminate them through explosions.
Poznámka: sami si najděte, kde v README.TXT se o Zoncích mluví a jak dobře LLM tuto informaci dokázal zpracovat.

18. Vrácení části zdrojového kódu na základě položeného dotazu

Podívejme se ještě na jeden příklad. Tentokrát jsem se pokusil získat zdrojový kód určité třídy (konkrétně třídy Ovoce) z knihy o Pythonu (https://knihy.nic.cz/cs/detail/29/), ke které mám „zdrojové kódy“ napsané v Markdownu.

Dotaz zněl jednoduše:

display class Ovoce

Odpověď byla zpracována následovně:

Created at: 1758745437
Output items: 2
 
--- Output Item 1 ---
Output type: file_search_call
  Tool Call ID: call_CEgssrYfjL0klzlXkzcYewfI
  Tool Status: completed
  Queries: Class Ovoce
  Results:
  ...
  ...
  ...
 
--- Output Item 2 ---
Output type: message
Response content: The class `Ovoce` along with its subclasses `Hruska` (Pear)
and `Jablko` (Apple) are defined in a programming example to illustrate the
concept of variance in object-oriented programming. Below is the definition of
these classes in Java:
 
```java
class Ovoce {
}
 
class Hruska extends Ovoce {
    public String toString() {
        return "Hruska";
    }
}
 
class Jablko extends Ovoce {
    public String toString() {
        return "Jablko";
    }
}
```
 
This hierarchy involves a base class `Ovoce`, with two derived classes `Hruska`
and `Jablko`. The `toString()` method in both subclasses provides a simple way
to return the string representation of each fruit. This basic class structure
is used to demonstrate type variance and how objects of these types interact
within an array specified as type `Ovoce`, addressing concepts such as
compile-time and runtime type safety in Java.

To ve skutečnosti vůbec není špatná odpověď (navíc přeložená do angličtiny).

Poznámka: podrobnosti embeddingu, priority RAG databází atd. si uvedeme příště.

19. Repositář s demonstračními příklady

Projekty popsané v předchozích kapitolách je možné nalézt v repositáři https://github.com/tisnik/most-popular-python-libs. Následují odkazy na jednotlivé soubory s jejich stručným popisem:

První projekt: volání LLM modelu přes stack

# Příklad Stručný popis Adresa příkladu
1 demo1/pyproject.toml konfigurační soubor s definicí projektu https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo1/pyproject.toml
2 demo1/pdm.lock soubor se seznamem a haši nainstalovaných balíčků https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo1/pdm.lock
3 demo1/run.yaml konfigurace našeho stacku https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo1/run.yaml
4 demo1/client1.py skript v Pythonu s realizovaným klientem https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo1/client1.py

Druhý projekt: výpis všech dostupných modelů

# Příklad Stručný popis Adresa příkladu
1 demo2/pyproject.toml konfigurační soubor s definicí projektu https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo2/pyproject.toml
2 demo2/pdm.lock soubor se seznamem a haši nainstalovaných balíčků https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo2/pdm.lock
3 demo2/run.yaml konfigurace našeho stacku https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo2/run.yaml
4 demo2/client2.py skript v Pythonu s realizovaným klientem https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo2/client2.py

Třetí projekt: využití Llama Stacku jako Pythonní knihovny

# Příklad Stručný popis Adresa příkladu
1 demo3/pyproject.toml konfigurační soubor s definicí projektu https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo3/pyproject.toml
2 demo3/pdm.lock soubor se seznamem a haši nainstalovaných balíčků https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo3/pdm.lock
3 demo3/run.yaml konfigurace našeho stacku https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo3/run.yaml
4 demo3/client3.py skript v Pythonu s realizovaným klientem https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo3/client3.py

Čtvrtý projekt: nové rozhraní pro komunikaci s LLM

# Příklad Stručný popis Adresa příkladu
1 demo4/pyproject.toml konfigurační soubor s definicí projektu https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo4/pyproject.toml
2 demo4/run.yaml konfigurace našeho stacku https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo4/run.yaml
3 demo4/client4.py skript v Pythonu s realizovaným klientem https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo4/client4.py

Pátý projekt: hledání odpovědí z předaných a zpracovaných dokumentů

# Příklad Stručný popis Adresa příkladu
1 demo5/pyproject.toml konfigurační soubor s definicí projektu https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo5/pyproject.toml
2 demo5/run.yaml konfigurace našeho stacku https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo5/run.yaml
3 demo5/client5.py skript v Pythonu s realizovaným klientem https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo5/client5.py
4 demo5/output_ovoce.txt výstup modelu – informace o třídě Ovoce https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo5/output_ovoce.txt
5 demo5/output_zonk.txt výstup modelu – získání informace ze souboru README.TXT https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo5/output_zonk.txt
6 demo5/README.TXT dokumentace ke hře Supaplex https://github.com/tisnik/most-popular-python-libs/blob/master/llama-stack-demo/demo5/README.TXT

20. Odkazy na Internetu

  1. llama-stack na GitHubu
    https://github.com/meta-llama/llama-stack
  2. llama-stack na PyPi
    https://pypi.org/project/llama-stack/
  3. Configuring a „Stack“
    https://llama-stack.readthedocs.io/en/la­test/distributions/configu­ration.html#
  4. Generativní umělá inteligence
    https://cs.wikipedia.org/wi­ki/Generativn%C3%AD_um%C4%9Bl%C3%A1_­inteligence
  5. Generative artificial intelligence
    https://en.wikipedia.org/wi­ki/Generative_artificial_in­telligence
  6. Generativní AI a LLM: ®evoluce v umělé inteligenci?
    https://www.itbiz.cz/clan­ky/generativni-ai-a-llm-revoluce-v-umele-inteligenci/
  7. langchain
    https://python.langchain.com/doc­s/introduction/
  8. langgraph
    https://github.com/langchain-ai/langgraph
  9. autogen
    https://github.com/microsoft/autogen
  10. metaGPT
    https://github.com/geekan/MetaGPT
  11. phidata
    https://github.com/phidatahq/phidata
  12. CrewAI
    https://github.com/crewAIInc/crewAI
  13. pydanticAI
    https://github.com/pydantic/pydantic-ai
  14. controlflow
    https://github.com/Prefec­tHQ/ControlFlow
  15. langflow
    https://github.com/langflow-ai/langflow
  16. LiteLLM
    https://github.com/BerriAI/litellm
  17. Llama Stack
    https://github.com/meta-llama/llama-stack
  18. uv
    https://docs.astral.sh/uv/
  19. Python na Root.cz
    https://www.root.cz/n/python/
  20. PDM: moderní správce balíčků a virtuálních prostředí Pythonu
    https://www.root.cz/clanky/pdm-moderni-spravce-balicku-a-virtualnich-prostredi-pythonu/
  21. YAML
    https://en.wikipedia.org/wiki/YAML
  22. Top 11 LLM API Providers in 2025
    https://www.helicone.ai/blog/llm-api-providers
  23. Zpracování dat reprezentovaných ve formátu JSON nástrojem jq
    https://www.root.cz/clanky/zpracovani-dat-reprezentovanych-ve-formatu-json-nastrojem-jq/
  24. LLama Stack SDK pro jazyk Python
    https://github.com/meta-llama/llama-stack-client-python
  25. LLama Stack SDK pro jazyk Swift
    https://github.com/meta-llama/llama-stack-client-swift/tree/latest-release
  26. LLama Stack SDK pro ekosystém Node.js
    https://github.com/meta-llama/llama-stack-client-node
  27. LLama Stack SDK pro jazyk Kotlin
    https://github.com/meta-llama/llama-stack-client-kotlin/tree/latest-release
  28. SQLite
    https://www.sqlite.org/index.html
  29. Llama Stack examples
    https://github.com/The-AI-Alliance/llama-stack-examples
  30. Building RAG-based LLM Applications for Production
    https://www.anyscale.com/blog/a-comprehensive-guide-for-building-rag-based-llm-applications-part-1
  31. Retrieval-augmented generation
    https://medium.com/@mikeshwe_19587/re­trieval-augmented-generation-a0b6b6c20c03
  32. Supaplex: README.TXT
    https://github.com/sergiou87/open-supaplex/blob/73df867bc9c147­90a23b8d66c86388e09b7e5312/re­sources/README.TXT
Neutrální ikona do widgetu na odběr článků ze seriálů

Zajímá vás toto téma? Chcete se o něm dozvědět víc?

Objednejte si upozornění na nově vydané články do vašeho mailu. Žádný článek vám tak neuteče.


Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.