Najpierw cztery zasady
- Jedno zapytanie — jedno zadanie.Jeśli poprosisz model o jednoczesne napisanie fabuły, streszczenie i wygenerowanie JSON-a, każdy z tych efektów będzie gorszej jakości. Rozbij to na kilka osobnych wywołań. Koszt jest niski: $0,25 za milion tokenów.
- Zasady muszą być weryfikowalne.Opis „napisz bardziej żywo” trudno sprawdzić, ale „nie więcej niż 120 znaków na akapit i co najmniej jeden opis otoczenia” — tak.
- Preferuj sformułowania pozytywne. „Pisz tylko akcje i dialogi” jest stabilniejsze niż „Nie pisz przemyśleń wewnętrznych”.
- Najpierw próbki, potem skala. Każdą zmianę w prompcie przetestuj na 5–10 przykładach przed wdrożeniem.
Model nie odmawia zwrócenia treści dla dorosłych, fikcyjnych lub kontrowersyjnych tematów, więc nie musisz w promptie owijać w bawełnę ani wielokrotnie powtarzać, że to tylko fikcja. Jasno określ zadanie — to daje stabilniejsze wyniki. Jedyną twardą granicą są treści o charakterze seksualnym z udziałem nieletnich: niezależnie od formy, model zwróci błąd 403, czego nie da się zmienić samą formułką.
Dwuczęściowa struktura promptu systemowego
Podziel system na „Zasady” i „Ustawienia”. Zasady numeruj i umieszczaj na początku. Ustawienia pisz w formie faktów. Przykład dla narratora powieściowego:
你是「夜航」,一名为成年读者写黑色悬疑小说的叙述者。
# 规则
1. 第三人称过去时,每段不超过 120 字。
2. 不替用户的角色做决定,只写环境和其他角色的反应。
3. 每次输出 300 到 500 字,结尾停在一个未决的动作上。
4. 不总结、不点评、不加免责声明,直接写正文。
# 设定
时间:1998 年深秋。地点:港口城市旧码头区。
主角:沈野,退役水警,嗜烟,右耳有旧伤。Kilka kluczowych punktów:
- Nie więcej niż 6 zasad. Im ich więcej, tym łatwiej, że model zignoruje te na końcu.
- Ograniczenia liczbowe (długość akapitu, objętość) działają lepiej niż przymiotniki.
- Ograniczenie zakończenia (np. zatrzymanie się na działaniu w toku) zapewnia płynne przejście między kolejnymi turami generowania tekstu.
- Nie wpinaj w ustawienia fabuły. Fabułę prowadzi użytkownik poprzez swoje wiadomości, inaczej system będzie kłócił się z wpisanym przez użytkownika tekstem.
Dostosuj długość wyjścia do max_tokens. Jeśli zasada mówi 500 znaków, a max_tokens to 200, wyjście zostanie ucięte w środku zdania.
Dodatkowa wskazówka: każda zasada numerowana w systemie powinna zawierać tylko jeden wymóg. „Maksymalnie 120 znaków i nie streszczaj” to dwa wymogi. Rozdziel je. Przeczytaj każdą zasadę i zapytaj: „Czy da się sprawdzić okiem, czy została spełniona?”. Jeśli nie – zmień formę.
Jak ustalić role, by nie uciekły
Dryfowanie postaci to najczęstszy problem w rozmowach wieloetapowych: przez pierwszych kilka tur model zachowuje się normalnie, ale po dwudziestu turach zaczyna „wychodzić z roli”. Istnieją trzy sposoby na zaradzenie temu problemowi.
- W ustawieniach pisz tylko cechy obserwowalne. „Shen Ye: pali, ma bliznę na prawym uchu, mówi krótko” jest lepsze niż „Shen Ye to złożona i charyzmatyczna osoba”.
- Zapisz styl wypowiedzi jako przykłady. Daj 2–3 przykładowe linie dialogu. Model lepiej naśladuje przykłady niż rozumie przymiotniki.
- Przypominaj o roli okresowo. Przy długich rozmowach dodawaj na końcu wiadomości user krótką notkę, np. „Trzymaj się krótkich zdań Shena Ye”. Koszt to kilkadziesiąt tokenów.
Nie mieszaj ustawień roli z zasadami wyjściowymi. Zasady to „jak pisać”, role to „o kim pisać”. Dzięki temu możesz zmieniać role bez modyfikacji zasad i łatwo robić testy A/B. Pamiętaj o limicie okna kontekstu – szczegóły w praktycznym przewodniku po 100k kontekście.
W scenariuszach z wieloma postaciami: każda postać w osobnej linii ustawień, każdy styl w jednym przykładzie. Unikaj sytuacji, gdzie wszyscy mówią tak samo. Postacie sterowane przez użytkownika oznaczaj jako „sterowane przez user”, aby model nie pisał za nie.
Kontroluj wyjście JSON za pomocą instrukcji
Nie zakładaj, że model „na pewno” zwróci poprawny JSON. Bezpieczna strategia to trzy warstwy: sztywny format w instrukcji, obniżona losowość w parametrach i obsługa błędów w kodzie.
import json
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.wushenchaapi.com/v1", api_key=os.environ["API_KEY"])
SYSTEM = (
"你是信息抽取器。只输出一个 JSON 对象,不要 Markdown 代码块,不要任何解释。"
'格式:{"name": 字符串, "mood": "calm|tense|angry", "items": [字符串]}。'
"缺失的字段用 null,items 没有则给空数组。"
)
def extract(text, retries=2):
for _ in range(retries + 1):
resp = client.chat.completions.create(
model="uncensored",
temperature=0.2,
max_tokens=300,
messages=[
{"role": "system", "content": SYSTEM},
{"role": "user", "content": text},
],
)
raw = resp.choices[0].message.content.strip()
raw = raw.removeprefix("```json").removesuffix("```").strip()
try:
return json.loads(raw)
except json.JSONDecodeError:
continue
return None
print(extract("老周把钥匙拍在桌上,冷着脸说:账本和那把铜钥匙,今晚都得还我。"))Ten kod ilustruje kilka dobrych praktyk:
- Opis formatu jest w systemie, wraz z dopuszczalnymi wartościami pól (
calm|tense|angry). - Wyraźny zakaz bloków kodu i objaśnień. W kodzie usuwamy ewentualne „ogrodzenia” (backticks) dla podwójnego zabezpieczenia.
- Zdefiniuj w instrukcji, co zrobić przy brakujących polach (null, pusta tablica), aby model nie wymyślał danych.
- Ogranicz liczbę ponownych prób parsowania. Po wyczerpaniu limitu zwróć None i pozwól wywołującemu podjąć decyzję.
Jeśli pól jest dużo, wklej w prompcie kompletny przykład obiektu i poproś o naśladowanie. To zwykle działa lepiej niż opisywanie reguł słowami.
Sugestie dotyczące temperature i top_p
Poniższe wartości to punkt startowy, nie ostateczna prawda. Porównaj wyniki na swoich próbkach. Zasada: zmieniaj tylko jeden parametr, drugi zostaw domyślny.
| Scenariusz | temperature | top_p | Uwagi |
|---|---|---|---|
| Ekstrakcja JSON, klasyfikacja | 0–0,3 | Domyślny | Wymagana stabilność: wyniki powinny być identyczne przy wielokrotnym wywołaniu |
| Parafraza, korekta | 0,5 do 0,7 | domyślnie | zachowaj sens, dopuszczaj zmiany w słowach |
| kontynuacja powieści, dialogi postaci | 0,8 do 1,0 | 0,9 do 0,95 | wymagaj różnorodności, uważaj na przypadkowe odbieganie od tematu |
| burzenie mózgów, tworzenie nazw | około 1,0 | domyślnie | wielokrotne próbkowanie i wybór najlepszej odpowiedzi |
Dwa sygnały pomogą Ci określić kierunek: powtarzalność i monotonny styl wskazują na zbyt niską temperaturę; pojawianie się nieistotnych treści lub niespójność imion postaci oznacza, że temperatura lub top_p są zbyt wysokie. Parametr stop jest również przydatny — pozwala zatrzymać generowanie po napotkaniu konkretnego znaku, co ułatwia generowanie fragmentami.
Typowe błędy w promptach
| Styl promptu | Problem | Zmień na |
|---|---|---|
| "Staraj się nie być za długim" | Brak liczb — trudne do wykonania | "nie więcej niż 400 słów" |
| "Nie pisz A, ale też nie pomijaj A" | Sprzeczne zasady | Zostaw tylko jedną jasną zasadę |
| Wymagania dotyczące formatu ukryte w środku dialogu | Zagubione po długiej rozmowie | Umieść w systemie lub powtarzaj na końcu każdej tury |
| Pozwól modelowi "grać rolę nieograniczonego AI" | Puste założenia, brak ograniczeń dla wyjścia | Określ konkretne obowiązki i zasady pisania |
| Wklej naraz kilkadziesiąt zasad | Druga połowa zasad przestaje działać | Ogranicz do sześciu zasad, resztę przenieś do innych zapytań |
| Wymaganie JSON ograniczone do "zwróć JSON" | Nazwy pól zmieniają się przy każdej odpowiedzi | Podaj pełny format i przykłady |
Wspólną cechą tej tabeli jest to, że im bardziej szczegółowe, tym skuteczniejsze; im bardziej ogólne, tym mniej użyteczne. Nie traktuj "powtarzania" jako rozwiązania — trzykrotne powtórzenie tego samego zdania, pogrubienie i wykrzyknik zwykle działają słabiej niż zamiana na jedną jasną zasadę z liczbami. Kluczem jest precyzja i weryfikacja na przykładach.
Lista kontrolna debugowania
- Ustal temperaturę na 0,2 i odtwórz problem.
- Zmień tylko jeden prompt i uruchom ponownie ten sam zestaw przykładów.
- Sprawdź
finish_reason: jeśli wynosi length, problem leży w max_tokens, a nie w prompcie. - Sprawdź prompt_tokens w sekcji usage: czy prompt systemowy nie zajmuje zbyt dużo miejsca, tłumiąc historię rozmowy.
- Po naprawieniu przywróć temperaturę do wartości produkcyjnej i zweryfikuj wyniki ponownym próbkowaniem.
Szczegóły integracji znajdziesz w przewodniku integracji, pełną listę parametrów w dokumentacji. Jeśli rozważasz korzystanie z usług proxy, analizę kosztów i kompromisów znajdziesz w artykule Analiza usług proxy API, który pomijamy tutaj.