# Engenharia de prompt

A engenharia de prompts, ou simplesmente prompting, usa linguagem natural para melhorar o desempenho de modelos de linguagem de grande escala (LLMs) em uma variedade de tarefas. Um prompt pode direcionar o modelo para gerar uma saída desejada. Em muitos casos, você nem precisa de um modelo [fine-tuned](#fine-tuning) para uma tarefa. Basta um bom prompt.

Tente pedir a um LLM que classifique algum texto. Ao criar um prompt, é importante fornecer instruções muito específicas sobre a tarefa e sobre como o resultado deve ser.

```py
from transformers import pipeline
import torch

pipeline = pipeline(task="text-generation", model="mistralai/Mistral-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")
prompt = """Classify the text into neutral, negative or positive.
Text: This movie is definitely one of my favorite movies of its kind. The interaction between respectable and morally strong characters is an ode to chivalry and the honor code amongst thieves and policemen.
Sentiment:
"""

outputs = pipeline(prompt, max_new_tokens=10)
for output in outputs:
    print(f"Result: {output['generated_text']}")
Result: Classify the text into neutral, negative or positive. 
Text: This movie is definitely one of my favorite movies of its kind. The interaction between respectable and morally strong characters is an ode to chivalry and the honor code amongst thieves and policemen.
Sentiment:
Positive
```

O desafio reside em projetar prompts que produzam os resultados que você espera, pois a linguagem é incrivelmente matizada e expressiva.

Este guia aborda as melhores práticas, técnicas e exemplos de engenharia de prompts para resolver tarefas de linguagem e raciocínio.

## Boas práticas

1. Tente escolher os modelos mais recentes para obter o melhor desempenho. Lembre-se de que os LLMs podem vir em duas variantes, [base](https://hf.co/mistralai/Mistral-7B-v0.1) e [instruction-tuned](https://hf.co/mistralai/Mistral-7B-Instruct-v0.1) (ou chat).

    Os modelos base são excelentes em completar texto dado um prompt inicial, mas não são tão bons em seguir instruções. Os modelos ajustados por instrução são versões específicas dos modelos base treinadas em dados instrucionais ou conversacionais. Isso torna os modelos ajustados por instrução mais adequados para o uso de prompts.

    > [!WARNING]
    > Os LLMs modernos são tipicamente modelos apenas de decodificador, mas existem alguns LLMs encoder-decoder, como [Flan-T5](../model_doc/flan-t5) ou [BART](../model_doc/bart), que podem ser usados para prompting. Carregue esses modelos diretamente com a classe [AutoModelForSeq2SeqLM](/docs/transformers/main/pt/model_doc/auto#transformers.AutoModelForSeq2SeqLM) (em vez de usar [Pipeline](/docs/transformers/main/pt/main_classes/pipelines#transformers.Pipeline)) e gere as saídas a partir do próprio modelo.

2. Comece com um prompt curto e simples e itere sobre ele para obter melhores resultados.

3. Coloque as instruções no início ou no final de um prompt. Para prompts mais longos, os modelos podem aplicar otimizações para evitar que a atenção escale de forma quadrática, o que dá mais ênfase ao início e ao final de um prompt.

4. Separe claramente as instruções do texto de interesse.

5. Seja específico e descritivo sobre a tarefa e a saída desejada, incluindo, por exemplo, seu formato, comprimento, estilo e idioma. Evite descrições e instruções ambíguas.

6. As instruções devem focar no "o que fazer" em vez do "o que não fazer".

7. Guie o modelo para gerar a saída correta escrevendo a primeira palavra ou até mesmo a primeira frase.

8. Experimente outras técnicas, como [few-shot](#few-shot-prompting) e [chain-of-thought](#chain-of-thought), para melhorar os resultados.

9. Teste seus prompts com diferentes modelos para avaliar sua robustez.

10. Versionar e acompanhar o desempenho dos seus prompts.

## Técnicas

Criar um bom prompt por si só, também conhecido como zero-shot prompting, pode não ser suficiente para obter os resultados desejados. Você pode precisar experimentar algumas técnicas de prompting para alcançar o melhor desempenho.

Esta seção aborda algumas técnicas de prompt.

### Prompting com poucos exemplos

O few-shot prompting melhora a precisão e o desempenho ao incluir exemplos específicos do que um modelo deve gerar dado um input. Os exemplos explícitos dão ao modelo uma melhor compreensão da tarefa e do formato de saída que você está procurando. Tente experimentar com diferentes números de exemplos (2, 4, 8, etc.) para ver como isso afeta o desempenho. O exemplo abaixo fornece ao modelo 1 exemplo (1-shot) do formato de saída (uma data no formato MM/DD/YYYY) que ele deve retornar.

```python
from transformers import pipeline
import torch

pipeline = pipeline(model="mistralai/Mistral-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")
prompt = """Text: The first human went into space and orbited the Earth on April 12, 1961.
Date: 04/12/1961
Text: The first-ever televised presidential debate in the United States took place on September 28, 1960, between presidential candidates John F. Kennedy and Richard Nixon.
Date:"""

outputs = pipeline(prompt, max_new_tokens=12, do_sample=True, top_k=10)
for output in outputs:
    print(f"Result: {output['generated_text']}")
# Result: Text: The first human went into space and orbited the Earth on April 12, 1961.
# Date: 04/12/1961
# Text: The first-ever televised presidential debate in the United States took place on September 28, 1960, between presidential candidates John F. Kennedy and Richard Nixon.
# Date: 09/28/1960
```

A desvantagem do few-shot prompting é que é necessário criar prompts mais longos, o que aumenta a computação e a latência. Além disso, há um limite para o comprimento dos prompts. Por fim, um modelo pode aprender padrões indesejados a partir dos seus exemplos e pode não funcionar bem em tarefas de raciocínio complexo.

Para melhorar o few-shot prompting em LLMs modernos ajustados por instrução, use o [chat template](../conversations) específico do modelo. Esses modelos são treinados em conjuntos de dados com conversas por turnos entre um "user" e um "assistant". Estruturar seu prompt para se alinhar a isso pode melhorar o desempenho.

Estruture seu prompt como uma conversa por turnos e use o método `apply_chat_template` para tokenizar e formatá-lo.

```python
from transformers import pipeline
import torch

pipeline = pipeline(model="mistralai/Mistral-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")

messages = [
    {"role": "user", "content": "Text: The first human went into space and orbited the Earth on April 12, 1961."},
    {"role": "assistant", "content": "Date: 04/12/1961"},
    {"role": "user", "content": "Text: The first-ever televised presidential debate in the United States took place on September 28, 1960, between presidential candidates John F. Kennedy and Richard Nixon."}
]

prompt = pipeline.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)

outputs = pipeline(prompt, max_new_tokens=12, do_sample=True, top_k=10)

for output in outputs:
    print(f"Result: {output['generated_text']}")
```

Enquanto a abordagem básica de few-shot prompting incorporava exemplos em uma única string de texto, o formato de template de chat oferece os seguintes benefícios.

- O modelo pode ter uma compreensão potencialmente aprimorada, pois consegue reconhecer melhor o padrão e os papéis esperados da entrada do usuário e da saída do assistente.
- O modelo pode produzir o formato de saída desejado de forma mais consistente, pois sua estrutura é semelhante à do seu input durante o treinamento.

Consulte sempre a documentação de um modelo específico ajustado por instruções para saber mais sobre o formato do modelo de chat dele, para que você possa estruturar seus prompts de poucos exemplos de acordo.

### Cadeia de raciocínio

Chain-of-thought (CoT) é eficaz na geração de saídas mais coerentes e bem fundamentadas ao fornecer uma série de prompts que ajudam um modelo a "pensar" mais aprofundadamente sobre um tópico.

O exemplo abaixo fornece ao modelo vários prompts para trabalhar etapas intermediárias de raciocínio.

```py
from transformers import pipeline
import torch

pipeline = pipeline(model="mistralai/Mistral-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")
prompt = """Let's go through this step-by-step:
1. You start with 15 muffins.
2. You eat 2 muffins, leaving you with 13 muffins.
3. You give 5 muffins to your neighbor, leaving you with 8 muffins.
4. Your partner buys 6 more muffins, bringing the total number of muffins to 14.
5. Your partner eats 2 muffins, leaving you with 12 muffins.
If you eat 6 muffins, how many are left?"""

outputs = pipeline(prompt, max_new_tokens=20, do_sample=True, top_k=10)
for output in outputs:
    print(f"Result: {output['generated_text']}")
Result: Let's go through this step-by-step:
1. You start with 15 muffins.
2. You eat 2 muffins, leaving you with 13 muffins.
3. You give 5 muffins to your neighbor, leaving you with 8 muffins.
4. Your partner buys 6 more muffins, bringing the total number of muffins to 14.
5. Your partner eats 2 muffins, leaving you with 12 muffins.
If you eat 6 muffins, how many are left?
Answer: 6
```

Assim como o [few-shot](#few-shot-prompting) prompting, a desvantagem do CoT é que ele exige mais esforço para projetar uma série de prompts que ajudem o modelo a raciocinar sobre uma tarefa complexa, e o aumento do comprimento do prompt eleva a latência.

## Ajuste fino

Embora o prompting seja uma forma poderosa de trabalhar com LLMs, existem cenários em que um modelo ajustado finamente, ou até mesmo o ajuste fino de um modelo, funciona melhor.

Aqui estão alguns cenários em que um modelo ajustado faz sentido.

- Seu domínio é extremamente diferente do que um LLM foi pré-treinado, e o uso extensivo de prompts não produziu os resultados que você deseja.
- Seu modelo precisa funcionar bem em um idioma com poucos recursos.
- Seu modelo precisa ser treinado em dados sensíveis que possuem requisitos regulatórios rigorosos.
- Você está usando um modelo pequeno devido a custos, privacidade, infraestrutura ou outras restrições.

Em todos esses cenários, verifique se você possui um conjunto de dados específico do domínio grande o suficiente para treinar seu modelo, se tem tempo e recursos suficientes e se o custo do ajuste fino compensa. Caso contrário, talvez seja melhor tentar otimizar seu prompt.

## Exemplos

Os exemplos abaixo demonstram o uso de prompts em um LLM para diferentes tarefas.

```py
from transformers import pipeline
import torch

pipeline = pipeline(model="mistralai/Mistral-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")
prompt = """Return a list of named entities in the text.
Text: The company was founded in 2016 by French entrepreneurs Clément Delangue, Julien Chaumond, and Thomas Wolf in New York City, originally as a company that developed a chatbot app targeted at teenagers.
Named entities:
"""

outputs = pipeline(prompt, max_new_tokens=50, return_full_text=False)
for output in outputs:
    print(f"Result: {output['generated_text']}")
Result:  [Clément Delangue, Julien Chaumond, Thomas Wolf, company, New York City, chatbot app, teenagers]
```

```py
from transformers import pipeline
import torch

pipeline = pipeline(model="mistralai/Mistral-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")
prompt = """Translate the English text to French.
Text: Sometimes, I've believed as many as six impossible things before breakfast.
Translation:
"""

outputs = pipeline(prompt, max_new_tokens=20, do_sample=True, top_k=10, return_full_text=False)
for output in outputs:
    print(f"Result: {output['generated_text']}")
Result: À l'occasion, j'ai croyu plus de six choses impossibles
```

```py
from transformers import pipeline
import torch

pipeline = pipeline(model="mistralai/Mistral-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")
prompt = """Permaculture is a design process mimicking the diversity, functionality and resilience of natural ecosystems. The principles and practices are drawn from traditional ecological knowledge of indigenous cultures combined with modern scientific understanding and technological innovations. Permaculture design provides a framework helping individuals and communities develop innovative, creative and effective strategies for meeting basic needs while preparing for and mitigating the projected impacts of climate change.
Write a summary of the above text.
Summary:
"""

outputs = pipeline(prompt, max_new_tokens=30, do_sample=True, top_k=10, return_full_text=False)
for output in outputs:
    print(f"Result: {output['generated_text']}")
Result: Permaculture is the design process that involves mimicking natural ecosystems to provide sustainable solutions to basic needs. It is a holistic approach that comb
```

```py
from transformers import pipeline
import torch

pipeline = pipeline(model="mistralai/Mistral-7B-Instruct-v0.1", dtype=torch.bfloat16, device_map="auto")
prompt = """Answer the question using the context below.
Context: Gazpacho is a cold soup and drink made of raw, blended vegetables. Most gazpacho includes stale bread, tomato, cucumbers, onion, bell peppers, garlic, olive oil, wine vinegar, water, and salt. Northern recipes often include cumin and/or pimentón (smoked sweet paprika). Traditionally, gazpacho was made by pounding the vegetables in a mortar with a pestle; this more laborious method is still sometimes used as it helps keep the gazpacho cool and avoids the foam and silky consistency of smoothie versions made in blenders or food processors.
Question: What modern tool is used to make gazpacho?
Answer:
"""

outputs = pipeline(prompt, max_new_tokens=10, do_sample=True, top_k=10, return_full_text=False)
for output in outputs:
    print(f"Result: {output['generated_text']}")
Result: A blender or food processor is the modern tool
```

