Atualizado em
Criando um aplicativo em chinês: prompts, controle de script e UTF-8
Lançar um recurso em chinês é principalmente um problema de localização, não de modelagem. Você decide qual script os usuários veem, mantém as codificações limpas do arquivo à rede e orçamenta tokens para textos que não se dividem por espaços. Este guia cobre essas três camadas com código que você pode executar contra o endpoint de chat completions hoje.
O que você está configurando
O serviço expõe POST /v1/chat/completions e GET /v1/models sob https://api.chinesellmapi.com/v1. A autenticação é uma chave bearer, e o único id do modelo é uncensored. É uma API apenas de texto com um modelo, então não há nada para selecionar entre: seu trabalho de localização ocorre inteiramente no prompt e no seu código ao redor dele.
Limites importantes antes de projetar: janela de contexto compartilhada de 100.000 tokens entre prompt e conclusão, max_tokens com valor padrão de 2.048 e limite máximo de 32.000, corpos de requisição de até 8 MB e 300 requisições por minuto por chave. O streaming (stream: true) funciona via eventos enviados pelo servidor, e o formato de chamada de funções OpenAI é aceito.
Novas contas recebem um crédito de teste de $0,50 válido por sete dias, sem necessidade de detalhes de pagamento; registre-se com e-mail e senha e a chave aparece imediatamente. O FAQ do teste grátis detalha as regras.
Escreva prompts em chinês e diga qual chinês
Prompts mistos são a fonte mais comum de deriva em recursos localizados. Se as instruções estão em inglês mas o conteúdo é chinês, as respostas às vezes voltam em inglês ou em uma mistura. Um padrão confiável é um prompt do sistema escrito no idioma alvo, declarando três coisas: o papel, o script e o vocabulário regional. Mantenha o texto fornecido pelo usuário em uma mensagem separada para que ele nunca seja confundido com instruções.
Aqui está uma configuração em chinês simplificado. Observe que o prompt do sistema diz ao modelo para responder apenas em caracteres simplificados e evitar inglês aleatório, com nomes próprios como exceção:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.chinesellmapi.com/v1",
api_key=os.environ["API_KEY"],
)
SYSTEM_SC = (
"你是一名产品文案助手。始终使用简体中文回答,使用中国大陆常见的用词和标点,"
"不要夹杂繁体字或英文句子,专有名词除外。"
)
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": SYSTEM_SC},
{"role": "user", "content": "为一款记账应用写三条应用商店的一句话简介。"},
],
max_tokens=300,
temperature=0.7,
)
print(resp.choices[0].message.content)
print(resp.usage)
Dois hábitos pagam rapidamente. Primeiro, mantenha os prompts curtos e concretos: um papel, um formato de saída, uma ou duas restrições. Segundo, coloque o requisito de idioma na mensagem do sistema em vez de repeti-lo em cada turno do usuário, para que o histórico da conversa não o dilua.
Controlando saída Simplificada vs Tradicional
A escolha do script é uma decisão de produto vinculada à localidade do usuário, não uma configuração do modelo. Produtos voltados para a China continental esperam caracteres simplificados; audiências de Taiwan e Hong Kong esperam caracteres tradicionais, com vocabulário diferente também (os exemplos usuais são termos de software, rede e banco de dados). A abordagem prática é mapear sua tag de localidade para um prompt do sistema e tornar a escolha explícita no código.
- zh-CN, zh-SG: Chinês simplificado, vocabulário da China continental, dígitos de largura normal e pontuação chinesa de largura total.
- zh-TW: Chinês tradicional, vocabulário de Taiwan, colchetes angulares são comuns para citações.
- zh-HK: Chinês tradicional com terminologia de Hong Kong; forneça um glossário curto se seu produto tiver termos fixos.
A variante Tradicional da mesma chamada se parece com isto; apenas o prompt do sistema muda:
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.chinesellmapi.com/v1", api_key=os.environ["API_KEY"])
SYSTEM_TC = (
"你是一名產品文案助手。請一律使用繁體中文回答,採用臺灣常用的詞彙與全形標點,"
"例如「軟體」「網路」「資料庫」,不要混入簡體字。"
)
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": SYSTEM_TC},
{"role": "user", "content": "請用兩句話說明什麼是雙重驗證。"},
],
max_tokens=200,
)
print(resp.choices[0].message.content)
Os modelos ocasionalmente vazam alguns caracteres do outro script, especialmente quando a mensagem do usuário já está no outro script. Adicione uma verificação pós-barata e tente novamente com uma instrução mais firme se falhar. Para qualquer coisa além de uma verificação de amostra, execute a saída por meio de uma biblioteca conversora dedicada como a OpenCC:
# A cheap guard: flag replies that contain characters that exist only in Simplified.
# The set below is a small sample, not a full list; use a converter such as OpenCC
# for production-grade checks.
SIMPLIFIED_ONLY = set("这个们说话时间书买卖东车门开关见觉")
def looks_simplified(text: str) -> bool:
return any(ch in SIMPLIFIED_ONLY for ch in text)
reply = "請用繁體中文回覆的範例文字"
print(looks_simplified(reply)) # False
UTF-8 do disco à rede e de volta
A maioria dos bugs de chinês corrompido não são problemas do modelo. Eles vêm de uma codificação padrão em algum lugar do pipeline: um console Windows usando uma página de códigos legada, um CSV aberto sem codificação, um proxy que reescreve o tipo de conteúdo. Torne cada limite explícito.
Em Python, passe encoding="utf-8" para open e, se você construir JSON manualmente, use ensure_ascii=False seguido por .encode("utf-8"). O exemplo abaixo faz isso com requests simples, mostrando também a estrutura HTTP bruta da chamada:
import json
import os
import requests
# 1) Always open files as UTF-8, never rely on the platform default encoding.
with open("notes_zh.txt", "r", encoding="utf-8") as f:
note = f.read()
payload = {
"model": "uncensored",
"messages": [{"role": "user", "content": "请把下面的笔记整理成三个要点:\n" + note}],
"max_tokens": 400,
}
# 2) requests encodes json= as UTF-8 for you. If you build the body by hand,
# keep Chinese readable and make the encoding explicit.
body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
r = requests.post(
"https://api.chinesellmapi.com/v1/chat/completions",
headers={
"Authorization": "Bearer " + os.environ["API_KEY"],
"Content-Type": "application/json; charset=utf-8",
},
data=body,
timeout=60,
)
r.raise_for_status()
r.encoding = "utf-8"
print(r.json()["choices"][0]["message"]["content"])
No Node, readFile retorna um Buffer a menos que você forneça uma codificação, e strings de modelo contendo caracteres chineses estão OK desde que o arquivo de origem seja salvo em UTF-8. O SDK oficial serializa o corpo para você:
import { readFile } from "node:fs/promises";
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.chinesellmapi.com/v1",
apiKey: process.env.API_KEY,
});
// Pass "utf8" explicitly; without it readFile returns a Buffer, not a string.
const note = await readFile("notes_zh.txt", "utf8");
const res = await client.chat.completions.create({
model: "uncensored",
messages: [{ role: "user", content: `请把下面的笔记整理成三个要点:\n${note}` }],
max_tokens: 400,
});
console.log(res.choices[0].message.content);
console.log(res.usage);
Mais duas armadilhas. Truncar strings pelo comprimento dos bytes pode cortar um caractere ao meio, então sempre fatie por caracteres. Ao fazer streaming, decodifique o fluxo como UTF-8 incrementalmente, pois um caractere multibyte pode ser dividido entre pedaços de rede; os SDKs lidam com isso, mas parsers manuais geralmente não.
Orçamento de tokens para texto chinês
O chinês não tem espaços, então contagens de palavras são inúteis para orçamento. Como suposição de planejamento, não uma constante medida, trate um caractere chinês como aproximadamente 1 a 2 tokens e use 1,5 quando precisar de um único número. Palavras latinas e dígitos embutidos no texto são mais próximos de 1,3 tokens por palavra. A proporção varia com o vocabulário, então a única figura autoritativa é o objeto usage retornado com cada resposta.
Um pequeno helper torna fácil estimar um prompt antes de enviá-lo e ajustar as proporções contra o uso real ao longo do tempo:
import re
CJK = re.compile(r"[㐀-鿿- -〿]")
def rough_tokens(text: str, per_cjk: float = 1.5, per_other_word: float = 1.3) -> int:
"""Planning estimate only. The 1.5 and 1.3 ratios are assumptions, not
measured values; compare against resp.usage and adjust them."""
cjk = len(CJK.findall(text))
others = len(re.findall(r"[A-Za-z0-9_]+", CJK.sub(" ", text)))
return round(cjk * per_cjk + others * per_other_word)
sample = "订单 A-1042 已发货,预计周三送达。"
print(rough_tokens(sample))
Exemplo prático, com suposições declaradas: um artigo de 2.000 caracteres a 1,5 tokens por caractere é cerca de 3.000 tokens de entrada. Um resumo de 400 caracteres é cerca de 600 tokens de saída. A $0,25 por milhão de tokens de entrada e $1,00 por milhão de tokens de saída, uma chamada custa aproximadamente $0,00075 para entrada mais $0,0006 para saída, totalizando cerca de $0,00135. Como o contexto é limitado a 100.000 tokens, a mesma suposição significa que um prompt de cerca de 40.000 caracteres deixa espaço para uma resposta.
Quando você precisa alimentar documentos longos, divida por parágrafo ou título, nunca no meio de uma frase, e mantenha max_tokens explícito. Preços e limites estão listados na página de preços.
Mantendo o chat chinês multi-turno dentro da janela
Recursos de chat reenviam todo o histórico em cada requisição, então custo e contexto crescem a cada turno. Como a janela é de 100.000 tokens compartilhados entre prompt e conclusão, uma conversa longa eventualmente aciona um 400 se você não fizer nada. Decida uma política de redução de tamanho cedo, em vez de reagir a erros.
Uma política simples é manter o prompt do sistema, remover as voltas mais antigas até que o prompt estimado se encaixe em um orçamento, e reservar o restante para a resposta. O esboço abaixo reutiliza o estimador da seção anterior:
MAX_PROMPT_TOKENS = 48_000 # leave headroom under the 100,000 window for the reply
def trim_history(messages, estimate):
# messages[0] is the system prompt and is always kept
system, rest = messages[0], messages[1:]
while rest and sum(estimate(m["content"]) for m in [system] + rest) > MAX_PROMPT_TOKENS:
rest.pop(0) # drop the oldest turn first
return [system] + rest
Para produtos onde o contexto inicial importa, como um bot de tutoria ou um assistente de suporte, substitua as voltas removidas por uma mensagem de resumo curto em vez de descartá-las diretamente. Peça ao modelo para comprimir as voltas antigas em algumas frases no mesmo script da conversa, então insira esse resumo logo após o prompt do sistema. Custa uma chamada extra de vez em quando e mantém a persona e os fatos estáveis.
Lembre-se também de limitar max_tokens de forma sensata para chat. Respostas em uma interface de mensagens raramente precisam de mais de algumas centenas de tokens, e um limite mais restrito torna a latência e o custo mais previsíveis. O streaming da resposta token por token ajuda na velocidade percebida, especialmente para texto chinês onde os usuários leem em curtos intervalos.
Lista de verificação de pré-lançamento e próximos passos
- Mapeie cada localidade para um prompt do sistema e teste a unidade do mapeamento.
- Defina codificações explicitamente em leituras de arquivo, corpos de solicitação e logs.
- Registre o
usagepor recurso e compare-o com seu estimador semanalmente. - Trate 402 (
no_credit), 429 e 503 (upstream_busy) de forma diferente: recarregue, reduza a velocidade ou tente novamente após alguns segundos. - Trate 403 (
content_blocked) como resposta final para essa requisição, não como caso de nova tentativa.
Se seu app envolve pipelines de tradução, continue com o guia de tradução e localização; para ficção serializada e chat de personagens, veja o guia de ficção web. A referência completa de parâmetros está nos docs.
Perguntas e respostas
Como faço para que as respostas voltem apenas em chinês simplificado?
Defina isso em um prompt de sistema, por exemplo "responda sempre em chinês simplificado com vocabulário da China continental". Mantenha essa instrução na mensagem do sistema e adicione uma verificação pós-geração se a saída precisar ser estrita.
Posso solicitar chinês tradicional para usuários de Taiwan?
Sim. Use um prompt de sistema escrito em caracteres tradicionais que nomeie o vocabulário regional desejado e mapeie isso a partir da localidade zh-TW no seu código.
Por que vejo caracteres chineses estranhos na saída?
Quase sempre um problema de codificação no lado do cliente. Leia os arquivos como UTF-8, defina o charset do tipo de conteúdo e certifique-se de que seu terminal ou visualizador de logs também use UTF-8.
Quantos tokens o texto chinês utiliza?
Planeje com aproximadamente 1,5 tokens por caractere como estimativa, depois verifique o campo de uso em cada resposta e ajuste sua estimativa.
Sua chave está a um formulário de distância
Crie uma conta, copie a chave, altere a URL base. Essa é toda a configuração.