Course
Tutorial de encadeamento de prompts: O que é Prompt Chaining e como usá-lo?
Você já tentou montar um móvel sem ler as instruções? Se você tiver sorte, poderá juntar algumas peças, mas o resultado pode ser bem confuso sem uma orientação passo a passo. Isso é semelhante ao desafio enfrentado por modelos de linguagem grandes (LLMs) quando lidam com problemas complexos. Esses modelos têm um potencial incrível, mas muitas vezes não atingem o objetivo quando uma tarefa exige um raciocínio detalhado e de várias etapas.
Quando recebem uma única solicitação, os LLMs podem fornecer respostas muito amplas, sem profundidade ou sem detalhes críticos. Essa limitação decorre da dificuldade de capturar todo o contexto necessário e fornecer orientação adequada em um único prompt.
A solução para isso é encadeamento de avisos.
O encadeamento de prompts envolve a divisão de uma tarefa complexa em uma série de prompts menores e mais gerenciáveis. Cada prompt aborda uma parte específica da tarefa, e o resultado de um prompt serve como entrada para o próximo. Esse método permite uma abordagem mais estruturada, guiando o LLM por uma cadeia de etapas de raciocínio que levam a uma resposta mais precisa e abrangente. Usando uma sequência lógica de prompts, podemos usar plenamente os LLMs para resolver problemas complexos de forma eficaz.
Este tutorial faz parte do meu "Prompt Engineering": Série de postagens no blog "Do zero ao herói":
- Engenharia imediata para todos
- Prompting de disparo zero
- Prompting de poucos disparos
- Encadeamento de prompts
O que é Prompt Chaining?
O encadeamento de prompts é um método em que a saída de um prompt do LLM é usada como entrada para o próximo prompt em uma sequência. Essa técnica envolve a criação de uma série de prompts conectados, cada um focado em uma parte específica do problema geral. Seguir essa sequência permite que o LLM seja guiado por um processo de raciocínio estruturado, ajudando-o a produzir respostas mais precisas e detalhadas.
O principal objetivo do encadeamento imediato é melhorar o desempenho, a confiabilidade e a clareza dos aplicativos LLM. Em tarefas complexas, um único prompt geralmente não oferece profundidade e contexto suficientes para uma boa resposta. O encadeamento de prompts resolve isso dividindo a tarefa em etapas menores, garantindo que cada etapa seja tratada com cuidado. Esse método melhora a qualidade do resultado do LLM e facilita a compreensão de como o resultado final foi alcançado.
Vamos dar uma olhada em alguns dos benefícios do encadeamento de prompts:
Benefício |
Descrição |
Exemplo |
Quebra a complexidade |
Decompõe tarefas complexas em subtarefas menores e gerenciáveis, permitindo que o LLM se concentre em um aspecto de cada vez. |
Gerar um trabalho de pesquisa passo a passo (esboço, seções, conclusão) em vez de tudo de uma vez. |
Melhora a precisão |
Orienta o raciocínio do LLM por meio de etapas intermediárias, fornecendo mais contexto para respostas precisas e relevantes. |
Diagnosticar um problema técnico identificando os sintomas, reduzindo as causas e sugerindo soluções. |
Aumenta a capacidade de explicação |
Aumenta a transparência no processo de tomada de decisão do LLM, facilitando a compreensão de como as conclusões são alcançadas. |
Explicar uma decisão jurídica delineando as leis relevantes, aplicando-as a um caso e chegando a uma conclusão com cada etapa claramente documentada. |
Como implementar o encadeamento de prompts
A implementação do encadeamento de prompts envolve uma abordagem sistemática para dividir uma tarefa complexa e orientar um LLM por meio de uma série de etapas bem definidas.
Vamos ver como você pode criar e executar com eficiência uma cadeia de prompts.
Identificar subtarefas
A primeira etapa do encadeamento de solicitações é decompor a tarefa complexa em subtarefas menores e gerenciáveis. Cada subtarefa deve representar um aspecto distinto do problema geral. Dessa forma, o LLM pode se concentrar em uma parte de cada vez.
Por exemplo, suponha que você queira que o LLM escreva um relatório abrangente sobre mudanças climáticas. As subtarefas podem incluir:
- Pesquisa de dados climáticos históricos
- Resumir as principais descobertas da literatura científica
- Analisar o impacto das mudanças climáticas em diferentes ecossistemas
- Propor possíveis soluções e estratégias de mitigação
Sugestões de design
Em seguida, crie avisos claros e concisos para cada subtarefa. Cada solicitação deve ser específica e direta, garantindo que o LLM compreenda a tarefa e possa gerar resultados relevantes. É importante ressaltar que o resultado de um prompt deve ser adequado como entrada para o próximo, criando um fluxo de informações.
Para nossas subtarefas acima, poderíamos criar os seguintes prompts:
- Subtarefa 1 Prompt: "Resuma as principais tendências das mudanças na temperatura global no último século."
- Subtarefa 2 Prompt: "Com base nas tendências identificadas, liste os principais estudos científicos que discutem as causas dessas mudanças."
- Subtarefa 3 Prompt: "Resuma as descobertas dos estudos listados, concentrando-se no impacto das mudanças climáticas nos ecossistemas marinhos."
- Subtarefa 4 Prompt: "Proponha três estratégias para mitigar o impacto das mudanças climáticas nos ecossistemas marinhos com base nas descobertas resumidas."
Execução em cadeia
Agora, precisamos executar os prompts sequencialmente, passando a saída de um prompt como entrada para o próximo. Essa execução passo a passo garante que o LLM se baseie em seus resultados anteriores, criando um resultado coeso e abrangente.
No nosso exemplo, os resultados das nossas subtarefas seriam mais ou menos assim:
- Saída da subtarefa 1: "A temperatura global aumentou aproximadamente 1,2 grau Celsius no último século, com aumentos significativos observados nos últimos 20 anos."
- Entrada para a subtarefa 2: "Considerando que as temperaturas globais aumentaram 1,2 grau Celsius no último século, liste os principais estudos científicos que discutem as causas dessas mudanças."
- Resultado da subtarefa 2: "Os principais estudos incluem: 'The Role of Greenhouse Gases in Global Warming' (O Papel dos Gases de Efeito Estufa no Aquecimento Global), por Dr. Smith, 'Deforestation and Climate Change' (Desflorestamento e Mudança Climática), do Dr. Jones, e 'Oceanic Changes and Climate Patterns' (Mudanças oceânicas e padrões climáticos), do dr. Lee."
- Entrada para a subtarefa 3: Resuma as descobertas de "The Role of Greenhouse Gases in Global Warming" (O papel dos gases de efeito estufa no aquecimento global), do Dr. Smith, 'Deforestation and Climate Change' (Desflorestamento e Mudança Climática), do Dr. Jones, e 'Oceanic Changes and Climate Patterns' (Mudanças oceânicas e padrões climáticos), do dr. Lee, com foco no impacto da mudança climática nos ecossistemas marinhos".
Tratamento de erros
A implementação de mecanismos de tratamento de erros é fundamental para resolver possíveis problemas durante a execução imediata. Isso pode incluir a configuração de verificações para verificar a qualidade e a relevância do resultado antes de prosseguir para o próximo prompt e a criação de prompts de fallback para orientar o LLM de volta ao programa se ele se desviar do caminho esperado. Por exemplo:
- Verificação de erro 1: Após cada saída, verifique se as informações são relevantes e completas. Se o resumo das tendências das mudanças na temperatura global estiver incompleto, peça ao LLM que forneça mais detalhes.
- Fallback Prompt: Se o LLM não conseguir listar estudos científicos relevantes, use uma solicitação mais específica, como "Liste cinco estudos revisados por pares da última década que discutam as causas do aumento da temperatura global".
Implementação
Vamos ver como você pode implementar isso em Python!
Etapa 1: Configuração do ambiente
Primeiro, precisamos importar as bibliotecas necessárias. Usaremos a classe OpenAI
do pacote openai
e os
para manipular as variáveis de ambiente.
import openai
import os
É fundamental armazenar informações confidenciais, como chaves de API, de forma segura. Uma maneira de conseguir isso é definir a chave da API como uma variável de ambiente. Você pode fazer isso usando uma API da OpenAI da OpenAI.
os.environ['OPENAI_API_KEY'] = 'your-api-key-here'
Certifique-se de substituir 'your-api-key-here'
por sua chave real da API da OpenAI.
Com a chave de API definida, agora você pode inicializar o cliente OpenAI. Esse cliente será usado para fazer chamadas de API para os serviços da OpenAI.
Client = OpenAI ()
Etapa 2: Definição de uma função para interagir com a API de conclusão de bate-papo da OpenAI.
Agora, criaremos uma função Python para interagir com a API de conclusão de bate-papo da OpenAI. Essa função solicitará a API e retornará a resposta gerada.
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
Vamos detalhar essa função-it:
- Recebe um prompt e um parâmetro de modelo opcional.
- Faz uma chamada de API para o OpenAI usando o ponto de extremidade de conclusões de bate-papo.
- Configura a conversa com uma mensagem do sistema e uma mensagem do usuário (o prompt)
- Defina a temperatura como 0 para obter saídas mais determinísticas (aumente a temperatura para obter saídas mais criativas).
- Retorna o conteúdo da resposta ou
None
se ocorrer um erro.
Etapa 3: Encadeamento de vários prompts
Agora, criaremos uma função Python que encadeia vários prompts, alimentando a saída de um prompt como entrada para o próximo.
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
A função prompt_chain
implementa o encadeamento de prompts. It:
- Começa com um prompt inicial e é concluído.
- Itera através de uma lista de prompts de acompanhamento.
- Para cada solicitação de acompanhamento, ele combina a solicitação com a saída anterior, obtém uma conclusão para essa solicitação combinada e atualiza o resultado.
- Se alguma etapa falhar, você receberá uma mensagem de erro.
- A saída de cada etapa é impressa para que você tenha visibilidade.
Etapa 4: Exemplo de uso
Agora, demonstraremos como você pode usar a função prompt_chain
para criar uma sequência de prompts que se baseiam uns nos outros. Este exemplo se concentrará no resumo das principais tendências das mudanças de temperatura global e na exploração de estudos científicos relacionados e estratégias de mitigação, mas você pode aplicá-lo ao seu próprio caso de uso!
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)
Aqui, definimos um prompt inicial sobre mudanças na temperatura global e, em seguida, configuramos uma lista de prompts de acompanhamento que se baseiam uns nos outros. Em seguida, chamamos a função prompt_chain
com esses prompts e, por fim, imprimimos o resultado final.
Como você trabalha em conjunto
Vamos resumir o processo:
- O prompt inicial apresenta um resumo das tendências de temperatura.
- O primeiro acompanhamento usa esse resumo para encontrar estudos relevantes.
- A segunda continuação resume as descobertas desses estudos sobre os ecossistemas marinhos.
- O prompt final usa todas essas informações para propor estratégias de atenuação.
Esse encadeamento permite uma abordagem passo a passo para consultas complexas, em que cada etapa se baseia nas informações das etapas anteriores.
Técnicas de encadeamento de prompts
O encadeamento de prompts pode ser implementado de várias maneiras para atender a diferentes tipos de tarefas e requisitos. Aqui, exploramos três técnicas principais: Encadeamento sequencial, encadeamento condicional e encadeamento em looping.
Encadeamento sequencial
O encadeamento sequencial envolve a vinculação de prompts em uma sequência linear e direta. Cada prompt depende do resultado do anterior, criando um fluxo passo a passo de informações e tarefas. Essa técnica é ideal para tarefas que exigem uma progressão lógica de um estágio para o outro, como:
- Resumo de texto: Dividir um documento longo em seções resumidas e, em seguida, combinar esses resumos em um resumo geral coeso.
- Geração de código: Geração de trechos de código passo a passo, como a criação de definições de funções, a implementação dessas funções e, por fim, a criação de casos de teste.
O trecho de código na seção anterior é um exemplo de encadeamento sequencial.
Encadeamento condicional
O encadeamento condicional introduz ramificações na cadeia de prompts com base na saída do LLM. Essa técnica permite fluxos de trabalho mais flexíveis e adaptáveis, possibilitando que o LLM siga caminhos diferentes, dependendo das respostas geradas.
Vamos ver como podemos implementar o encadeamento condicional para realizar a análise de sentimentos.
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)
Primeiro, definimos uma nova função, analyze_sentiment()
, que usa o modelo de linguagem para determinar o sentimento de um determinado texto. Em seguida, na função conditional_prompt_chain()
, começamos com o prompt inicial sobre a adoção de energia renovável. Depois de obter a resposta inicial, analisamos seu sentimento. Com base no sentimento, escolhemos um prompt de acompanhamento diferente:
- Para um sentimento positivo, perguntamos sobre oportunidades.
- Para um sentimento negativo, perguntamos sobre soluções.
- Para um sentimento neutro, perguntamos sobre as principais áreas de foco.
O prompt de acompanhamento escolhido é então enviado ao modelo de linguagem junto com o contexto da resposta inicial. O resultado final é a resposta a esse prompt de acompanhamento condicional.
Observe que a escolha do segundo prompt não é predeterminada, mas depende do conteúdo da primeira resposta. Além disso, o fluxo da conversa se adapta com base na análise de sentimentos, mostrando como a cadeia pode se ramificar em diferentes caminhos. Isso permite interações mais dinâmicas e sensíveis ao contexto com o modelo de linguagem.
Quando você executar esse código, a pergunta específica de acompanhamento dependerá do fato de a análise inicial da adoção de energia renovável ser percebida como positiva, negativa ou neutra. Isso cria uma cadeia de prompts mais adaptável e responsiva.
Encadeamento em looping
O encadeamento de loops envolve a criação de loops em um encadeamento de prompt para iterar sobre os dados ou executar tarefas repetitivas. Essa técnica é útil ao lidar com listas ou coleções de itens que exigem etapas de processamento semelhantes. Alguns dos benefícios e desafios dessa abordagem são:
- Eficiência: Automatiza tarefas repetitivas, economizando tempo e esforço.
- Processamento de dados: Adequado para tarefas como processamento de vários registros, compactação em lote ou aprimoramentos iterativos.
- Desafios: Requer um tratamento cuidadoso para evitar loops infinitos e garantir que cada iteração produza um progresso significativo.
Vejamos como o encadeamento de looping seria implementado para uma tarefa de completude de texto:
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)
Primeiro, definimos uma nova função, check_completeness()
, que usa o modelo de linguagem para determinar se uma determinada resposta está completa ou precisa de mais informações.
Em seguida, na função looping_prompt_chain()
, começamos com o prompt inicial sobre fotossíntese. Depois de obter a resposta inicial, entramos em um loop:
- Verificamos se a resposta atual está completa usando
check_completeness().
- Se estiver concluído, saímos do loop e retornamos o resultado.
- Se a resposta estiver incompleta, geramos um novo prompt solicitando que você amplie a resposta anterior.
- Em seguida, obtemos uma nova resposta com base nesse prompt de expansão.
Esse processo continua até que você receba uma resposta considerada completa ou atinja o número máximo de iterações (o padrão é 5).
O loop garante que você continue refinando e expandindo a resposta até que ela seja considerada completa ou até atingirmos o limite de iteração.
Quando você executar esse código, ele tentará fornecer uma explicação abrangente da fotossíntese, podendo passar por várias iterações de expansão se as respostas iniciais forem consideradas incompletas. Isso cria uma cadeia de prompts mais completa e adaptável, visando a um resultado final abrangente.
Aplicações práticas do Prompt Chaining
O encadeamento imediato pode aumentar significativamente os recursos dos LLMs em vários aplicativos. Nesta seção, exploramos alguns usos práticos do encadeamento de prompts, demonstrando como ele pode ser aplicado a tarefas do mundo real.
Resposta a perguntas sobre documentos
O encadeamento de prompts pode ser usado para resumir documentos longos e, em seguida, gerar respostas a perguntas específicas. Isso envolve primeiro dividir o documento em seções gerenciáveis, resumir cada seção e, em seguida, usar esses resumos para responder a perguntas detalhadas.
Vamos ver como você pode implementar isso:
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}")
Esse trecho de código demonstra como o encadeamento de prompts pode ser usado para tarefas complexas, como análise de documentos e resposta a perguntas. Ele divide uma tarefa grande (compreender um documento longo) em etapas menores e gerenciáveis (resumir seções). Ele usa o resultado de uma etapa (resumos) como entrada para a próxima (responder a perguntas). Ele permite o processamento de documentos que podem ser muito longos para serem processados em um único prompt.
Quando você executar esse código com um documento real e longo, ele dividirá o documento em seções gerenciáveis, resumirá cada seção e usará esses resumos para responder às perguntas fornecidas sobre as causas, os efeitos e as soluções das mudanças climáticas.
Geração de texto com verificação de fatos
A geração de texto com verificação de fatos envolve a geração de texto e a incorporação de etapas de verificação de fatos na cadeia de prompts. Isso garante que a saída não seja apenas coerente, mas também precisa.
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)
A função text_generation_with_verification()
gerencia todo o processo. Você começa usando o site generate_text()
para criar um parágrafo inicial sobre o tópico. Em seguida, extract_facts()
extrai as principais afirmações desse texto. verify_facts()
verifica essas afirmações, rotulando-as como Verdadeiras, Falsas ou Incertas. Por fim, revise_text()
reescreve o texto original, corrigindo erros e anotando informações incertas. Esse processo ajuda a garantir que o texto final seja informativo e preciso.
O encadeamento do prompt ocorre em várias etapas: a geração inicial do texto, a extração de fatos do texto gerado, a verificação de cada fato extraído e a revisão do texto com base nos fatos verificados.
Quando você executar esse código com um tópico como "os efeitos das mudanças climáticas nos ursos polares", ele gerará um texto inicial sobre o tópico, extrairá afirmações factuais desse texto, verificará cada uma dessas afirmações e revisará o texto com base nos fatos verificados, garantindo um resultado final mais preciso. Lembre-se de que você pode usar o tema de sua preferência!
Geração de código com depuração
Usar o encadeamento de prompts para escrever o código e depois testá-lo pode acelerar o desenvolvimento. Esse método ajuda a garantir que o código funcione corretamente e faça o que deve ser feito. Isso vai além de apenas garantir que o código seja executado sem erros.
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)
A função code_generation_with_debugging()
gerencia todo o processo. Funciona da seguinte maneira: Primeiro, generate_code()
escreve algum código Python para a tarefa. Em seguida, generate_test_cases()
cria testes para esse código. run_tests()
verifica se o código passa nesses testes. Se algum teste falhar, o debug_code()
tentará corrigir os problemas.
Observe que cada etapa se baseia na anterior. Você começa escrevendo o código, depois faz testes, executa-os e corrige os problemas. Isso divide a codificação em etapas menores e mais fáceis. Esse método mostra como o encadeamento de prompts pode lidar com tarefas complexas, como a codificação. Ele copia a forma como os programadores reais trabalham: escrever código, testá-lo e corrigir qualquer problema. Cada etapa usa o que foi feito antes, permitindo o aprimoramento constante do código.
Quando você executar esse código com uma tarefa como "calcular o fatorial de um número", ele gerará o código Python inicial para calcular o fatorial, criará casos de teste para essa função, simulará a execução desses testes e relatará os resultados. Se algum teste falhar, ele tentará depurar e corrigir o código e, em seguida, executará novamente os testes.
Tarefas de raciocínio em várias etapas
O encadeamento de prompts pode resolver problemas complexos que exigem várias etapas de raciocínio, como problemas matemáticos com palavras ou quebra-cabeças lógicos. Cada etapa se baseia na anterior, garantindo uma abordagem estruturada e completa.
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)
Primeiro, solve_step_by_step()
divide o problema em partes menores. Ele solicita ao modelo de IA cada etapa, uma a uma, até que a solução esteja completa. Cada etapa é salva. Em seguida, o site combine_steps()
executa todas essas etapas e pede à IA que as mescle em uma explicação clara. A função get_completion()
trata da comunicação com a API da OpenAI durante todo esse processo.
Para este exemplo, você resolverá esse problema: "Um carro dirige a 60 milhas por hora durante 2 horas, depois a 40 milhas por hora durante 3 horas. Qual é a extensão total?"
Quando você executar esse código, ele dividirá o problema em etapas de raciocínio menores, coletará e imprimirá cada etapa, combinará as etapas em uma solução final e a imprimirá.
Práticas recomendadas para encadeamento de prompts
É essencial seguir algumas práticas recomendadas para maximizar a eficácia do encadeamento de avisos. Essas práticas garantem que suas cadeias sejam robustas, precisas e eficientes, levando a melhores resultados e a solicitações de LLM mais confiáveis.
Design imediato
O uso de prompts claros e concisos é essencial para que você obtenha os melhores resultados em um LLM. Quando seus prompts são diretos, o modelo pode entender facilmente o que você precisa, o que reduz a confusão e melhora a qualidade das respostas.
Aqui estão algumas dicas:
- Use uma linguagem simples: Evite palavras complexas e jargões técnicos.
- Seja direto: Declare claramente o que você deseja sem acrescentar detalhes desnecessários.
- Concentre-se em uma tarefa: Cada prompt deve abordar uma única tarefa ou pergunta.
Por exemplo:
- Em vez de: "Você poderia resumir os pontos principais das tendências históricas das temperaturas globais no último século, concentrando-se em quaisquer mudanças significativas e suas possíveis causas, bem como em eventos notáveis que possam ter influenciado essas tendências?"
- Use: "Resuma os pontos principais das tendências históricas da temperatura global no último século."
O uso de prompts bem estruturados também é fundamental para ajudar o LLM a seguir o fluxo lógico de uma tarefa. Quando seus prompts são organizados e coerentes, o modelo pode entender melhor e responder adequadamente.
Aqui estão algumas dicas:
- Divida tarefas complexas: Divida a tarefa em etapas menores e gerenciáveis.
- Garantir o fluxo lógico: Certifique-se de que cada prompt se baseie no anterior e conduza logicamente ao próximo.
Estruturando seus prompts dessa forma, você orienta o LLM na tarefa passo a passo, levando a respostas melhores e mais precisas. Por exemplo:
- Etapa 1: "Liste as principais mudanças nas temperaturas globais durante o século passado."
- Etapa 2: "Identifique as possíveis causas de cada grande mudança nas temperaturas globais."
Experimentação
Tarefas diferentes precisam de maneiras diferentes de encadear prompts. Escolher o método certo para sua tarefa pode fazer uma grande diferença. É uma boa ideia experimentar diferentes abordagens e ver o que funciona melhor para o que você está tentando fazer. Testes e comparações podem ajudar você a encontrar a melhor maneira de obter bons resultados.
É importante que você verifique com frequência o funcionamento das suas correntes de transmissão. Observe se os resultados são precisos, completos e relevantes. Isso ajuda você a ver o que está funcionando e o que precisa ser melhorado. Ao fazer isso regularmente, você pode fazer alterações e melhorias conforme necessário e garantir que está obtendo os melhores resultados.
Refinamento iterativo
O refinamento iterativo baseado em feedback e resultados leva a prompts mais precisos e eficazes. Você pode melhorar continuamente o desempenho do seu LLM coletando feedback dos resultados, identificando as deficiências e ajustando os prompts de acordo. Esse processo contínuo garante que seus prompts se tornem cada vez mais precisos e relevantes ao longo do tempo. Por exemplo:
- Solicitação inicial: "Descreva o impacto da mudança climática."
- Prompt refinado: "Descreva o impacto da mudança climática nos ecossistemas costeiros na última década."
Refinar a estrutura da cadeia
A maneira como você organiza sua cadeia de prontidão pode realmente afetar o resultado final. Alterar a ordem e a lógica dos seus prompts é útil com base no que você vê funcionando. Isso garante que cada etapa faça sentido após a anterior. Ao fazer isso, você pode obter respostas melhores e mais lógicas da IA.
Tratamento de erros
O tratamento robusto de erros garante que a cadeia de prompts possa continuar funcionando mesmo que os prompts individuais falhem. Ao configurar verificações de validade de saída e usar prompts de fallback, você pode orientar o LLM de volta ao programa quando ocorrerem erros. Essa abordagem mantém o fluxo e a confiabilidade da cadeia de prontidão, garantindo um desempenho consistente.
Monitoramento e registro
É importante que você fique de olho no funcionamento das suas cadeias de prontidão. Isso ajuda você a entender o que é eficaz e a identificar quaisquer problemas. Use ferramentas para registrar informações importantes, como o que entra nos prompts, o que sai e quanto tempo leva. Por exemplo, anote cada etapa da cadeia, o que é produzido e os erros que ocorrem. Se você fizer isso, poderá estudar o processo e aprimorá-lo, o que levará a melhores resultados.
A manutenção de registros detalhados ajuda você a corrigir problemas e a melhorar suas cadeias de prontidão. Armazene esses registros de forma organizada para que seja mais fácil estudá-los e aprender com eles. Isso ajuda você a identificar problemas e ajustar suas cadeias de prontidão. Como resultado, você pode fazer com que eles funcionem melhor e forneçam respostas mais precisas
Seguir essas práticas recomendadas permitirá que você crie cadeias de prompt eficazes e confiáveis que aprimorem os recursos dos LLMs, garantindo que você obtenha melhor desempenho e resultados mais significativos em vários aplicativos.
Conclusão
Neste artigo, exploramos o encadeamento de prompts, uma técnica para melhorar o desempenho dos LLMs em tarefas complexas, dividindo-os em prompts menores e mais gerenciáveis. Abordamos diferentes métodos de encadeamento, suas aplicações e práticas recomendadas para ajudar você a aproveitar efetivamente os LLMs para uma ampla gama de casos de uso.
Se você quiser saber mais sobre engenharia de prontidão, recomendo estes artigos:
Perguntas frequentes
Há alguma estrutura ou ferramenta que facilite o encadeamento imediato para LLMs?
Embora não exista uma estrutura dedicada para encadeamento imediato, ferramentas como LangChain, PyTorch e TensorFlow podem ser usadas para implementar e gerenciar fluxos de trabalho de encadeamento imediato, usando seus recursos para lidar com dados sequenciais e saídas de modelos.
Quais são algumas abordagens alternativas para aprimorar o desempenho do LLM além do encadeamento imediato?
O ajuste fino em conjuntos de dados específicos do domínio, a destilação de conhecimento, a integração de funções, o refinamento iterativo e o ajuste de parâmetros são algumas abordagens alternativas.
Eles oferecem benefícios exclusivos e podem ser usados individualmente ou em combinação para melhorar o desempenho do LLM em tarefas ou casos de uso específicos.
O encadeamento imediato pode ser integrado a sistemas automatizados para aplicativos em tempo real?
Sim, o encadeamento de avisos pode ser integrado a sistemas automatizados, como chatbots, assistentes virtuais e plataformas de análise de dados em tempo real, para aumentar a precisão e a coerência de suas respostas e resultados.
Quais são os possíveis desafios de implementar o encadeamento de solicitações em ambientes de produção?
Os desafios incluem o gerenciamento de dependências imediatas, a garantia de baixa latência para aplicativos em tempo real, o tratamento eficaz de erros e resultados incompletos e a manutenção da escalabilidade e do desempenho do sistema à medida que a complexidade das tarefas aumenta.
Saiba mais sobre a IA!
Course
ChatGPT Prompt Engineering para desenvolvedores
Track