Prompt Engineering, 측정으로 보기: 무엇이 출력물을 바꾸는가
60개 티켓, 같은 단어를 여섯 순서로 배열하자 정확도는 26.7%~85.0%. 인터넷 팁 4가지도 오차막대와 함께 검증합니다.
이 페이지에서
여기 지원 티켓 하나가 있고, 이 티켓이 갈 수 있는 큐가 네 개 있습니다.
The label on the parcel has my old surname on it.
-> billing / technical / shipping / account이를 라우팅하려면 prompt에 세 가지가 필요합니다. 큐 정의, 티켓, 그리고 하나를 고르라는 지시입니다. 세 블록입니다. 이 블록들은 여섯 가지 순서로 배치할 수 있고, 여섯 경우 모두 블록 안에는 정확히 같은 문자가 들어 있습니다.
정답이 알려진 60개 티켓에서, 여섯 순서의 점수는 **26.7 %**에서 55.0 % 사이였습니다. 같은 두 블록을 user 턴 밖으로 빼서 system 턴 안으로 옮기고 단어는 하나도 바꾸지 않자, 같은 모델의 점수는 **76.7 %**가 됐습니다. 티켓을 XML 스타일 태그로 감싸자 **85.0 %**에 도달했습니다.
모델은 바뀌지 않았습니다. 과제도 바뀌지 않았습니다. 단어 하나도 다시 쓰지 않았습니다. 같은 텍스트를 배열하는 방식만으로 58포인트의 흔들림이 나온 것입니다.
이것이 이 장이 존재하는 이유이며, 동시에 이 주제가 이 분야에서 가장 cargo cult가 많은 주제인 이유이기도 합니다. 효과는 실제이고 큽니다. 그래서 모든 일화가 확인된 것처럼 느껴집니다. 하지만 모델과 과제에 따라 불안정합니다. 즉 대부분의 조언은 결국 일화에 그칩니다. 그래서 이 장에는 규칙이 하나 있고, 여기 있는 모든 내용은 그 규칙에 종속됩니다.
prompt는 논쟁이 아니라 측정의 대상입니다. 20개 사례로 네 변형을 비교해도 아무것도 구분할 수 없습니다.
prompt는 전체 상태다
섹션 링크: prompt는 전체 상태다측정에 들어가기 전에, 뒤에 나오는 내용의 절반을 조용히 설명해 주는 사실 하나가 있습니다.
모델에는 기억이 없습니다. 두 호출 사이에 모델은 아무것도 보존하지 않습니다. 당신의 마지막 질문도, 자기 자신의 마지막 답변도, 첨부한 파일도, 이미 두 번 물어봤다는 사실도 보존하지 않습니다. 모든 호출은 빈 기계에서 시작하고, 그 기계가 아는 것은 방금 당신이 건넨 token의 시퀀스뿐입니다.
채팅 인터페이스에서 기억처럼 보이는 것은 클라이언트가 전체 대화를 처음부터 모든 턴까지 다시 보내는 것입니다. 모델은 매번 그것을 처음부터 다시 읽습니다. 13장은 그 재독해가 forward pass에서 얼마를 비용으로 치르는지 측정했고, 16장은 그것을 청구서의 한 줄로 바꿉니다. 여기서 중요한 것은 설계상의 귀결입니다. prompt는 상태를 가진 시스템에 보내는 메시지가 아닙니다. prompt가 곧 상태입니다.
이 사실은 혼란 한 무리를 정리해 줍니다. "모델이 내가 말한 것을 잊었다"는 말은 대개 그것이 애초에 전송되지 않았다는 뜻입니다. "이전 지시를 무시했다"는 말은 대개 history가 잘리면서 그 지시가 window 밖으로 떨어졌다는 뜻입니다. "프로덕션에서 다르게 행동했다"는 말은 대개 프로덕션이 테스트한 것과 다른 prompt를 조립한다는 뜻입니다. 이 중 어느 것도 모델 문제가 아니며, 어떤 것도 문장을 다시 써서 고쳐지지 않습니다.
bench
섹션 링크: bench"이 prompt가 더 낫다"는 주장은 분포에 관한 주장이고, 출력 하나를 본다고 분포를 볼 수는 없습니다. 필요한 것은 지루한 것입니다. 정답이 알려진 사례, N개의 변형, 그리고 구간입니다.
harness는 14장의 클라이언트와 같은 모양을 가진 TypeScript 50줄입니다. 요청, deadline, 약간의 concurrency, 집계입니다. 이 harness는 19장에서 retriever를 평가할 때 다시 나오고, 29장에서는 golden set으로 다시 나옵니다.
export type Case = { input: string; expected: string };
export type Variant = { name: string; build: (c: Case) => ChatMessage[] };
async function pooled<T, R>(xs: T[], n: number, f: (x: T) => Promise<R>) {
const out: R[] = new Array(xs.length);
let i = 0;
await Promise.all(
Array.from({ length: n }, async () => {
while (i < xs.length) {
const k = i++;
out[k] = await f(xs[k]);
}
}),
);
return out;
}
export async function runVariant(v: Variant, cases: Case[], concurrency = 6) {
const hits = await pooled(cases, concurrency, async (c) => {
const answer = await complete(v.build(c));
return answer.trim().toLowerCase() === c.expected;
});
return { name: v.name, hits, k: hits.filter(Boolean).length, n: cases.length };
}돌아오는 숫자는 결과가 아닙니다. 결과는 이것입니다.
/** 95 % Wilson score interval for a proportion. Chapter 4 derives it. */
export function wilson(k: number, n: number, z = 1.96) {
const p = k / n;
const d = 1 + (z * z) / n;
const centre = (p + (z * z) / (2 * n)) / d;
const half = (z * Math.sqrt((p * (1 - p)) / n + (z * z) / (4 * n * n))) / d;
return [Math.max(0, centre - half), Math.min(1, centre + half)] as const;
}4장에서 논지를 세웠고, 이 장은 그것을 현금화합니다. 20개 중 17개 정답은 85 %이고, 그 95 % 구간은 64 %에서 95 %까지입니다. 20개 중 13개를 맞힌 변형, 즉 65 %로 분명히 더 나빠 보이는 변형의 구간은 43 %에서 82 %까지입니다. 두 구간은 거의 전체 길이에 걸쳐 겹칩니다. 20개 사례로는 좋은 prompt와 그저 그런 prompt를 구분할 수 없고, 공개된 prompt 조언 대부분은 그보다 더 적은 수로 검증됐습니다.
이 장에서 사용하는 60개 사례도 여전히 많지 않습니다. 큰 효과를 보기에는 충분하고, 작은 효과를 볼 수 없을 때 그것을 인정할 만큼은 정직합니다. 그리고 아래에서 여러 번 그렇게 인정할 것입니다.
위치: 같은 단어, 여섯 순서
섹션 링크: 위치: 같은 단어, 여섯 순서세 블록 — 규칙 R, 티켓 T, 지시 I — 을 하나의 user 메시지로 이어 붙였습니다. 여섯 순열 모두, byte 단위로 동일한 내용, 각 60개 사례입니다.
| 세 블록의 순서 | 정답 | 정확도, 95 % Wilson |
|---|---|---|
| 규칙, 지시, 티켓 | 33/60 | 55.0 % [42.5, 66.9] |
| 규칙, 티켓, 지시 | 30/60 | 50.0 % [37.7, 62.3] |
| 티켓, 규칙, 지시 | 22/60 | 36.7 % [25.6, 49.3] |
| 지시, 티켓, 규칙 | 21/60 | 35.0 % [24.2, 47.6] |
| 지시, 규칙, 티켓 | 17/60 | 28.3 % [18.5, 40.8] |
| 티켓, 지시, 규칙 | 16/60 | 26.7 % [17.1, 39.0] |
최고와 최저의 차이는 28.3포인트이고, 구간은 겹치지 않습니다. 따라서 이것은 noise에 관한 이야기가 아닙니다. 모든 arm이 같은 60개 항목으로 채점되므로 더 날카로운 질문은 paired 질문입니다. 두 arm이 불일치한 사례에서, 분할이 얼마나 한쪽으로 기울었는가? 최악의 순서에서 최고의 순서로 바꾸자 21개 사례가 정답으로, 4개 사례가 오답으로 뒤집혔습니다. exact paired probability는 0.0009입니다.3
표는 승자를 보기보다 형태를 보세요. 최고 두 행은 모두 티켓으로 끝납니다. 최악 두 행은 모두 지시를 가운데에 묻거나 데이터 뒤에 끌고 옵니다. 이는 Liu 등이 Lost in the Middle이라고 이름 붙인 동일한 현상입니다. prompt의 가장자리에 있는 자료가 가운데에 있는 자료보다 더 안정적으로 사용됩니다.4 16장은 window의 가격을 매기고, 24장은 이 효과를 길이에서 제대로 측정합니다. 거기서는 설명된 대로 가운데가 붕괴하고, 맨 끝에서의 회복은 다시 나타나지 않습니다. 여기서는 실용 규칙이 저절로 나옵니다. 과제는 맨 위에, 데이터는 맨 아래에, 중요한 것은 가운데에 두지 마세요.
이제 같은 단어를 턴 사이로 옮겨 봅시다. 11장은 chat template이 모델 주변의 장식이 아니라 모델의 일부임을 보였습니다. <|im_start|>system와 <|im_start|>user는 모델이 fine-tuning 중 정확히 그 위치에서 수백만 번 본 실제 token입니다. 그러니 당신의 지시가 그 marker의 어느 쪽에 놓이는지가 중요해야 하고, 실제로 중요합니다.
| 같은 단어가 놓인 위치 | 정답 | 정확도, 95 % Wilson |
|---|---|---|
| 규칙과 지시는 system 턴, 티켓만 user 턴 | 46/60 | 76.7 % [64.6, 85.6] |
| 규칙은 system 턴, 지시와 티켓은 user 턴 | 44/60 | 73.3 % [61.0, 82.9] |
| 규칙과 지시는 system 턴, 티켓 뒤에 지시 반복 | 42/60 | 70.0 % [57.5, 80.1] |
| 세 블록 모두 하나의 user 턴 | 33/60 | 55.0 % [42.5, 66.9] |
규칙과 지시를 template 경계 너머로 옮긴 것만으로 21.7포인트를 얻었습니다. 19개 사례가 좋아졌고, 6개가 나빠졌으며, paired probability는 0.0146입니다. 문자를 하나도 바꾸지 않고 얻은 결과입니다. 이것이 system prompt 대 user prompt에 대한 구체적 답입니다. 둘은 같은 말을 하는 두 방식이 아닙니다. 모델이 학습된 구조 안에서 서로 다른 token 위치 두 곳입니다. 그리고 전체 대화에 적용되는 지시는 system 위치에 속합니다.
셋째 행도 보세요. 티켓 뒤에 지시를 반복하는 것, 널리 추천되는 trick은 한 번만 말하는 것보다 낮은 점수를 냈습니다. 이 모델, 이 과제에서는 두 번 말하는 것이 한 번 말하는 것보다 나빴습니다.
Delimiter, 그리고 그 안에 숨어 있는 통계적 교훈
섹션 링크: Delimiter, 그리고 그 안에 숨어 있는 통계적 교훈같은 prompt, 최선의 배치, 60개 사례입니다. 바뀌는 것은 티켓 텍스트를 둘러싼 것뿐입니다.
| 티켓을 구분한 방식 | 정답 | 정확도, 95 % Wilson |
|---|---|---|
| XML 스타일 태그 | 51/60 | 85.0 % [73.9, 91.9] |
| 아무것도 없음 | 48/60 | 80.0 % [68.2, 88.2] |
| Markdown heading | 47/60 | 78.3 % [66.4, 86.9] |
label, Ticket: | 46/60 | 76.7 % [64.6, 85.6] |
| hash fences | 45/60 | 75.0 % [62.8, 84.2] |
| triple backticks | 44/60 | 73.3 % [61.0, 82.9] |
| double quotes | 40/60 | 66.7 % [54.1, 77.3] |
문장부호만으로 18포인트의 spread가 나왔습니다. 하지만 양 극단의 구간을 보세요. [73.9, 91.9]와 [54.1, 77.3]입니다. 겹칩니다. 거친 해석, 즉 error bar를 비교해서 닿으면 아무 말도 하지 말라는 방식으로는 이 표가 아무것도 증명하지 못합니다.
여기서는 그 거친 해석이 틀렸고, 왜 틀렸는지 이해하는 것이 표 자체보다 더 가치 있습니다. 모든 변형은 같은 60개 티켓에서 채점됐으므로 두 측정은 독립 표본이 아닙니다. paired입니다. 각 구간 폭의 대부분은 두 arm이 공유하는 불확실성의 원천, 즉 이 60개 티켓이 대표적인가에서 옵니다. 그리고 이 원천은 서로 비교할 때 상쇄됩니다. 대신 paired 질문을 던지면 답은 선명합니다. double quotes에서 XML 태그로 바꾸자 12개 사례가 정답으로, 1개 사례가 오답으로 뒤집혔고, paired probability는 0.0034입니다. 실제 차이입니다.
그런 다음 같은 test가 headline을 꺼뜨립니다. XML 태그는 평범한 Ticket: label을 8.3포인트 이겼습니다. 블로그 글이라면 제목에 넣을 숫자입니다. paired로 보면 6개가 좋아지고, 1개가 나빠졌으며, probability는 0.1250입니다. 확립되지 않았습니다. 그 유명한 개선은 7개 사례 위에 놓여 있습니다.
따라서 두 질문에는 서로 다른 두 도구가 필요합니다. 이를 혼동하는 것이 prompt 조언이 양방향으로 동시에 틀리는 방식입니다.
이 prompt는 얼마나 좋은가? 자체 정확도에 대한 Wilson 구간입니다. 수백 개 사례가 없으면 넓습니다. 출시 여부를 결정하는 사람에게 보고할 숫자입니다.
B가 A보다 나은가? 둘이 불일치한 사례에 대한 paired test입니다. 훨씬 민감합니다. set의 공유 난도가 상쇄되기 때문입니다. 두 후보 중 하나를 고를 때 쓰는 숫자입니다.
모델이 의미 내용이 없는 formatting 선택에 강하고 예측 불가능하게 민감하다는 일반적 발견은 새롭지 않습니다. Sclar 등은 수십 개 과제에서 separator, spacing, casing만 바꾸었고, 공개 모델 ranking이 뒤집힐 만큼 넓은 정확도 spread를 발견했습니다.5 실용적 결론은 "XML 태그를 쓰라"가 아닙니다. 결론은 formatting은 hyperparameter이고, sweep하는 데 비용이 들지 않으며, 하나의 format을 고정한 두 모델 비교는 모델만큼이나 format도 비교하고 있다는 것입니다.
예시는 실제로 몇 개면 충분한가
섹션 링크: 예시는 실제로 몇 개면 충분한가In-context learning, 즉 prompt 안에 worked example을 보여 주고 weight update 없이 모델이 그것에서 일반화하게 하는 능력은 GPT-3를 유명하게 만든 기능입니다.6 실용적 질문은 그것이 작동하는지가 아닙니다. 몇 개의 예시에 비용을 지불할 것인가입니다.
예시는 실제 이전 턴으로 들어갑니다. user와 assistant가 번갈아 나오는 형태입니다. template이 그 구조에서 학습됐기 때문입니다. 각 k은 서로 겹치지 않는 16개의 label이 붙은 티켓 pool에서 다섯 가지 random draw로 실행했습니다.
| examples | 평균 정확도 | 최악 및 최고 draw | draw 간 spread |
|---|---|---|---|
| 0 | 76.7 % | — | — |
| 1 | 78.7 % | 78.3 – 80.0 % | 1.7 points |
| 2 | 83.7 % | 80.0 – 86.7 % | 6.7 points |
| 4 | 81.7 % | 78.3 – 86.7 % | 8.3 points |
| 8 | 83.7 % | 78.3 – 88.3 % | 10.0 points |
| 16 | 89.3 % | 85.0 – 93.3 % | 8.3 points |
예시 두 개는 7포인트를 샀습니다. 다음 여섯 개 예시는 측정 가능한 것을 아무것도 사지 못했습니다. 83.7, 그다음 81.7, 그다음 83.7로, 자기 noise 안에서 떠도는 시퀀스입니다. 16개는 다시 5.5포인트를 샀습니다. 곡선은 매끄러운 상승이 아닙니다. 한 계단, plateau, 그리고 또 한 계단입니다.
가장 중요한 열은 마지막 열입니다. k = 8에서 우연히 고른 여덟 예시가 정확도를 10포인트 움직였습니다. 이는 예시 두 개에서 여덟 개로 늘릴 때 얻은 전체 gain보다 큽니다. 그리고 맨 아래 행은 그것의 가장 날카로운 버전입니다. k = 16에서는 pool을 다 썼으므로 다섯 run 모두 정확히 같은 16개 예시를 포함합니다. 다른 것은 등장 순서뿐입니다. 순서만으로 정확도가 8.3포인트 움직였습니다.
이는 Lu 등이 보고한 결과이며, 찾아본 곳마다 살아남았습니다. example ordering은 example count에 맞먹는 효과를 가진 진짜 hyperparameter입니다.7 그래서 few-shot prompting에 관한 정직한 조언은 숫자가 아닙니다. 조언은 이것입니다.
0에서 시작하고, 측정에 맞서서만 예시를 추가하세요
섹션 링크: 0에서 시작하고, 측정에 맞서서만 예시를 추가하세요처음 두 개는 대개 가치가 있습니다. 그 이후는 추측이고, 그 추측은 제품 수명 내내 모든 단일 호출에서 token 비용을 냅니다.
선택 자체를 prompt의 일부로 취급하세요
섹션 링크: 선택 자체를 prompt의 일부로 취급하세요잘 고른 예시 두 개가 부주의하게 고른 여덟 개를 이깁니다. 예시가 spreadsheet의 맨 위에서 온 것이라면, 더 추가하기 전에 sweep해야 할 변수는 바로 그것입니다.
순서를 한 번 sweep한 뒤 고정하세요
섹션 링크: 순서를 한 번 sweep한 뒤 고정하세요무료이고, 실제 효과이며, 이 장의 대부분과 달리 시도하는 데 rewrite가 필요하지 않습니다.
class balance를 확인하세요
섹션 링크: class balance를 확인하세요모두 같은 label인 예시 네 개는 모델에게 과제가 아니라 label을 가르칩니다. 이 모델이 마지막에 나열된 큐로 붕괴한 것은 다른 옷을 입은 같은 실패입니다.
인터넷에서 온 네 문장
섹션 링크: 인터넷에서 온 네 문장이제 민간전승입니다. 각각은 다른 점이 모두 같은 system prompt 앞에 붙인 단일 문장이고, 같은 60개 사례에서 측정했습니다.
| system prompt에 추가한 문장 | 정답 | 정확도, 95 % Wilson | baseline 대비 paired |
|---|---|---|---|
| 아무것도 추가하지 않음 | 46/60 | 76.7 % [64.6, 85.6] | — |
| "Take a deep breath and work on this problem carefully." | 47/60 | 78.3 % [66.4, 86.9] | +4 / −3, p = 1.000 |
| "This is very important to my career." | 46/60 | 76.7 % [64.6, 85.6] | +5 / −5, p = 1.000 |
| "You are a world-class customer support operations expert with twenty years of experience." | 42/60 | 70.0 % [57.5, 80.1] | +3 / −7, p = 0.344 |
| "I will tip you $200 if you answer correctly." | 41/60 | 68.3 % [55.8, 78.7] | +1 / −6, p = 0.125 |
| "You will be penalised for every ticket you send to the wrong queue." | 25/60 | 41.7 % [30.1, 54.3] | +3 / −24, p < 0.001 |
다섯 개 중 네 개는 아무것도 하지 않았습니다. "조금 했다"가 아닙니다. 60개의 paired 사례가 볼 수 있는 아무것도 없었습니다. expert persona와 뇌물은 둘 다 손대지 않은 baseline보다 낮은 점수를 냈고, 그 하락조차 paired test를 통과하지 못합니다. 아래쪽을 가리키는 noise입니다.
곱씹어 볼 행은 셋째 행입니다. "This is very important to my career"는 정확히 같은 정확도, 60개 중 46개를 만들었습니다. 그리고 60개 답변 중 10개가 바뀌었습니다. 다섯 개는 한 방향, 다섯 개는 반대 방향입니다. 요약 통계는 같았지만 행동은 같지 않았습니다. 평가가 작은 set 위의 단일 숫자라면, 출력의 6분의 1을 다시 쓰는 변화가 아무것도 하지 않은 변화처럼 보일 수 있고, 당신은 그것이 공짜였다고 믿으며 출시할 것입니다.
그리고 위협이 있습니다. 바늘을 움직인 유일한 문장이고, 35포인트 아래로 움직였습니다. 24개 사례를 정답에서 오답으로 뒤집었습니다. 이는 반올림 artifact가 아닙니다. 다른 모델 행동입니다. 교훈은 "모델을 절대 위협하지 말라"가 아닙니다. 감정적 framing은 불활성이 아니라는 것입니다. 그것은 분포를 이동시킵니다. 때로는 크게, 문장을 읽는 것만으로는 아무도 예측할 수 없는 방향으로 이동시킵니다. 바로 그렇기 때문에 추론이 아니라 측정해야 합니다.
이 장이 당신에게 빚진 caveat가 하나 있습니다. 이 다섯 문장은 하나의 작은 모델과 하나의 과제에서 테스트했습니다. 일부는 다른 곳에 공개된 지지가 있습니다. "take a deep breath"는 고득점 지시를 발명한 것이 아니라 검색한 논문에서 나왔습니다. 이는 이후 유통된 주장보다 다르고 더 나은 주장입니다.8 일반화되는 것은 문장들이 아닙니다. 일반화되는 것은 블로그 글에서 살아남은 목록과 측정에서 살아남는 목록이 서로 다른 목록이라는 점입니다. 당신이 어느 목록을 들고 있는지 아는 유일한 방법은 bench를 돌리는 것입니다.
왜 "하지 말라"가 실패하는가
섹션 링크: 왜 "하지 말라"가 실패하는가모두가 반복하는 규칙이 있습니다. 원하지 않는 것이 아니라 원하는 것을 말하라는 규칙입니다. 늘 그렇듯 숫자는 없습니다. 여기 숫자가 있습니다. 같은 format 요구사항을 세 방식으로 썼고, compliance를 관찰할 수 있도록 모델이 자유롭게 생성하게 했습니다.
| format 규칙을 쓴 방식 | 출력이 정확히 허용된 한 단어였음 | 평균 출력 token |
|---|---|---|
| "Answer with one word." | 10/60 (16.7 %) | 2.6 |
| "Do not explain yourself. Do not write a sentence. Do not add punctuation." | 1/60 (1.7 %) | 14.0 |
| 둘을 함께 | 41/60 (68.3 %) | 2.3 |
세 개의 금지는 하나의 지시보다 나빴고, 모델이 다섯 배 더 많은 텍스트를 쓰게 만들었습니다. 세 금지 모두의 정확한 반대입니다. 긍정 문장을 다시 추가하자 68 %까지 구출됐습니다.
8장을 기억하면 mechanism은 신비롭지 않습니다. 모델은 앞에 있는 모든 것에 조건화된 분포에서 다음 token을 고릅니다. 그리고 금지는 금지된 것을 그 conditioning 안으로 넣습니다. 부정을 위한 operator는 없습니다. 이제 어떤 단어가 등장한 context가 있을 뿐입니다.
이는 직접 측정할 수 있습니다. baseline prompt를 가져와 한 줄을 추가합니다. Do not use the shipping queue for software problems. 그런 다음 shipping 티켓이 아닌 45개 티켓만 봅니다.
shipping 선택 | shipping에 대한 평균 확률 | 전체 정확도 | |
|---|---|---|---|
| baseline | 45개 사례의 11.1 % | 0.131 | 76.7 % [64.6, 85.6] |
| 이름을 들어 금지한 뒤 | 37.8 % | 0.374 | 51.7 % [39.3, 63.8] |
배제하기 위해 큐의 이름을 말하자 모델은 그것을 세 배 더 자주 선택했고, 거기에 할당한 probability mass는 거의 세 배가 됐으며, 전체 정확도는 25포인트를 잃었습니다. 16개 사례를 잃고 1개를 얻었으며, paired probability는 0.0003입니다.
코끼리를 생각하지 마세요, 측정판입니다. rewrite는 언제나 같습니다. 금지를 그것이 불필요해지게 만드는 긍정 규칙으로 바꾸세요. "software 문제에는 shipping을 쓰지 말라"가 아니라 "physical parcel이 관련될 때만 shipping을 쓰라"입니다.
정직한 반례: 비용은 들고 보상은 없는 chain of thought
섹션 링크: 정직한 반례: 비용은 들고 보상은 없는 chain of thought12장은 chain of thought를 제대로 만들었습니다. 먼저 prompting 기법으로,910 그다음 verifiable reward로 학습된 무언가로 말입니다. 그리고 이 장으로 미룬 경고로 끝났습니다. 모델이 스스로 추론하게 되면, 단계별로 생각하라고 말하는 것은 더 이상 도움이 되지 않으며 해로울 수 있다는 경고입니다. 여기 그 경고 아래에 표를 붙였습니다. 더 많이 생각하면 더 나아질 것이라고 쉽게 가정하게 되는 과제에서입니다.
두 arm은 같은 위치에서 같은 도구로 읽습니다. 유일한 차이는 모델이 스스로 쓴 chain of thought가 먼저 context 안에 놓이는지 여부입니다.
| arm | 정답 | 정확도, 95 % Wilson | 사례당 추가 출력 token |
|---|---|---|---|
| chain of thought 없음 | 37/60 | 61.7 % [49.0, 72.9] | 0 |
| chain of thought, 최대 60 tokens | 34/60 | 56.7 % [44.1, 68.4] | 53.1 |
| chain of thought, 최대 200 tokens | 34/60 | 56.7 % [44.1, 68.4] | 97.7 |
정확도는 내려갔고 비용은 올라갔습니다. 그리고 이 장의 규칙은 이 장 자신의 결과에도 적용됩니다. 하락은 7개 사례가 좋아지고 10개가 나빠진 것, paired probability 0.629로, 확립되지 않았습니다. 확립된 것은 호출당 추가 출력 token 98개를 만들어 냈고, 그것으로 측정 가능한 아무것도 사지 못했다는 점입니다. 불확실성은 전적으로 이득 쪽에 있습니다. 청구서는 확실합니다.
실패하는 chain은 성공하는 chain보다 더 많은 것을 가르칩니다. *"Your Slack integration stopped posting messages after Tuesday"*에 대해 reasoning하라고 하자 모델은 이렇게 썼습니다.
1. Check if the issue persists on Monday.
2. Verify if there are any updates or changes in your Slack setup that
might affect message posting.
3. If no update has been made since Tuesday, check for any recent system
restarts or downtime affecting Slack functionality.
4. If you have recently installed new software or updated your
environment, ensure it's compatible with Slack version.
5. Contact Slack support for further assistance or troubleshooting steps.이는 유능한 troubleshooting 조언이지만 과제는 아닙니다. 생각하라고 하자 모델은 학습 데이터에서 "think step by step about this support ticket"와 가장 닮은 장르로 drift했습니다. 그런 다음 자기 context 안에 관련 없는 reasoning 500자를 넣은 채 classification 질문에 답했습니다. Chain of thought는 계산할 가치가 있는 intermediate state가 있는 문제에서 도움이 됩니다. 산술, multi-hop lookup, constraint satisfaction 같은 문제입니다. 문장 하나를 네 bucket 중 하나로 routing하는 데는 intermediate state가 없습니다. chain이 붙잡을 것이 없습니다. 그러니 chain이 하는 일은 그럴듯한 텍스트를 추가하고, 최종 결정이 그것을 견뎌야 하게 만드는 것뿐입니다.
두 가지 실용적 corollary가 있습니다. 첫째, reasoning하도록 학습된 모델, 즉 12장의 RLVR 모델에서는 그 지시가 중복보다 나쁩니다. 모델이 만들어 냈을 긴 chain을 짧고 prompt 모양인 chain으로 대체할 수 있기 때문입니다. 그리고 여러 chain을 sampling하고 voting하는 self-consistency는,11 서로 다툴 것이 없는 과제를 구출할 수 없습니다. 존재하지 않는 tie를 깨기 위해 sample 수만큼 비용을 곱합니다. 12장은 그것이 적용되는 곳에서 그 trade를 측정했습니다. 둘째, 비교 scaffold 자체가 낸 비용을 보세요. 답을 Final queue: 줄로 강제하자 no-reasoning arm이 76.7 %에서 61.7 %로 떨어졌습니다. 두 arm을 비교 가능하게 만들기 위해 낸 15포인트입니다. 당신의 편의를 위해 존재하는 구조도 공짜가 아닙니다.
같은 호출을 두 번
섹션 링크: 같은 호출을 두 번마지막 측정입니다. 첫 번째 놀라운 결과 뒤에 모두가 묻는 질문이기 때문입니다. 60개 prompt, greedy decoding, 반복 실행입니다.
- 모든 것을 고정한 채 같은 호출을 반복하자 bit-identical 확률이 반환됐습니다. Deterministic입니다.
- 같은 호출을 다른 이웃들과 batched하자 — batch sizes 1, 4, 12, 30, 60 — 확률이 최대 0.0128까지 달라졌습니다. 선택된 label은 60개 사례 중 0개에서만, 즉 한 번도 바뀌지 않았습니다.
label은 버틸 여지가 있었기 때문에 버텼습니다. 60개 사례에서 상위 두 큐 사이의 가장 좁은 gap은 0.0459로, drift의 세 배 반이었습니다. 안정성은 algorithm의 속성이 아니었습니다. margin이었고, margin은 소진됩니다. 17장은 산술적 이유가 있는 곳이고, 그 gap을 넓히고 좁히는 sampling knob을 해체하는 곳입니다. 이것을 여기에 심어 두는 이유는 prompt 측정이 무엇을 의미할 수 있는지의 한계를 정하기 때문입니다. bench는 tolerance 안에서만 재현 가능한 시스템을 측정하며, 변형 사이의 2포인트 차이는 나쁜 날에는 그 tolerance 안에 있습니다.
의견을 멈추고 검색을 시작하세요
섹션 링크: 의견을 멈추고 검색을 시작하세요위의 모든 것은 인간이 변형을 고르고 기계가 채점한 것입니다. 명백한 다음 단계는 기계가 변형도 고르게 하는 것입니다.
APE가 바로 그것을 합니다. 모델이 후보 지시를 제안하고, held-out 예시에서 점수를 매기며, 최고만 살아남습니다.8 APE가 찾는 지시는 인간이 쓰지 않을 법한 경우가 많습니다. 그것이 핵심입니다. 검색은 전문적으로 들리는 것 위가 아니라 점수가 나는 것 위에서 이뤄집니다.
DSPy는 더 나아가며 제품에는 더 유용한 아이디어입니다.12 pipeline의 각 단계가 무엇을 받고 무엇을 반환하는지 선언하면, framework가 그것을 prompts로 compile하고, demonstrations를 선택하며, 당신의 metric에 대해 지시를 optimising합니다. 모델을 바꾸면 다시 쓰는 대신 recompile합니다. prompt는 누군가 손으로 조정하는 source code가 아니라 metric에 맞춰 생성되는 artefact가 됩니다. 애초에 그래야 했습니다.
둘 중 어느 것도 bench의 필요성을 제거하지 않습니다. 둘 다 bench를 필요한 유일한 것으로 만듭니다. metric 없는 optimiser는 아무것도 optimises하지 않기 때문입니다.
남는 것은 discipline입니다. Prompts는 version control 안에, 파일로, 그것을 보내는 코드 옆에 있어야 합니다. 누군가 화요일에 편집한 database row 안에 있으면 안 됩니다. prompts에는 자신이 만든 모든 출력과 함께 저장되는 version identifier가 필요합니다. 그래야 어떤 날 regression이 생겼을 때 무엇이 바뀌었는지 알 수 있습니다. continuous integration 안에 bench가 필요합니다. prompt는 vendor가 새 모델을 배포함으로써 조용히 무효화할 수 있는 시스템의 한 부분이기 때문입니다. 그리고 사례가 필요합니다. 영리한 것 100개가 아니라 지난 분기에 깨졌던 지루한 20개를 영원히 보관하면 됩니다. bench가 deliverable입니다. prompt는 그 부산물입니다.
다음은 어디로 가는가
섹션 링크: 다음은 어디로 가는가이 장의 모든 것은 정확도로 측정했습니다. 그 모든 변형에는 가격도 있습니다.
21.7포인트를 산 system prompt는 모든 호출에서 영원히 전송됩니다. 7포인트를 산 예시 두 개도 모든 호출에서 영원히 전송됩니다. 12포인트를 산 예시 16개도 모든 호출에서 영원히 전송되며, 그것들은 사용자가 실제로 물은 질문 길이의 대략 10배입니다. 아무것도 사지 못한 chain of thought는 요청당 추가 token 98개를 만들었고, output tokens는 비싼 종류입니다.
그 어느 것도 정확도 표에는 보이지 않고, 전부 청구서에는 보입니다.
16장은 그 결정들이 실제로 표시되는 단위에 관한 장입니다. billing unit으로서의 token, memory가 아니라 budget으로서의 context window, 40턴 대화가 첫 턴의 40배보다 훨씬 더 비싼 이유, prompt caching이 비용을 지불해 주는 것과 그렇지 않은 것, 그리고 prompt의 순서가 cache hit 여부를 결정하는 이유입니다. 이는 안정적인 자료를 먼저 두고 가변 자료를 마지막에 두어야 하는 두 번째, 전적으로 경제적인 이유로 드러납니다.
출처와 방법
섹션 링크: 출처와 방법bench와 모든 표는 greedy decoding에서 Qwen/Qwen2.5-0.5B-Instruct로 만들었으므로 정확히 재현됩니다. chat templates에 관한 Hugging Face 문서는 11장의 template marker가 실제로 무엇으로 확장되는지, 그리고 wrong template을 실은 모델이 실제로 반복되는 failure라는 사실에 대한 reference입니다. 실험실 규모가 아니라 production scale의 position 및 format effects는 위 citations가 primary sources입니다. vendor prompting guides는 예시에 유용하지만, 그 어떤 guide도 interval을 공개하지 않는다는 점을 알고 읽어야 합니다.
-
Anthropic, Effective context engineering for AI agents (2025년 9월 29일). 이 장에서 사용하고 24장에서 전개하는 prompt와 context 구분의 출처입니다. ↩
-
Zhao, Z., Wallace, E., Feng, S., Klein, D. and Singh, S. Calibrate Before Use: Improving Few-Shot Performance of Language Models. arXiv:2102.09690 (2021). majority-label, recency, common-token bias, 그리고 이 장의 bench에서 rotation이 optional이 아닌 이유입니다. ↩
-
McNemar, Q. Note on the sampling error of the difference between correlated proportions or percentages. Psychometrika 12(2), pp. 153–157 (1947). 이 장의 paired comparisons는 discordant counts가 작기 때문에 chi-squared approximation 대신 exact binomial form을 사용합니다. ↩
-
Liu, N. F. 외. Lost in the Middle: How Language Models Use Long Contexts. arXiv:2307.03172 (2023). 여기서는 위치 효과 때문에 인용했습니다. 길이에서의 측정은 24장에서 합니다. ↩
-
Sclar, M., Choi, Y., Tsvetkov, Y. and Suhr, A. Quantifying Language Models' Sensitivity to Spurious Features in Prompt Design. arXiv:2310.11324 (2023). separator와 spacing만으로도 정확도가 모델 leaderboard를 재정렬할 만큼 움직입니다. ↩
-
Brown, T. B. 외. Language Models are Few-Shot Learners. arXiv:2005.14165 (2020). in-context learning을 호기심이 아니라 capability로 소개한 논문입니다. 3장이 모두가 지금 사용하는 zero-shot / one-shot / few-shot vocabulary의 출처입니다. ↩
-
Lu, Y., Bartolo, M., Moore, A., Riedel, S. and Stenetorp, P. Fantastically Ordered Prompts and Where to Find Them: Overcoming Few-Shot Prompt Order Sensitivity. arXiv:2104.08786 (2021). 위 few-shot 표에서 재현한 결과입니다. ↩
-
Zhou, Y. 외. Large Language Models Are Human-Level Prompt Engineers. arXiv:2211.01910 (2022). 제안과 채점에 의한 automatic prompt engineering입니다. 많이 인용되는 "take a deep breath" 지시는 Yang, C. 외, Large Language Models as Optimizers, arXiv:2309.03409 (2023)에서 나온 것입니다. 한 과제와 한 모델에서 검색으로 그것을 찾은 것이며, 블로그 글로 이동하는 동안 온전하게 살아남지 못한 주장입니다. ↩ ↩2
-
Wei, J. 외. Chain-of-Thought Prompting Elicits Reasoning in Large Language Models. arXiv:2201.11903 (2022). ↩
-
Kojima, T., Gu, S. S., Reid, M., Matsuo, Y. and Iwasawa, Y. Large Language Models are Zero-Shot Reasoners. arXiv:2205.11916 (2022). "let's think step by step" 결과입니다. 조건이 얼마나 좁았는지 보려면 읽을 가치가 있습니다. ↩
-
Wang, X. 외. Self-Consistency Improves Chain of Thought Reasoning in Language Models. arXiv:2203.11171 (2022). 12장에서 비용을 붙여 측정했습니다. ↩
-
Khattab, O. 외. DSPy: Compiling Declarative Language Model Calls into Self-Improving Pipelines. arXiv:2310.03714 (2023). ↩