Prompt Engineering 101: Few-Shot + CoT + Structured Output
Model capabilities are fixed; what truly differentiates outcomes is Prompt Engineering. Mastering the big three (few-shot exemplars, chain-of-thought, structured output) lifts quality one tier on the same model, reliably feeding production pipelines.
Few-Shot: Style Alignment by Example
"Rewrite professionally" is vague and yields random results. Prepend 2-3 real input-output exemplars in the prompt; the model precisely learns your style, formatting rules, and terminology preferences from concrete samples. Far more stable than pure natural-language instructions, and handles bilingual mixed corpora.
from openai import AsyncOpenAI
import json
from typing import Any
from pydantic import BaseModel, Field
client = AsyncOpenAI()
FEW_SHOT_PROMPT = '''你是资深后端技术写作编辑,擅长将草稿改写成精炼博客风格。
要求:事实准确,保留技术细节,简洁专业,段落开头先给核心结论。
## 示例1 输入
"FastAPI比Flask快,因为用了ASGI和Pydantic,自动生成文档"
## 示例1 输出
**核心结论:FastAPI 通过 ASGI 异步 + Pydantic 类型驱动两大设计,同等硬件下单接口吞吐量约为 Flask 的 2.5-4 倍。**
除异步网络栈外,FastAPI 的请求校验基于 Pydantic v2 的 Rust 内核(pydantic-core),单个 schema 校验耗时较 Flask + marshmallow 方案低一个数量级;另一个隐形收益是基于 OpenAPI spec 自动生成的接口文档和类型化客户端 SDK,在团队协作场景相当于免费的 API 契约工具链。
## 待改写输入
"{raw_input}"
## 你的输出'''
COT_PROMPT = '''你是算法竞赛金牌选手。请逐步推导再给出最终答案,每一步标记并解释推理依据。
问题:给定数组 nums = [3, 1, 4, 2, 5, 8, 7, 6],求最长递增子序列的长度。
思考步骤:
步骤1:
步骤2:
步骤3:
最终答案(仅数字):'''
class ProductCategorizeResult(BaseModel):
reasoning: list[str] = Field(description="分类判断过程,每个维度一条")
category: str = Field(description="必须属于 [Electronics, Fashion, Books, Home, Other]")
confidence: float = Field(ge=0.0, le=1.0)
matched_keywords: list[str] = Field(default_factory=list)
async def few_shot_transform(raw: str) -> str:
r = await client.chat.completions.create(
model="gpt-4o-mini", temperature=0.3,
messages=[{"role": "user", "content": FEW_SHOT_PROMPT.format(raw_input=raw)}])
return r.choices[0].message.content or ""
async def categorize_structured(title: str, desc: str) -> dict[str, Any]:
r = await client.chat.completions.create(
model="gpt-4o-mini-2024-07-18", temperature=0.0,
messages=[{"role": "user", "content": f"商品标题 {title}\n描述 {desc}"}],
response_format={"type": "json_object"})
data = json.loads(r.choices[0].message.content or "{}")
return ProductCategorizeResult(**data).model_dump()
Chain-of-Thought & Structured Outputs
For multi-step reasoning (logic/math/code debugging), explicitly require step-by-step deduction before final answer - accuracy typically improves 15-30%. For downstream-system consumption, enforce JSON mode via Pydantic response_format + retry on parse failures to avoid brittle free-text regex scraping.
| Technique | Problem Solved | Optimal Temp | Typical Use Cases |
|---|---|---|---|
| Zero-Shot instruction | Simple standard tasks | 0.1-0.3 | Translation, summarization, format conversion |
| Few-Shot exemplar injection | Custom style/format rules | 0.2-0.5 | Copy rewrite, labeling, coding style alignment |
| Chain-of-Thought steps | Multi-step reasoning/logic | 0.0-0.3 | Algorithm problems, debugging, root cause analysis |
| JSON Schema structured | Program interface handoff | 0.0 fixed | Tag ingestion, field extraction, function calling |
Best Practices
Start prompts with role (System), then context+task, then constraints (word count/format/tone/forbidden). Iterate against 20 labeled samples for real accuracy metrics; failure cases feed back as few-shot exemplars so every improvement has quantified evidence.