Engenharia de comando

No módulo de IA generativa, você aprendeu que o espaço de entrada dos modelos de IA generativa é praticamente ilimitado. Para gerar resultados que atendam às expectativas dos usuários, você precisa criar comandos. Um comando é um contrato estruturado entre seu aplicativo e o modelo.

Um comando bem escrito:

  • Indica como o LLM deve criar a resposta.
  • Consiste em vários componentes que podem ser versionados, testados e aprimorados com o tempo.
  • Pode atuar como um artefato compartilhado para colaboração entre equipes.

Neste módulo, você vai aprender a escrever comandos eficazes. Explicamos como um comando é estruturado e como os componentes dele são distribuídos entre o sistema e o usuário final. Você também vai aprender técnicas básicas de comandos e os cenários em que aplicar cada uma delas.

Ao longo deste módulo, vamos usar um exemplo compartilhado: o BlogBuddy, um assistente de escrita com tecnologia de IA, inspirado no uso da API Prompt pela CyberAgent.

Volte ao módulo de IA generativa para conferir o projeto do sistema BlogBuddy.

Componentes do comando

Cada componente de comando tem uma função específica para orientar o comportamento do modelo.

  • Contexto: estabelece a função e o domínio do modelo para que ele entenda como se comportar.
  • Instrução: atribui uma tarefa específica ao modelo.
  • Variáveis de entrada: contexto específico da situação, fornecido pelo aplicativo em tempo real.
  • Formato de saída: define a estrutura de saída esperada. Por exemplo, talvez você queira saídas JSON.
  • Exemplos: demonstre como a tarefa deve ser executada para uma ou mais entradas.
  • Restrições: defina limites claros para manter a saída consistente, segura e alinhada à marca.

Seu comando pode incluir alguns ou todos esses componentes. O exemplo a seguir ilustra esses componentes para o recurso de assistente de escrita do BlogBuddy.

### Context

You are a writing assistant for blog authors.
Your job is to generate helpful, concise, and engaging content.

### Instruction

Generate 3 alternative titles for the user's blog post with a given style.

### Input variables

Here is the content of the blog post:
${blogPostContent}

Here is the desired style:
${titleStyle}

### Output format

Return valid JSON ONLY, in the following exact structure:
{
  "titles": ["Title option 1", "Title option 2", "Title option 3"]
}

### Examples

Example input:
{
  "blogPostContent": "I finally visited the small neighborhood café I've been eyeing for months...",
  "titleStyle": "friendly"
}

Example output:
{
  "titles": [
    "A First Visit to the Neighborhood Café",
    "Trying the Café I've Wanted to Visit for Months",
    "My Experience at a Long-Awaited Local Spot"
  ]
}
### Constraints

- Each title must be under 128 characters.
- Titles must be original, not copied verbatim from the draft.
- Keep the tone natural and human. Avoid emojis unless explicitly requested.
- Avoid sensationalism or clickbait.
- If the draft includes multiple topics, choose the most prominent topic.

Para seus primeiros comandos, comece com o essencial: instrução e formato de saída. Em seguida, adicione mais componentes de forma iterativa à medida que analisa os resultados e determina quais controles mais refinados são necessários para o sucesso.

Comandos do sistema x comandos do usuário

Alguns dos componentes de solicitação são codificados, enquanto outros podem ser fornecidos pelo usuário final:

  • O comando do sistema é fornecido pelos desenvolvedores de aplicativos e define o comportamento geral do modelo. Ele pode definir a função do modelo, o tom esperado, o formato de saída (como um esquema JSON estrito) e restrições globais. É também no comando do sistema que você codifica os requisitos de segurança e responsabilidade. Ele permanece consistente em todas as solicitações e oferece uma base estável para o comportamento do modelo.

  • O comando do usuário contém a solicitação imediata que gera uma saída. O usuário pede uma tarefa específica, que pode incluir variáveis específicas. Por exemplo, "Mostre três títulos para esta postagem", "Continue este parágrafo" ou "Deixe este texto mais formal".

A maioria das APIs de IA generativa permite estruturar um comando como uma matriz de mensagens, cada uma com uma função (sistema ou usuário) e conteúdo. Isso facilita a separação de instruções estáveis e globais de entradas dinâmicas por solicitação.

Como você decide quais componentes pertencem ao comando do sistema e quais devem ser especificados pelo usuário? A resposta depende da flexibilidade da experiência do usuário e da capacidade do modelo.

