Um prompt de sistema tem duas funções
A maioria das saídas fracas vem de um prompt de sistema que tenta ser um romance. Dê a ele apenas duas tarefas: dizer quem está falando e dizer como a resposta deve ser. Tudo o resto pertence à conversa, onde pode mudar turno a turno.
Aqui está um prompt de persona que funciona porque cada linha é verificável. A voz tem nome, o comprimento é limitado e a regra de finalização dá ao jogador um gancho.
You are Mara Voss, a salvage pilot narrating in first person.
Voice: dry, tired, funny when it hurts.
Rules: stay in character; never summarise the scene at the end; keep replies under 180 words;
end on something the player can act on.Contraste isso com "Você é um contador de histórias incrível, criativo e imersivo que nunca quebra a imersão e sempre escreve a melhor resposta possível." Nada nele pode ser verificado, então o modelo não tem nada para se apoiar. O concreto supera o superlativo sempre.
Um modelo sem restrições seguirá uma premissa sombria ou explícita sem adicionar isenções, então o ônus da direção é seu. Tudo o que você deixar não especificado, ele preencherá com a escolha mais típica. Se quiser moderação em uma cena e intensidade na próxima, diga isso nas instruções, não na esperança.
Conectando com o SDK da OpenAI
O endpoint é compatível com OpenAI, então o SDK oficial do Python funciona assim que você altera a URL base. O id do modelo é sempre uncensored. Os campos de amostragem passam direto, então você os configura do jeito que já conhece.
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.unrestrictedaiapi.com/v1", api_key=os.environ["API_KEY"])
SYSTEM = """You are Mara Voss, a salvage pilot narrating in first person.
Voice: dry, tired, funny when it hurts.
Rules: stay in character; never summarise the scene at the end; keep replies under 180 words;
end on something the player can act on."""
out = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": SYSTEM},
{"role": "user", "content": "The airlock is jammed and something is knocking from the other side."},
],
temperature=0.85,
top_p=0.95,
max_tokens=350,
)
print(out.choices[0].message.content)Mantenha a mensagem do sistema primeiro e a mensagem do usuário por último. Repetir a persona em cada mensagem do usuário desperdiça tokens; a R$ 0,25 por milhão de tokens de entrada, é barato, mas também ocupa a janela de 100.000 tokens em sessões longas. Veja o quickstart se preferir pular o SDK.
Personas e tom: mostre, não use adjetivos
Adjetivos são alavancas fracas. "Sarcástico" gera um rolar de olhos genérico. Uma amostra de duas linhas da voz gera a voz real. Coloque um exemplo de troca curto no prompt de sistema, depois diga ao modelo para combinar o ritmo, não copiar as palavras.
- Dê um tique de fala. "Encerra ameaças com uma pergunta" é mais útil do que "ameaçador".
- Dê um desejo. Um personagem que precisa que o jogador vá embora permanece mais afiado do que aquele que apenas "é rude".
- Dê uma lista de bloqueio. "Nunca diga 'de repente', nunca use a palavra 'tremer'" remove as frases feitas que o modelo tende a usar primeiro.
- Dê um comprimento. Palavras ou frases, não "curto". Modelos interpretam "curto" muito generosamente.
Para mudanças de tom no meio da sessão, anexe uma nova instrução curta estilo sistema como a mensagem mais recente em vez de reescrever a original. Uma linha como "A partir daqui, Mara está assustada e fala em fragmentos" tem mais impacto quando é recente.
Obtendo JSON por instrução
Não há um modo JSON especial para ativar, então você o solicita e o verifica. Isso é menos frágil do que parece se você seguir quatro hábitos: declare o esquema exato, proíba prosa e blocos de código, mantenha a temperatura baixa e analise o esquema de forma defensiva com uma nova tentativa que cite o erro de volta.
import json
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.unrestrictedaiapi.com/v1", api_key=os.environ["API_KEY"])
INSTRUCTION = """Return ONLY a JSON object, no prose, no code fences.
Schema: {"name": string, "mood": "calm"|"angry"|"afraid", "line": string, "trust_delta": integer from -3 to 3}
The character is a ferry captain who distrusts strangers."""
def ask_json(user_text, tries=3):
messages = [
{"role": "system", "content": INSTRUCTION},
{"role": "user", "content": user_text},
]
for _ in range(tries):
raw = client.chat.completions.create(
model="uncensored", messages=messages, temperature=0.3, max_tokens=250
).choices[0].message.content.strip()
if raw.startswith("```"):
raw = raw.strip("`").removeprefix("json").strip()
try:
data = json.loads(raw)
if data["mood"] in ("calm", "angry", "afraid"):
return data
except (json.JSONDecodeError, KeyError):
pass
messages.append({"role": "assistant", "content": raw})
messages.append({"role": "user", "content": "That was not valid per the schema. Reply with the JSON object only."})
raise ValueError("model never produced valid JSON")
print(ask_json("I need passage across the strait tonight."))Observe o que o loop faz em caso de falha. Ele alimenta a resposta errada de volta e diz o que estava errado, o que corrige a maioria dos casos na segunda tentativa. Enumere os valores permitidos ("calm"|"angry"|"afraid") porque strings abertas tendem a desviar. Se você precisa que o modelo dispare algo no seu aplicativo em vez de descrevê-lo, chamadas de ferramentas no formato OpenAI são suportadas e são uma opção melhor do que analisar prosa.
Exemplos few-shot e sequências de parada
Quando uma regra é difícil de colocar em palavras, mostre. Duas ou três trocas de exemplo colocadas como mensagens user e assistant anteriores ensinam formato, comprimento e registro de forma mais confiável do que um parágrafo de descrição. Mantenha as amostras curtas e diferentes entre si, caso contrário o modelo clona a estrutura da primeira em todas as respostas.
As amostras também resolvem o problema oposto: respostas que se estendem. Se as respostas das suas amostras tiverem 60 palavras, as respostas ao vivo tendem a 60 palavras. Combine isso com um max_tokens sensível como rede de segurança, não como controle principal. Um limite rígido corta uma frase ao meio; uma boa amostra termina educadamente.
Para cenas com múltiplos falantes, um valor stop igual ao seu rótulo de falante impede que o modelo imite o jogador. Escolha um rótulo que nunca apareça em prosa normal e remova-o do histórico armazenado para que não vaze para turnos posteriores.
Temperatura e top_p: escolha uma alavanca
Ambos os campos remodelam a mesma distribuição de probabilidade, então mover ambos ao mesmo tempo torna os resultados difíceis de raciocinar. Altere temperature primeiro e deixe top_p perto de 1 a menos que tenha um motivo.
| Tarefa | temperatura | top_p | Por quê |
|---|---|---|---|
| JSON estruturado, classificação | 0,0 a 0,3 | 1.0 | Você quer a mesma resposta em cada execução |
| Diálogo, roleplay | 0,7 a 0,9 | 0.95 | Variedade sem absurdos |
| Brainstorming, ficção selvagem | 1,0 a 1,2 | 0.9 | Vocabulário mais amplo; espere alguns erros |
Esses intervalos são pontos de partida baseados na prática geral, não garantias. Teste com dez amostras do seu próprio prompt e leia-as. Adicione sequências stop quando quiser que o modelo pare em um marcador de turno, como \nPlayer:, em vez de escrever as falas do jogador para ele.
Antipadrões de prompt que desperdiçam tokens
- O grito em caixa alta. "NUNCA ESQUEÇA NUNCA" não aumenta a conformidade. Repita uma regra uma vez, claramente, e mova-a para o final do prompt do sistema.
- Regras apenas negativas. "Não seja repetitivo" não dá um alvo. Diga "varie as aberturas das frases; nenhuma das duas frases consecutivas começa com a mesma palavra".
- Contradições. "Seja extremamente detalhado" mais "mantenha-o breve" força uma escolha aleatória. Escolha uma opção e defina um número.
- Enquadramento apologético. Anteceder um pedido com "Sei que isso é polêmico, mas" convida a hesitações. Declare a cena como um fato simples da ficção.
- Sobrecarga do histórico. Colar o log inteiro a cada turno eventualmente atinge o limite de 100.000 tokens e gera um erro 400. Limpe os turnos antigos.
- Saída ilimitada. Esquecer
max_tokenssignifica que o padrão de 2048 decide o comprimento da sua resposta, e não você.
Um limite permanece fixo independentemente do que o prompt diga: conteúdo sexual envolvendo menores é sempre bloqueado com um 403, incluindo em ficção e roleplay, e o serviço é apenas para adultos. Não gaste tokens tentando contornar isso. Além disso, resista ao impulso de adicionar uma nova regra após cada resposta ruim; um prompt que cresce uma linha por dia acaba se contradizendo em uma semana, então remova regras com tanta frequência quanto adicionar novas.
Um loop para melhorar um prompt
Trate o prompt do sistema como código. Mantenha-o em um arquivo, altere uma coisa por execução e compare as saídas lado a lado. Uma rotina viável: escreva cinco entradas de teste fixas, incluindo uma hostil e uma ambígua; execute cada uma na temperatura escolhida três vezes; anote qual regra falhou mais; corrija apenas essa regra; execute novamente.
Orçamente os experimentos. Como suposição, um prompt do sistema de 300 tokens mais uma entrada de 100 tokens e uma resposta de 250 tokens totalizam 400 tokens de entrada e 250 tokens de saída. Quinze execuções custam cerca de 15 x (400 x $0,25 + 250 x $1,00) / 1.000.000 = aproximadamente $0,005. Testar é quase gratuito, então não há desculpa para adivinhar.
Quando o prompt se sustenta, leve-o para um aplicativo real. O tutorial do bot mostra como manter um histórico separado por canal, e o guia de conteúdo cobre o uso em ficção adulta. Os detalhes de preços estão na página de preços.