Cursus
Heb je ooit geprobeerd een meubelstuk in elkaar te zetten zonder de handleiding te lezen? Met wat geluk krijg je het deels voor elkaar, maar zonder stapsgewijze begeleiding wordt het vaak een rommeltje. Dat lijkt op de uitdaging waar large language models (LLM’s) voor staan bij complexe problemen. De modellen hebben enorm veel potentie, maar slaan de plank vaak mis zodra een taak gedetailleerd redeneren in meerdere stappen vraagt.
Bij één enkele prompt geven LLM’s soms antwoorden die te algemeen zijn, onvoldoende diepgang hebben of cruciale details missen. Dit komt doordat het lastig is om alle benodigde context te vangen en voldoende richting te geven in één prompt.
De oplossing hiervoor is prompt chaining.
Prompt chaining houdt in dat je een complexe taak opdeelt in een reeks kleinere, beter behapbare prompts. Elke prompt pakt een specifiek onderdeel van de taak aan, en de output van de ene prompt dient als input voor de volgende. Deze methode zorgt voor een meer gestructureerde aanpak, waarbij je de LLM door een keten van redeneerstappen leidt naar een accurater en vollediger antwoord. Met een logische volgorde van prompts kunnen we LLM’s optimaal inzetten om complexe problemen effectief op te lossen.
Deze tutorial maakt deel uit van mijn serie blogposts “Prompt Engineering: From Zero to Hero”:
- Prompt engineering voor iedereen
- Zero-shot prompting
- Few-shot prompting
- Prompt chaining
Wat is prompt chaining?
Prompt chaining is een methode waarbij de output van de ene LLM-prompt wordt gebruikt als input voor de volgende prompt in een reeks. Deze techniek bestaat uit een serie verbonden prompts die elk focussen op een specifiek deel van het totale probleem. Door deze volgorde te volgen, begeleid je de LLM door een gestructureerd redeneerproces, wat helpt om accuratere en meer gedetailleerde antwoorden te produceren.
Het hoofddoel van prompt chaining is de prestaties, betrouwbaarheid en helderheid van LLM-toepassingen te verbeteren. Voor complexe taken biedt één enkele prompt vaak niet genoeg diepgang en context voor een goed antwoord. Prompt chaining lost dit op door de taak in kleinere stappen op te delen en zo te zorgen dat elke stap zorgvuldig wordt afgehandeld. Deze methode verbetert de kwaliteit van de LLM-output en maakt het bovendien makkelijker te begrijpen hoe het eindresultaat tot stand is gekomen.
Laten we eens kijken naar enkele voordelen van prompt chaining:
|
Voordeel |
Beschrijving |
Voorbeeld |
|
Breekt complexiteit op |
Splitst complexe taken op in kleinere, behapbare subtaken, zodat de LLM zich telkens op één aspect kan richten. |
Een onderzoeksartikel stap voor stap genereren (opzet, secties, conclusie) in plaats van alles in één keer. |
|
Verbetert nauwkeurigheid |
Stuurt het redeneren van de LLM via tussenstappen, met meer context voor precieze en relevante antwoorden. |
Een technisch probleem diagnosticeren door eerst symptomen te identificeren, oorzaken te vernauwen en vervolgens oplossingen te suggereren. |
|
Verhoogt uitlegbaarheid |
Vergroot de transparantie van het beslisproces van de LLM, zodat je makkelijker snapt hoe conclusies tot stand komen. |
Een juridische beslissing uitleggen door relevante wetten te schetsen, ze toe te passen op een casus en stap voor stap naar een conclusie te werken. |
Hoe implementeer je prompt chaining
Prompt chaining implementeren betekent dat je een complexe taak systematisch opdeelt en een LLM door een reeks duidelijk gedefinieerde stappen leidt.
Zo maak en voer je effectief een promptketen uit.
Identificeer subtaken
De eerste stap bij prompt chaining is het opsplitsen van de complexe taak in kleinere, behapbare subtaken. Elke subtaak moet een duidelijk onderdeel van het geheel vertegenwoordigen. Zo kan de LLM zich steeds op één deel concentreren.
Stel dat je de LLM een uitgebreid rapport over klimaatverandering wilt laten schrijven. Mogelijke subtaken zijn:
- Historische klimaatdata onderzoeken
- Belangrijkste bevindingen uit wetenschappelijke literatuur samenvatten
- De impact van klimaatverandering op verschillende ecosystemen analyseren
- Mogelijke oplossingen en mitigatiestrategieën voorstellen
Ontwerp prompts
Ontwerp vervolgens duidelijke en beknopte prompts voor elke subtaak. Elke prompt moet specifiek en direct zijn, zodat de LLM de taak begrijpt en relevante output kan genereren. Belangrijk is dat de output van de ene prompt geschikt is als input voor de volgende, zodat er een informatiestroom ontstaat.
Voor de bovenstaande subtaken zouden we de volgende prompts kunnen maken:
- Subtaak 1 – prompt: "Vat de belangrijkste trends in wereldwijde temperatuurveranderingen in de afgelopen eeuw samen."
- Subtaak 2 – prompt: "Noem op basis van de geïdentificeerde trends de belangrijkste wetenschappelijke studies die de oorzaken van deze veranderingen bespreken."
- Subtaak 3 – prompt: "Vat de bevindingen van de genoemde studies samen, met focus op de impact van klimaatverandering op mariene ecosystemen."
- Subtaak 4 – prompt: "Stel op basis van de samengevatte bevindingen drie strategieën voor om de impact van klimaatverandering op mariene ecosystemen te beperken."
Keten uitvoeren
Voer de prompts nu sequentieel uit en geef de output van de ene prompt door als input aan de volgende. Deze stapsgewijze uitvoering zorgt ervoor dat de LLM voortbouwt op eerdere outputs en zo tot een samenhangend en volledig resultaat komt.
Voor ons voorbeeld zouden de outputs van de subtaken er ongeveer zo uitzien:
- Output van subtaak 1: "De wereldwijde temperatuur is in de afgelopen eeuw met ongeveer 1,2 graden Celsius gestegen, met aanzienlijke toename in de afgelopen 20 jaar."
- Input voor subtaak 2: "Aangezien de wereldwijde temperaturen in de afgelopen eeuw met 1,2 graden Celsius zijn gestegen, noem de belangrijkste wetenschappelijke studies die de oorzaken van deze veranderingen bespreken."
- Output van subtaak 2: "Belangrijke studies zijn onder meer: 'The Role of Greenhouse Gases in Global Warming' van Dr. Smith, 'Deforestation and Climate Change' van Dr. Jones en 'Oceanic Changes and Climate Patterns' van Dr. Lee."
- Input voor subtaak 3: "Vat de bevindingen samen van 'The Role of Greenhouse Gases in Global Warming' van Dr. Smith, 'Deforestation and Climate Change' van Dr. Jones en 'Oceanic Changes and Climate Patterns' van Dr. Lee, met focus op de impact van klimaatverandering op mariene ecosystemen."
Foutafhandeling
Mechanismen voor foutafhandeling zijn cruciaal om mogelijke problemen tijdens de uitvoering van prompts op te vangen. Denk aan controles die de kwaliteit en relevantie van de output checken vóór je doorgaat naar de volgende prompt, en aan fallback-prompts om de LLM terug op koers te brengen als die afwijkt van het verwachte pad. Bijvoorbeeld:
- Foutcontrole 1: Controleer na elke output of de informatie relevant en volledig is. Als de samenvatting van temperatuurtrends onvolledig is, vraag de LLM om extra details.
- Fallback-prompt: Als de LLM er niet in slaagt relevante wetenschappelijke studies te noemen, gebruik dan een specifiekere prompt zoals "Noem vijf peer-reviewed studies uit het afgelopen decennium die de oorzaken van de stijging van de wereldtemperatuur bespreken."
Implementatie
Laten we bekijken hoe je dit in Python implementeert!
Stap 1: De omgeving instellen
Allereerst importeren we de benodigde libraries. We gebruiken de OpenAI-klasse uit het pakket openai en os om omgevingsvariabelen te beheren.
import openai
import os
Het is essentieel om gevoelige informatie, zoals API-sleutels, veilig op te slaan. Eén manier is door de API-sleutel als omgevingsvariabele te zetten. Dat kan met een OpenAI API-sleutel.
os.environ['OPENAI_API_KEY'] = 'your-api-key-here'
Vervang 'your-api-key-here' door je eigen OpenAI API-sleutel.
Met de API-sleutel ingesteld kun je nu de OpenAI-client initialiseren. Deze client gebruik je om API-calls naar de services van OpenAI te doen.
Client = OpenAI ()
Stap 2: Een functie definiëren om met de chatcompletions-API van OpenAI te communiceren.
We maken nu een Python-functie om met de chatcompletions-API van OpenAI te communiceren. Deze functie stuurt een prompt naar de API en retourneert de gegenereerde reactie.
def get_completion(prompt, model="gpt-3.5-turbo"):
try:
response = client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": prompt}
],
temperature=0,
)
return response.choices[0].message.content
except Exception as e:
print(f"An error occurred: {e}")
return None
Laten we deze functie ontleden—ze:
- Neemt een prompt en een optionele modelparameter aan.
- Doet een API-call naar OpenAI via de chatcompletions-endpoint.
- Zet het gesprek op met een systeembericht en een gebruikersbericht (de prompt).
- Zet de temperatuur op 0 voor meer deterministische outputs (verhoog voor creatievere outputs).
- Retourneert de content van de response of
Noneals er een fout optreedt.
Stap 3: Meerdere prompts ketenen
We maken nu een Python-functie die meerdere prompts aan elkaar ketent, waarbij de output van de ene prompt als input voor de volgende dient.
def prompt_chain(initial_prompt, follow_up_prompts):
result = get_completion(initial_prompt)
if result is None:
return "Initial prompt failed."
print(f"Initial output: {result}\n")
for i, prompt in enumerate(follow_up_prompts, 1):
full_prompt = f"{prompt}\n\nPrevious output: {result}"
result = get_completion(full_prompt)
if result is None:
return f"Prompt {i} failed."
print(f"Step {i} output: {result}\n")
return result
De functie prompt_chain implementeert prompt chaining. Ze:
- Begint met een initiële prompt en haalt de completion op.
- Doorloopt een lijst met vervolgprompts.
- Combineert voor elke vervolgprompt de prompt met de vorige output, haalt een completion op en werkt het resultaat bij.
- Retourneert een foutmelding als een stap faalt.
- Print de output van elke stap voor inzicht.
Stap 4: Voorbeeldgebruik
We laten nu zien hoe je de functie prompt_chain gebruikt om een reeks prompts te maken die op elkaar voortbouwen. Dit voorbeeld focust op het samenvatten van belangrijke trends in wereldwijde temperatuurveranderingen en het verkennen van gerelateerde wetenschappelijke studies en mitigatiestrategieën, maar je kunt het toepassen op je eigen usecase!
initial_prompt = "Summarize the key trends in global temperature changes over the past century."
follow_up_prompts = [
"Based on the trends identified, list the major scientific studies that discuss the causes of these changes.",
"Summarize the findings of the listed studies, focusing on the impact of climate change on marine ecosystems.",
"Propose three strategies to mitigate the impact of climate change on marine ecosystems based on the summarized findings."
]
final_result = prompt_chain(initial_prompt, follow_up_prompts)
print("Final result:", final_result)
Hier definiëren we een initiële prompt over temperatuurveranderingen, en vervolgens een lijst met vervolgprompts die op elkaar voortbouwen. Daarna roepen we de functie prompt_chain aan met deze prompts en printen we het eindresultaat.
Hoe het samenwerkt
Laten we het proces samenvatten:
- De initiële prompt levert een samenvatting van temperatuurtrends op.
- De eerste vervolgprompt gebruikt deze samenvatting om relevante studies te vinden.
- De tweede vervolgprompt vat de bevindingen van deze studies samen over mariene ecosystemen.
- De laatste prompt gebruikt al deze informatie om mitigatiestrategieën te voorstellen.
Deze keten maakt een stapsgewijze aanpak van complexe vragen mogelijk, waarbij elke stap voortbouwt op de informatie uit voorgaande stappen.
Prompt chaining-technieken
Prompt chaining kun je op verschillende manieren toepassen, afhankelijk van de taak en je eisen. Hier bespreken we drie primaire technieken: sequentieel ketenen, conditioneel ketenen en lus-gebaseerd ketenen.
Sequentieel ketenen
Sequentieel ketenen verbindt prompts in een eenvoudige, lineaire volgorde. Elke prompt hangt af van de output van de vorige, waardoor een stapsgewijze stroom van informatie en taken ontstaat. Deze techniek is ideaal voor taken die een logische voortgang van de ene fase naar de volgende vereisen, zoals:
- Tekstsamenvatting: Een lang document opdelen in samengevatte secties en die samenvattingen vervolgens samenvoegen tot één geheel.
- Codegeneratie: Codefragmenten stap voor stap genereren, zoals eerst functiedefinities maken, vervolgens de functies implementeren en tot slot testcases schrijven.
De code in de vorige sectie is een voorbeeld van sequentieel ketenen.
Conditioneel ketenen
Conditioneel ketenen introduceert vertakkingen in de promptketen op basis van de output van de LLM. Deze techniek maakt flexibelere, aanpasbare workflows mogelijk, waarbij de LLM verschillende paden kan volgen afhankelijk van de gegenereerde antwoorden.
Laten we bekijken hoe we conditioneel ketenen kunnen implementeren voor sentimentanalyse.
def analyze_sentiment(text):
prompt = f"Analyze the sentiment of the following text and respond with only one word - 'positive', 'negative', or 'neutral': {text}"
sentiment = get_completion(prompt)
return sentiment.strip().lower()
def conditional_prompt_chain(initial_prompt):
result = get_completion(initial_prompt)
if result is None:
return "Initial prompt failed."
print(f"Initial output: {result}\n")
sentiment = analyze_sentiment(result)
print(f"Sentiment: {sentiment}\n")
if sentiment == 'positive':
follow_up = "Given this positive outlook, what are three potential opportunities we can explore?"
elif sentiment == 'negative':
follow_up = "Considering these challenges, what are three possible solutions we can implement?"
else: # neutral
follow_up = "Based on this balanced view, what are three key areas we should focus on for a comprehensive approach?"
final_result = get_completion(f"{follow_up}\n\nContext: {result}")
return final_result
# Example usage
initial_prompt = "Analyze the current state of renewable energy adoption globally."
final_result = conditional_prompt_chain(initial_prompt)
print("Final result:", final_result)
Eerst definiëren we een nieuwe functie, analyze_sentiment(), die het taalmodel gebruikt om het sentiment van een gegeven tekst te bepalen. Vervolgens starten we in conditional_prompt_chain() met de initiële prompt over de adoptie van hernieuwbare energie. Na de eerste reactie analyseren we het sentiment. Afhankelijk van het sentiment kiezen we een andere vervolgprompt:
- Bij positief sentiment vragen we naar kansen.
- Bij negatief sentiment vragen we naar oplossingen.
- Bij neutraal sentiment vragen we naar belangrijke focusgebieden.
De gekozen vervolgprompt sturen we vervolgens naar het model, samen met de context uit de eerste reactie. Het eindresultaat is het antwoord op deze conditionele vervolgprompt.
Let op: de keuze voor de tweede prompt ligt niet vooraf vast, maar hangt af van de inhoud van de eerste reactie. De gespreksstroom past zich aan op basis van de sentimentanalyse, waardoor de keten in verschillende paden kan vertakken. Dit maakt de interactie dynamischer en contextbewuster.
Als je deze code draait, hangt de specifieke vervolgvraag af van of de initiële analyse van de adoptie van hernieuwbare energie als positief, negatief of neutraal wordt gezien. Zo ontstaat een meer adaptieve en responsieve keten van prompts.
Lus-gebaseerd ketenen
Lus-gebaseerd ketenen houdt in dat je lussen in een promptketen aanbrengt om over data te itereren of repetitieve taken uit te voeren. Deze techniek is handig voor lijsten of verzamelingen die vergelijkbare verwerkingsstappen vereisen. Enkele voordelen en uitdagingen:
- Efficiëntie: Automatiseert repetitieve taken en bespaart tijd en moeite.
- Dataverwerking: Geschikt voor taken als meerdere records verwerken, batch-samenvatting of iteratieve verbeteringen.
- Uitdagingen: Vereist zorgvuldige hantering om eindeloze lussen te vermijden en te zorgen dat elke iteratie betekenisvolle voortgang oplevert.
Zo zou lus-gebaseerd ketenen eruitzien voor een taak rond tekstvolledigheid:
def check_completeness(text):
prompt = f"Analyze the following text and respond with only 'complete' if it covers all necessary aspects, or 'incomplete' if more information is needed:\n\n{text}"
response = get_completion(prompt)
return response.strip().lower() == 'complete'
def looping_prompt_chain(initial_prompt, max_iterations=5):
current_response = get_completion(initial_prompt)
if current_response is None:
return "Initial prompt failed."
print(f"Initial output: {current_response}\n")
iteration = 0
while iteration < max_iterations:
if check_completeness(current_response):
print(f"Complete response achieved after {iteration + 1} iterations.")
return current_response
print(f"Iteration {iteration + 1}: Response incomplete. Expanding...")
expand_prompt = f"The following response is incomplete. Please expand on it to make it more comprehensive:\n\n{current_response}"
new_response = get_completion(expand_prompt)
if new_response is None:
return f"Expansion failed at iteration {iteration + 1}."
current_response = new_response
print(f"Expanded response: {current_response}\n")
iteration += 1
print(f"Maximum iterations ({max_iterations}) reached without achieving completeness.")
return current_response
# Example usage
initial_prompt = "Explain the process of photosynthesis."
final_result = looping_prompt_chain(initial_prompt)
print("Final result:", final_result)
Eerst definiëren we een nieuwe functie, check_completeness(), die het taalmodel gebruikt om te bepalen of een antwoord volledig is of meer informatie nodig heeft.
Vervolgens starten we in de functie looping_prompt_chain() met de initiële prompt over fotosynthese. Na de eerste reactie gaan we een lus in:
- We controleren met check_completeness() of het huidige antwoord volledig is.
- Als het volledig is, stoppen we de lus en geven we het resultaat terug.
- Als het onvolledig is, genereren we een nieuwe prompt om het vorige antwoord uit te breiden.
- We halen vervolgens een nieuw antwoord op op basis van deze uitbreidingsprompt.
Dit proces gaat door totdat we een antwoord hebben dat als volledig wordt beschouwd of totdat we het maximum aantal iteraties (standaard 5) bereiken.
De lus zorgt ervoor dat we het antwoord blijven verfijnen en uitbreiden totdat het volledig is of we de limiet bereiken.
Als je deze code draait, probeert hij een uitgebreide uitleg van fotosynthese te geven, eventueel via meerdere iteraties als de initiële antwoorden onvolledig zijn. Zo ontstaat een grondigere en adaptieve keten van prompts met als doel een volledig eindresultaat.
Praktische toepassingen van prompt chaining
Prompt chaining kan de capaciteiten van LLM’s in uiteenlopende toepassingen aanzienlijk vergroten. In deze sectie verkennen we een aantal praktische usecases en laten we zien hoe je prompt chaining inzet voor realistische taken.
Vragen beantwoorden over documenten
Je kunt prompt chaining gebruiken om lange documenten samen te vatten en vervolgens antwoorden op specifieke vragen te genereren. Dit houdt in dat je het document eerst in behapbare secties opdeelt, elke sectie samenvat en deze samenvattingen daarna gebruikt om gedetailleerde vragen te beantwoorden.
Zo implementeer je dit:
def split_document(document, max_length=1000):
"""Split the document into sections of approximately max_length characters."""
words = document.split()
sections = []
current_section = []
current_length = 0
for word in words:
if current_length + len(word) + 1 > max_length and current_section:
sections.append(' '.join(current_section))
current_section = []
current_length = 0
current_section.append(word)
current_length += len(word) + 1
if current_section:
sections.append(' '.join(current_section))
return sections
def summarize_section(section):
prompt = f"Summarize the following text in a concise manner:\n\n{section}"
return get_completion(prompt)
def answer_question(summaries, question):
context = "\n\n".join(summaries)
prompt = f"Given the following context, answer the question:\n\nContext:\n{context}\n\nQuestion: {question}"
return get_completion(prompt)
def document_qa(document, questions):
# Step 1: Split the document
sections = split_document(document)
print(f"Document split into {len(sections)} sections.")
# Step 2: Summarize each section
summaries = []
for i, section in enumerate(sections):
summary = summarize_section(section)
summaries.append(summary)
print(f"Section {i+1} summarized.")
# Step 3: Answer questions
answers = []
for question in questions:
answer = answer_question(summaries, question)
answers.append((question, answer))
return answers
# Example usage
long_document = """
[Insert a long document here. For brevity, we are using a placeholder.
In a real scenario, this would be a much longer text, maybe several
paragraphs or pages about a specific topic.]
This is a long document about climate change. It discusses various aspects
including causes, effects, and potential solutions. The document covers
topics such as greenhouse gas emissions, rising global temperatures,
melting ice caps, sea level rise, extreme weather events, impact on
biodiversity, and strategies for mitigation and adaptation.
The document also explores the economic implications of climate change,
international agreements like the Paris Agreement, renewable energy
technologies, and the role of individual actions in combating climate change.
[Continue with more detailed information about climate change...]
"""
questions = [
"What are the main causes of climate change mentioned in the document?",
"What are some of the effects of climate change discussed?",
"What solutions or strategies are proposed to address climate change?"
]
results = document_qa(long_document, questions)
for question, answer in results:
print(f"\nQ: {question}")
print(f"A: {answer}")
Deze code laat zien hoe je prompt chaining inzet voor complexe taken als documentanalyse en vraagbeantwoording. Het breekt een grote taak (een lang document begrijpen) op in kleinere stappen (secties samenvatten). De output van de ene stap (samenvattingen) dient als input voor de volgende (vragen beantwoorden). Zo kun je documenten verwerken die te lang zijn voor één prompt.
Als je deze code met een echt, lang document draait, wordt het document in behapbare secties gesplitst, elke sectie samengevat en deze samenvattingen gebruikt om de vragen over oorzaken, effecten en oplossingen rond klimaatverandering te beantwoorden.
Tekstgeneratie met factcheck
Tekstgeneratie met feitelijke verificatie houdt in dat je tekst genereert en factchecking-stappen in de promptketen opneemt. Zo zorg je dat de output niet alleen samenhangend is, maar ook accuraat.
def generate_text(topic):
prompt = f"Write a short paragraph about {topic}."
return get_completion(prompt)
def extract_facts(text):
prompt = f"Extract the key factual claims from the following text, listing each claim on a new line:\n\n{text}"
return get_completion(prompt)
def verify_facts(facts):
verified_facts = []
for fact in facts.split('\n'):
if fact.strip():
prompt = f"Verify the following statement and respond with 'True' if it's factually correct, 'False' if it's incorrect, or 'Uncertain' if it can't be verified without additional research: '{fact}'"
verification = get_completion(prompt)
verified_facts.append((fact, verification.strip()))
return verified_facts
def revise_text(original_text, verified_facts):
context = "Original text:\n" + original_text + "\n\nVerified facts:\n"
for fact, verification in verified_facts:
context += f"- {fact}: {verification}\n"
prompt = f"{context}\n\nRewrite the original text, keeping the verified facts, removing or correcting any false information, and indicating any uncertain claims as 'It is claimed that...' or similar phrasing."
return get_completion(prompt)
def text_generation_with_verification(topic):
print(f"Generating text about: {topic}")
# Step 1: Generate initial text
initial_text = generate_text(topic)
print("\nInitial Text:")
print(initial_text)
# Step 2: Extract facts
extracted_facts = extract_facts(initial_text)
print("\nExtracted Facts:")
print(extracted_facts)
# Step 3: Verify facts
verified_facts = verify_facts(extracted_facts)
print("\nVerified Facts:")
for fact, verification in verified_facts:
print(f"- {fact}: {verification}")
# Step 4: Revise text
revised_text = revise_text(initial_text, verified_facts)
print("\nRevised Text:")
print(revised_text)
return revised_text
# Example usage
topic = "the effects of climate change on polar bears"
final_text = text_generation_with_verification(topic)
De functie text_generation_with_verification() regelt het hele proces. Eerst genereert generate_text() een eerste alinea over het onderwerp. Daarna haalt extract_facts() de kernclaims uit de tekst. verify_facts() controleert deze claims en labelt ze als True, False of Uncertain. Tot slot herschrijft revise_text() de originele tekst, corrigeert fouten en markeert onzekere informatie. Zo wordt de uiteindelijke tekst zowel informatief als accuraat.
De promptketen vindt plaats in meerdere stappen: de initiële tekstgeneratie, het extraheren van feiten uit de gegenereerde tekst, de verificatie van elk feit en de herziening van de tekst op basis van de geverifieerde feiten.
Als je deze code draait met een onderwerp als "de effecten van klimaatverandering op ijsberen", wordt eerst tekst gegenereerd, vervolgens worden feitelijke claims eruit gehaald, elk van die claims geverifieerd en de tekst herzien op basis van de verificatie—zodat de output accurater is. Je kunt uiteraard je eigen onderwerp kiezen!
Codegeneratie met debugging
Prompt chaining gebruiken om code te schrijven en die daarna te testen kan de ontwikkeling versnellen. Deze aanpak helpt te zorgen dat de code correct werkt en doet wat ze moet doen—niet alleen foutloos draait.
def generate_code(task):
prompt = f"Write a Python function to {task}. Include comments explaining the code."
return get_completion(prompt)
def generate_test_cases(code):
prompt = f"Given the following Python code, generate 3 test cases to verify its functionality. Include both input and expected output for each test case:\n\n{code}"
return get_completion(prompt)
def run_tests(code, test_cases):
prompt = f"""
Given the following Python code and test cases, run the tests and report the results.
If any tests fail, explain why and suggest fixes.
Code:
{code}
Test Cases:
{test_cases}
For each test case, respond with:
1. "PASS" if the test passes
2. "FAIL" if the test fails, along with an explanation of why it failed and a suggested fix
"""
return get_completion(prompt)
def debug_code(code, test_results):
prompt = f"""
Given the following Python code and test results, debug the code to fix any issues.
Provide the corrected code along with explanations of the changes made.
Original Code:
{code}
Test Results:
{test_results}
"""
return get_completion(prompt)
def code_generation_with_debugging(task):
print(f"Generating code for task: {task}")
# Step 1: Generate initial code
initial_code = generate_code(task)
print("\nInitial Code:")
print(initial_code)
# Step 2: Generate test cases
test_cases = generate_test_cases(initial_code)
print("\nGenerated Test Cases:")
print(test_cases)
# Step 3: Run tests
test_results = run_tests(initial_code, test_cases)
print("\nTest Results:")
print(test_results)
# Step 4: Debug code if necessary
if "FAIL" in test_results:
print("\nDebugging code...")
debugged_code = debug_code(initial_code, test_results)
print("\nDebugged Code:")
print(debugged_code)
# Optionally, you can run tests again on the debugged code
print("\nRe-running tests on debugged code...")
final_test_results = run_tests(debugged_code, test_cases)
print("\nFinal Test Results:")
print(final_test_results)
return debugged_code
else:
print("\nAll tests passed. No debugging necessary.")
return initial_code
# Example usage
task = "calculate the factorial of a number"
final_code = code_generation_with_debugging(task)
De functie code_generation_with_debugging() regelt het hele proces. Zo werkt het: eerst schrijft generate_code() Python-code voor de taak. Daarna maakt generate_test_cases() tests voor die code. run_tests() controleert of de code slaagt voor de tests. Als er tests falen, probeert debug_code() de problemen te verhelpen.
Let op dat elke stap voortbouwt op de vorige. Je begint met code schrijven, maakt daarna tests, voert ze uit en lost eventuele problemen op. Zo breek je programmeren op in kleinere, beheersbare stappen. Deze methode laat zien hoe prompt chaining complexe taken zoals programmeren kan aanpakken. Het bootst na hoe ontwikkelaars werken: schrijven, testen en fixen. Elke stap gebruikt de vorige om de code stap voor stap te verbeteren.
Als je deze code draait met een taak als "het faculteit van een getal berekenen", wordt eerst Python-code gegenereerd, vervolgens testcases gemaakt en de tests “gesimuleerd” uitgevoerd. Falen er tests, dan wordt geprobeerd de code te debuggen en daarna de tests opnieuw te draaien.
Meer-staps redeneertaken
Prompt chaining kan complexe problemen oplossen die meerdere redeneerstappen vereisen, zoals wiskundige verhaalsommen of logische puzzels. Elke stap bouwt voort op de vorige, voor een gestructureerde en grondige aanpak.
def solve_step_by_step(problem):
steps = []
current_problem = problem
while True:
prompt = f"Solve the following problem step by step. Provide the next step only and explain it clearly:\n\n{current_problem}"
step = get_completion(prompt)
if step is None or "solution" in step.lower():
break
steps.append(step)
current_problem = f"{current_problem}\n\n{step}"
print(f"Step {len(steps)}: {step}\n")
return steps
def combine_steps(steps):
combined_steps = "\n".join(steps)
prompt = f"Combine the following steps into a coherent solution for the problem:\n\n{combined_steps}"
return get_completion(prompt)
def multi_step_reasoning(problem):
print(f"Solving problem: {problem}")
# Step 1: Solve step by step
steps = solve_step_by_step(problem)
# Step 2: Combine steps into a final solution
final_solution = combine_steps(steps)
print("\nFinal Solution:")
print(final_solution)
return final_solution
# Example usage
problem = "A car travels 60 miles per hour for 2 hours, then 40 miles per hour for 3 hours. What is the total distance traveled by the car?"
final_solution = multi_step_reasoning(problem)
Eerst breekt solve_step_by_step() het probleem op in kleinere delen. Het vraagt het AI-model om elke volgende stap, één voor één, totdat de oplossing compleet is. Elke stap wordt opgeslagen. Vervolgens neemt combine_steps() al deze stappen en vraagt het AI om ze samen te voegen tot één heldere uitleg. De functie get_completion() verzorgt het contact met de OpenAI API gedurende dit proces.
In dit voorbeeld wordt deze som opgelost: "Een auto rijdt 60 mijl per uur gedurende 2 uur en daarna 40 mijl per uur gedurende 3 uur. Wat is de totale afgelegde afstand?"
Als je deze code draait, wordt het probleem opgesplitst in kleinere redeneerstappen, elke stap verzameld en geprint, en worden de stappen gecombineerd tot een eindoplossing die ook geprint wordt.
Best practices voor prompt chaining
Het is essentieel om bepaalde best practices te volgen om prompt chaining zo effectief mogelijk te maken. Deze aandachtspunten zorgen voor robuuste, accurate en efficiënte ketens, wat leidt tot betere resultaten en betrouwbaardere LLM-toepassingen.
Promptontwerp
Duidelijke en beknopte prompts zijn essentieel voor goede resultaten met een LLM. Als je prompts rechttoe rechtaan zijn, begrijpt het model makkelijker wat je nodig hebt. Dat vermindert verwarring en verbetert de kwaliteit van de antwoorden.
Enkele tips:
- Gebruik eenvoudige taal: Vermijd moeilijke woorden en vakjargon.
- Wees direct: Zeg duidelijk wat je wilt, zonder onnodige details.
- Focus op één taak: Elke prompt moet één taak of vraag adresseren.
Bijvoorbeeld:
- In plaats van: "Kun je de belangrijkste punten van de historische trends in wereldwijde temperaturen in de afgelopen eeuw samenvatten, met focus op significante veranderingen en hun mogelijke oorzaken, en noemenswaardige gebeurtenissen die deze trends beïnvloed kunnen hebben?"
- Gebruik: "Vat de belangrijkste punten van historische wereldwijde temperatuurtrends in de afgelopen eeuw samen."
Ook goed gestructureerde prompts helpen de LLM de logische flow van een taak te volgen. Als je prompts georganiseerd en coherent zijn, kan het model beter begrijpen en passend reageren.
Enkele tips:
- Breek complexe taken op: Verdeel de taak in kleinere, behapbare stappen.
- Zorg voor logische flow: Laat elke prompt voortbouwen op de vorige en logisch leiden naar de volgende.
Door je prompts zo te structureren, begeleid je de LLM stap voor stap door de taak, wat leidt tot betere en accuratere antwoorden. Bijvoorbeeld:
- Stap 1: "Noem de belangrijkste veranderingen in wereldwijde temperaturen in de afgelopen eeuw."
- Stap 2: "Identificeer mogelijke oorzaken voor elke belangrijke temperatuurverandering."
Experimenteren
Verschillende taken vragen om verschillende manieren van ketenen. De juiste methode kiezen kan veel verschil maken. Het is verstandig om verschillende benaderingen uit te proberen en te zien wat het beste werkt voor jouw doel. Door te testen en te vergelijken vind je de beste manier om goede resultaten te behalen.
Het is belangrijk om regelmatig te controleren hoe goed je promptketens werken. Kijk naar de nauwkeurigheid, volledigheid en relevantie van de outputs. Zo zie je wat goed gaat en wat beter kan. Door dit consequent te doen kun je bijsturen en verbeteren, zodat je het beste resultaat behaalt.
Iteratief verfijnen
Iteratieve verfijning op basis van feedback en resultaten leidt tot preciezere en effectievere prompts. Je kunt de prestaties van je LLM continu verbeteren door feedback uit outputs te verzamelen, tekortkomingen te identificeren en prompts dienovereenkomstig aan te passen. Zo worden je prompts na verloop van tijd steeds accurater en relevanter. Bijvoorbeeld:
- Initiële prompt: "Beschrijf de impact van klimaatverandering."
- Verfijnde prompt: "Beschrijf de impact van klimaatverandering op kustecosystemen in het afgelopen decennium."
Ketenstructuur verfijnen
De manier waarop je je promptketen ordent kan het eindresultaat sterk beïnvloeden. Pas de volgorde en logica van je prompts aan op basis van wat werkt. Zo zorg je dat elke stap logisch volgt op de vorige. Daarmee krijg je betere en consistenter redenerende antwoorden van de AI.
Foutafhandeling
Robuuste foutafhandeling zorgt ervoor dat de keten blijft functioneren, ook als individuele prompts falen. Door validiteitscontroles op outputs in te bouwen en fallback-prompts te gebruiken, kun je de LLM weer op koers brengen als er fouten optreden. Zo blijft de flow en betrouwbaarheid van de keten behouden.
Monitoren en loggen
Het is belangrijk om te volgen hoe goed je promptketens presteren. Zo zie je wat werkt en waar problemen zitten. Gebruik tools om belangrijke informatie vast te leggen, zoals input, output en doorlooptijd. Noteer bijvoorbeeld elke stap in de keten, wat die opleverde en eventuele fouten. Door dit te doen kun je het proces analyseren en verbeteren, wat tot betere resultaten leidt.
Door gedetailleerde logs bij te houden, kun je problemen sneller oplossen en je promptketens verbeteren. Sla deze gegevens netjes op, zodat je ze eenvoudig kunt analyseren en ervan kunt leren. Zo spoor je issues op en kun je fijnslijpen. Het resultaat: beter werkende ketens en accuratere antwoorden
Door deze best practices te volgen maak je effectieve en betrouwbare promptketens die de capaciteiten van LLM’s vergroten, zodat je betere prestaties en betekenisvollere resultaten behaalt voor uiteenlopende toepassingen.
Conclusie
In dit artikel hebben we prompt chaining verkend: een techniek om de prestaties van LLM’s bij complexe taken te verbeteren door ze op te delen in kleinere, beter beheersbare prompts. We hebben verschillende ketenmethoden, hun toepassingen en best practices behandeld om LLM’s effectief in te zetten voor uiteenlopende usecases.
Wil je meer leren over prompt engineering? Dan raad ik deze artikelen aan:
FAQs
Zijn er frameworks of tools die prompt chaining voor LLM’s faciliteren?
Hoewel er geen toegewijd framework is voor prompt chaining, kun je tools als LangChain, PyTorch en TensorFlow gebruiken om promptchaining-workflows te implementeren en te beheren, dankzij hun mogelijkheden voor het verwerken van sequentiële data en modeloutputs.
Wat zijn alternatieve manieren om de prestaties van LLM’s te verbeteren naast prompt chaining?
Fine-tunen op domeinspecifieke datasets, knowledge distillation, functie-integratie, iteratieve verfijning en parameterafstelling zijn enkele alternatieve benaderingen.
Ze bieden elk unieke voordelen en kunnen afzonderlijk of in combinatie worden gebruikt om de prestaties van LLM’s voor specifieke taken of usecases te verbeteren.
Kan prompt chaining worden geïntegreerd met geautomatiseerde systemen voor realtime toepassingen?
Ja, prompt chaining kan worden geïntegreerd in geautomatiseerde systemen zoals chatbots, virtuele assistenten en realtime data-analyseplatforms om de nauwkeurigheid en samenhang van hun antwoorden en outputs te verbeteren.
Wat zijn mogelijke uitdagingen bij het implementeren van prompt chaining in productieomgevingen?
Uitdagingen zijn onder meer het beheren van promptafhankelijkheden, het waarborgen van lage latency voor realtime toepassingen, het effectief afhandelen van fouten en onvolledige outputs, en het behouden van de schaalbaarheid en prestaties naarmate de taakcomplexiteit toeneemt.
Ana Rojo Echeburúa is een AI- en dataspecialist met een PhD in Toegepaste Wiskunde. Ze houdt ervan om data om te zetten in bruikbare inzichten en heeft ruime ervaring in het aansturen van technische teams. Ana werkt graag nauw samen met klanten om hun bedrijfsproblemen op te lossen en innovatieve AI-oplossingen te creëren. Ze staat bekend om haar probleemoplossend vermogen en heldere communicatie, en is gepassioneerd door AI, vooral generatieve AI. Ana zet zich in voor continue ontwikkeling en ethische AI, en voor het vereenvoudigen van complexe vraagstukken en het op een toegankelijke manier uitleggen van technologie.

