Obsah článku / Contents
DSPy: Programovanie LLM Pipelines s Pythonom

DSPy: Keď sa písanie promptov stáva programovaním

V rýchlo sa meniacom svete Large Language Models (LLM) sa prompt engineering stal kľúčovou zručnosťou. Ale čo ak vám poviem, že dni manuálneho ladenia a krehkých promptov sú spočítané? Vstúpte do sveta DSPy – frameworku, ktorý mení hru tým, že pristupuje k LLM pipeline ako k softvérovému programu.

DSPy, čo znamená Declarative Self-improving Language Programs, je Python knižnica od Stanford NLP, ktorá vám umožňuje programovo definovať, optimalizovať a skladať moduly, ktoré využívajú LLM. Namiesto písania dlhých a zložitých promptov, definujete štruktúru vašej úlohy a necháte DSPy, aby našlo najlepší spôsob, ako ju vykonať.

Problém: Krehkosť tradičných promptov

Predstavte si, že budujete systém na odpovedanie na otázky (Question Answering). Váš tradičný prístup by mohol vyzerať takto:

1

Vytvoríte zložitý prompt

, ktorý obsahuje inštrukcie, pár príkladov (few-shot examples) a formátovanie výstupu.
2

testujete a ladíte

Manuálne ho pre rôzne prípady.
3

rozbije celý prompt

Zistíte, že (napr. z GPT-3.5 na Llama 3) alebo dokonca malá zmena v dátach .
4

Začnete odznova.

Tento cyklus je neefektívny, neškálovateľný a pripomína skôr umenie ako inžinierstvo.

Príklad: Manuálne vytvorený prompt

Answer the question based on the provided context.
Context: The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France. It is named after the engineer Gustave Eiffel, whose company designed and built the tower.
Question: Who designed the Eiffel Tower?
Answer: The Eiffel Tower was designed by Gustave Eiffel's company.
---
Context: The Great Wall of China is a series of fortifications that were built across the historical northern borders of ancient Chinese states and Imperial China as protection against various nomadic groups from the Eurasian Steppe.
Question: Why was the Great Wall of China built?
Answer: The Great Wall of China was built to protect against nomadic groups.
---
Context: {provided_context}
Question: {provided_question}
Answer:

Tento prístup je rigidný. Ak sa zmení formát otázky alebo kontextu, prompt môže zlyhať.

Riešenie: Programová kompozícia s DSPy

DSPy mení tento prístup od základov. Namiesto jedného monolitu definujete malé, znovupoužiteľné moduly nazývané Signatures.

1. Signature: Atómový blok vašej Pipeline

Signature je deklaratívny popis úlohy, ktorú má LLM vykonať. Definuje vstupné a výstupné polia.

python
import dspy

class BasicQA(dspy.Signature):
    """Answer questions based on context."""
    context = dspy.InputField(desc="may contain relevant facts")
    question = dspy.InputField()
    answer = dspy.OutputField(desc="often between 1 and 5 words")

Čo sa tu deje?

  • Definovali sme triedu BasicQA, ktorá dedí od dspy.Signature.
  • context a question sú naše vstupy.
  • answer je náš výstup.
  • desc atribúty sú hinty pre LLM, ktoré mu pomáhajú pochopiť účel poľa.

2. Moduly: Kombinovanie Signatures

DSPy poskytuje preddefinované moduly, ktoré môžete použiť s vašimi signatúrami. Najzákladnejší je dspy.Predict.

python
# Nakonfigurujte si svoj LLM (napr. OpenAI, Llama)
openai = dspy.OpenAI(model='gpt-3.5-turbo')
dspy.settings.configure(lm=openai)

# Vytvorte predikčný modul
qa_predictor = dspy.Predict(BasicQA)

# Spustite predikciu
result = qa_predictor(context="The capital of France is Paris.", question="What is the capital of France?")
print(result.answer) # Výstup: Paris

Toto je len začiatok. Skutočná sila prichádza s kompozíciou a optimalizáciou.

3. Kompozícia: Budovanie zložitých Pipelines