Casos de uso restritos

Para casos de uso muito específicos, a maior parte do comando pode ser predefinida no comando do sistema. Por exemplo, no BlogBuddy, os usuários podem clicar em Mostrar títulos para listar sugestões de títulos gerados para o rascunho.

A tarefa é fixa, o formato de saída é conhecido e o usuário não precisa fornecer contexto extra para receber o resultado esperado. Nesse caso, coloque todas as regras estáveis, diretrizes de tom, esquemas de saída e exemplos no comando do sistema.

Para criar isso com a API Prompt, usaríamos initialPrompts para definir o comportamento no nível do sistema para toda a sessão:

// Defines stable behavior for the entire session
const session = await LanguageModel.create({
  initialPrompts: [
    {
      role: "system",
      content: `You are a blog-writing assistant.
      Your task is to generate high-quality titles for blog posts.
      Always respond in concise, friendly language.
      Return exactly 3 alternative titles.
      Produce valid JSON with a "titles" array of strings.`
    }
  ]
});

Quando o usuário clica em Mostrar títulos, a solicitação é invocada para o conteúdo atual:

// The only variable input is the blog content
const result = await session.prompt(blogContent);

Com o tempo, os usuários podem pedir mais flexibilidade e controle. Nesse caso, você pode mover alguns componentes para o comando do usuário, com controles de interface. Por exemplo, um menu suspenso de especificações de estilo ou tom.

No entanto, muitas ações estruturadas podem prejudicar a experiência do usuário. Quando isso acontece, talvez seja melhor mudar para um design mais aberto, que permita aos usuários especificar a maioria dos comandos. Você vai aprender mais sobre como otimizar esse design no módulo de padrões de UX.

As tarefas flexíveis dependem de comandos detalhados do usuário

Uma experiência interativa e aberta que ajuda os usuários a escrever postagens de blog do zero e oferece mais flexibilidade. Eles podem pedir ideias, esboços, reescritas, mudanças de tom ou brainstorms, ou especificar exatamente como uma tarefa deve ser executada. Com esse tipo de aplicativo, provavelmente você vai precisar de um modelo mais poderoso do lado do servidor.

Com tarefas flexíveis, o usuário precisa especificar mais informações, já que o intervalo possível de opções é muito maior. O comando do sistema ainda rege o comportamento geral.

As práticas recomendadas são:

  • Coloque regras, estrutura e exemplos estáveis no comando do sistema. Coloque conteúdo dinâmico e solicitações específicas de tarefas no comando do usuário.
  • Quanto mais aberto for o UX, mais flexibilidade o comando do usuário precisará ter para acomodar entradas imprevisíveis.
  • Quanto mais trabalho o comando do usuário precisar fazer, mais capaz o modelo precisa ser, já que ele precisa lidar com uma variação maior com menos estrutura integrada.

Você pode usar essas regras para otimizar gradualmente a compensação entre controle e flexibilidade do usuário no contexto do produto. Observe de perto as preferências e os comportamentos dos usuários. Mais flexibilidade nem sempre se traduz em valor real. Os usuários também precisam ter tempo, habilidades e capacidade cognitiva para criar comandos mais extensos.

Técnicas comuns de criação de comandos

Os desenvolvedores geralmente testam várias técnicas de comandos para encontrar o que funciona melhor para o caso de uso e o modelo deles.

Comandos zero-shot

Você descreve a tarefa para o modelo e espera o melhor. Exemplo:

"What is the capital of France?"

O comando zero-shot é uma referência eficiente para muitas tarefas de IA. Para solicitações que não são complexas, como consultas de conhecimento enciclopédico, provavelmente é melhor usar essa técnica. No entanto, na maioria das aplicações do mundo real, é necessário expandir o comando com mais condições e lógica.

Comandos de poucos disparos (few-shot)

Com o uso de poucos exemplos, você fornece exemplos para demonstrar o comportamento, estilo, estrutura e outras variáveis importantes corretos. Confira um exemplo de comando para classificação de sentimento:

You classify user messages into one of the following categories:
- "positive"
- "negative"
- "neutral"
Here are examples to guide your classifications:
Input: "I love this product! It works perfectly."
Output: { "label": "positive" }

Input: "This is terrible. I want a refund."
Output: { "label": "negative" }