Predstavme si zložitejší RAG (Retrieval-Augmented Generation) systém. Tradične by to bol jeden masívny prompt. S DSPy ho poskladáme z modulov.

python
class RAG(dspy.Module):
    def __init__(self, num_passages=3):
        super().__init__()
        # 1. Retriever na nájdenie relevantných dokumentov
        self.retrieve = dspy.Retrieve(k=num_passages)
        # 2. Generátor odpovedí
        self.generate_answer = dspy.ChainOfThought(BasicQA)

    def forward(self, question):
        # Načítaj relevantné kontexty
        context = self.retrieve(question).passages
        # Vygeneruj odpoveď na základe kontextov
        prediction = self.generate_answer(context=context, question=question)
        return dspy.Prediction(context=context, answer=prediction.answer)

Čo sa stalo?

  • Vytvorili sme RAG modul.
  • Použili sme dspy.Retrieve na vyhľadávanie (napr. z vektorovej databázy).
  • Použili sme dspy.ChainOfThought pre generovanie odpovede, čo je pokročilejší modul, ktorý si sám vytvára "myšlienkový pochod".
  • Vo forward metóde sme definovali tok dát: question -> retrieve -> generate_answer -> prediction.

Kúzlo DSPy: Teleprompters a Optimalizácia

Tu prichádza tá najlepšia časť. DSPy dokáže optimalizovať vašu pipeline za vás. Proces optimalizácie sa nazýva compilation.

Kompilátor (nazývaný Teleprompter) zoberie vašu pipeline, tréningové dáta (zopár príkladov) a automaticky vygeneruje a otestuje rôzne prompty pre každý modul.

python
from dspy.teleprompt import BootstrapFewShot

# 1. Pripravte si pár príkladov (otázka, odpoveď)
trainset = [
    dspy.Example(question="What is the capital of Slovakia?", answer="Bratislava").with_inputs("question"),
    dspy.Example(question="Who wrote Hamlet?", answer="William Shakespeare").with_inputs("question"),
]

# 2. Vytvorte optimalizátor (Teleprompter)
# BootstrapFewShot vytvorí few-shot príklady pre každý krok
teleprompter = BootstrapFewShot(metric=dspy.evaluate.answer_exact_match)

# 3. Spustite kompiláciu
compiled_rag = teleprompter.compile(RAG(), trainset=trainset)

# 4. Použite optimalizovanú pipeline
prediction = compiled_rag(question="What is the highest mountain on Earth?")
print(prediction.answer) # Výstup bude pravdepodobne presnejší

Čo sa stalo počas kompilácie?

1

Krok 1

DSPy spustilo vašu RAG pipeline na tréningových dátach.
2

Analyzovalo, kde robí chyby.

3

Automaticky vygenerovalo few-shot príklady

pre generate_answer modul na základe úspešných a neúspešných pokusov.
4

Výsledkom je nová, "skompilovaná" pipeline, ktorá má v sebe zabudované optimalizované prompty.

Prečo je to revolučné?

1

Abstrakcia od konkrétneho LLM:

Vaša pipeline je definovaná nezávisle od modelu. Keď vyjde nový, lepší model, jednoducho ho prepnete a znova skompilujete.
2

Výkonnosť:

Optimalizované pipelines dosahujú výrazne lepšie výsledky ako manuálne ladené prompty.
3

Modularita:

Môžete jednoducho meniť a kombinovať moduly (dspy.ChainOfThought, dspy.ReAct, dspy.MultiChainComparison, atď.).
4

Reprodukovateľnosť:

Namiesto ukladania krehkých promptov verzujete štruktúrovaný kód.
5

Data-driven prístup:

Kvalita vašej pipeline priamo závisí od kvality vašich dát, nie od "mágie" v promptoch.

Záver

DSPy predstavuje posun od "prompt engineeringu" k "LLM programmingu". Je to silný nástroj pre každého, kto chce budovať robustné, škálovateľné a výkonné aplikácie postavené na LLM. Ak vás už unavuje nekonečné ladenie promptov a chcete začať pristupovať k LLM ako skutočný softvérový inžinier, DSPy je cesta vpred.

Všetky články