Os comandos de poucos disparos são úteis para esse tipo de tarefa pseudopreditiva. Ele também pode ser aplicado a tarefas que seguem uma estrutura reconhecível, como a geração de títulos na Figura 1.

Quando o espaço de saída é muito amplo, como conteúdo aberto ou longo, a solicitação com poucos exemplos provavelmente não é a melhor técnica. É difícil ou até mesmo impossível fornecer exemplos que cubram o espaço de maneira significativa.

Comandos com linha de raciocínio

Você incentiva o modelo a analisar etapa por etapa antes de produzir uma resposta. As etapas podem ser descritas explicitamente ou deixadas para o modelo definir. Exemplo:

"Think step-by-step to identify the main idea of this paragraph. Then produce a
short heading under 60 characters."

O raciocínio em cadeia funciona muito bem para tarefas que exigem raciocínio e execução em várias etapas, como criar um esboço de uma postagem de blog ou apoiar decisões complexas. É a principal técnica por trás dos chamados modelos de raciocínio.

Isso pode ser caro. Gerar rastreamentos de raciocínio detalhados aumenta o uso de computação, o custo e a latência. Use apenas quando seu caso de uso exigir raciocínio e planejamento complexos.

Comandos de autorreflexão

Depois da geração inicial, você pede que o modelo critique e revise a própria saída. Exemplo:

"Review your previous output.
Identify unclear phrasing and rewrite it more concisely."

A autorreflexão é especialmente útil para tarefas que se beneficiam do refinamento iterativo, como ferramentas de edição ou reescrita. É rápido de implementar e pode gerar ganhos de qualidade significativos. Um loop de autorreflexão é útil quando seu comando está funcionando bem. Primeiro, refine a saída para mais clareza ou aumentar a satisfação do usuário.

Seus pontos principais

Neste módulo, você aprendeu como os comandos são criados com base em componentes estruturados. Na prática, a engenharia de comandos é altamente experimental. A clareza e a confiabilidade só aparecem depois de várias rodadas de refinamento.

No próximo módulo, vamos falar sobre o desenvolvimento de comandos orientado por avaliação. Essa prática ajuda você a melhorar os comandos de forma sistemática e convergir para o que funciona melhor para seu produto e seus usuários.

Recursos

Cada uma dessas técnicas tem variantes e práticas recomendadas. Há uma ampla variedade de recursos externos detalhados, por exemplo:

Confira a documentação do modelo escolhido, porque pode haver recomendações específicas para você ter os melhores resultados possíveis.

Teste seu conhecimento

Que tipos de regras podem ser especificados em um comando do sistema?

Variáveis de entrada específicas (como entradas do usuário), estrutura de saída esperada, função do modelo e limite de contagem de caracteres.
Muito bem, é isso mesmo!
Apenas a entrada do usuário vai aqui.
Não é bem assim. Tente novamente.
Para estabelecer a função e o domínio do modelo, para que ele entenda como se comportar.
Não é bem assim. Tente novamente.
O tipo e o tamanho do modelo que você está usando.
Não. Tente novamente.

Qual técnica você deve usar quando quiser que o modelo raciocine por etapas antes de produzir a resposta?

Comandos zero-shot
Resposta incorreta.
Comandos de poucos disparos (few-shot)
Resposta incorreta.
Comandos com linha de raciocínio
Muito bem, é isso mesmo!
Comandos de autorreflexão
Resposta incorreta.

Quando o comando de poucos disparos é mais útil?

Ao pedir para o modelo realizar uma tarefa sem contexto.
Resposta incorreta.
Quando a tarefa segue uma estrutura reconhecível, como geração de títulos, ou exige uma formatação específica.
Muito bem, é isso mesmo!
Quando o espaço de saída é muito grande, como a escrita criativa aberta.
Resposta incorreta.
Quando você quer que o modelo critique o próprio trabalho.
Resposta incorreta.

O que é a técnica de comando de autoavaliação?

Pedir ao modelo para criticar e revisar a própria saída para melhorar a clareza ou a qualidade.
Muito bem, é isso mesmo!
Executar o comando várias vezes e calcular a média dos resultados.
Resposta incorreta.
Pedir que o usuário reescreva o comando se o resultado for ruim.
Resposta incorreta.
Permitir que o modelo mude o comando do sistema de forma dinâmica.
Resposta incorreta.