前三篇文章我们学了大模型的工作原理、Prompt Engineering 的 6 大技巧、以及推理模型的概念。这篇文章是动手篇——我们要写代码,把这些理论变成可以运行的程序。
我们选用的学习资源是 Prompt Engineering Guide,它是目前最全面的 Prompt 工程教程(GitHub 48k+ stars)。但光看不练没用,所以这篇文章会带你做一个完整的小项目:一个基于 LLM 的技术文章摘要生成器。
准备工作
环境要求
- Python 3.9+
- 一个 LLM API key(OpenAI、DeepSeek、或其他兼容 OpenAI 接口的服务都可以)
安装依赖
pip install openai python-dotenv
配置 API Key
在项目根目录创建 .env 文件:
OPENAI_API_KEY=sk-your-api-key-here
# 如果用 DeepSeek,改为:
# OPENAI_BASE_URL=https://api.deepseek.com
# OPENAI_API_KEY=sk-your-deepseek-key
第一步:最简 API 调用
先跑通最基本的 LLM 调用,确保环境没问题:
import os
from dotenv import load_dotenv
from openai import OpenAI
load_dotenv()
client = OpenAI(
api_key=os.getenv("OPENAI_API_KEY"),
base_url=os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1")
)
response = client.chat.completions.create(
model="gpt-4o-mini", # 或 "deepseek-chat"
messages=[
{"role": "user", "content": "用一句话解释什么是 LLM"}
]
)
print(response.choices[0].message.content)
跑通后你应该能看到模型的回复。这个最简单的例子就是一个 Zero-shot Prompt——直接问,没给示例。
第二步:用 System Prompt 定义角色
现在给模型加一个 System Prompt,让它扮演一个"技术文章编辑":
system_prompt = """你是一位资深技术编辑,擅长将复杂的技术文章浓缩为简洁的摘要。
你的摘要应该:
1. 第一句话概括文章核心观点
2. 列出 2-3 个关键要点
3. 最后一句话说明适用人群
不要使用"本文介绍了..."这种开头,直接说重点。"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": "请为以下文章写摘要:..."}
]
)
对比一下加了 System Prompt 前后的输出质量——你会发现角色设定对输出的专业度和格式有显著提升。
第三步:加入 Few-shot 示例
给模型看几个"优秀摘要"的例子,帮它理解你想要什么风格:
messages = [
{"role": "system", "content": system_prompt},
# Few-shot 示例
{"role": "user", "content": "文章:《Attention Is All You Need》论文解读"},
{"role": "assistant", "content": """Transformer 架构用自注意力机制完全取代了 RNN 的循环结构,在机器翻译任务上取得 SOTA。
关键要点:
- Self-Attention 让每个 token 能关注序列中任意位置
- 多头注意力捕捉不同层次的语言关系
- 并行计算大幅提升训练效率
适合关注 NLP 架构演进的研究者和工程师。"""},
# 实际请求
{"role": "user", "content": f"文章:{article_text}"}
]
第四步:用 CoT 提升摘要质量
对于特别长的文章,让模型先分析再总结:
cot_prompt = f"""请分析以下技术文章并生成摘要。
先思考以下问题(不需要输出思考过程):
1. 文章的核心问题是什么?
2. 提出了什么解决方案?
3. 关键技术细节有哪些?
4. 目标读者是谁?
然后按以下 JSON 格式输出:
{{
"one_liner": "一句话核心观点",
"key_points": ["要点1", "要点2", "要点3"],
"audience": "适用人群",
"difficulty": "入门/中级/高级"
}}
文章内容:
{article_text}"""
这里同时用了 CoT(引导思考)和 Structured Output(JSON 格式),两个技巧组合使用。
第五步:完整项目——批量摘要生成器
把前面的步骤组合成一个完整的工具:
import json
from pathlib import Path
class ArticleSummarizer:
def __init__(self, model="gpt-4o-mini"):
self.client = OpenAI(
api_key=os.getenv("OPENAI_API_KEY"),
base_url=os.getenv("OPENAI_BASE_URL", "https://api.openai.com/v1")
)
self.model = model
self.system_prompt = """你是一位资深技术编辑...""" # 同上文
def summarize(self, article_text: str) -> dict:
"""生成单篇文章的结构化摘要"""
response = self.client.chat.completions.create(
model=self.model,
messages=[
{"role": "system", "content": self.system_prompt},
{"role": "user", "content": self._build_prompt(article_text)}
],
temperature=0.3, # 摘要任务要确定性高
response_format={"type": "json_object"} # 强制 JSON 输出
)
return json.loads(response.choices[0].message.content)
def batch_summarize(self, articles: list[str]) -> list[dict]:
"""批量生成摘要"""
results = []
for i, article in enumerate(articles):
print(f"处理第 {i+1}/{len(articles)} 篇...")
result = self.summarize(article)
result["token_usage"] = self._get_last_usage()
results.append(result)
return results
def _build_prompt(self, article_text: str) -> str:
return f"""请分析以下技术文章并生成摘要...
文章内容:
{article_text}"""
def _get_last_usage(self) -> dict:
# 获取本次调用的 token 使用量
pass # 实际实现中从 response.usage 获取
# 使用
summarizer = ArticleSummarizer()
# 读取文章
articles = [
Path("articles/article1.md").read_text(),
Path("articles/article2.md").read_text(),
]
# 批量生成
results = summarizer.batch_summarize(articles)
# 保存结果
for article, result in zip(articles, results):
print(json.dumps(result, ensure_ascii=False, indent=2))
第六步:对比实验——不同技巧的效果
这是最有学习价值的部分。对同一篇文章,分别用不同技巧生成摘要,对比质量差异:
article = "这里放一篇 500 字以上的技术文章..."
# 实验 1: Zero-shot(最简)
print("=== Zero-shot ===")
print(call_llm(f"总结这篇文章:{article}"))
# 实验 2: + System Prompt
print("\n=== + System Prompt ===")
print(call_llm(f"总结这篇文章:{article}", system=system_prompt))
# 实验 3: + Few-shot
print("\n=== + Few-shot ===")
print(call_llm(few_shot_messages + [user_msg(article)]))
# 实验 4: + CoT
print("\n=== + CoT ===")
print(call_llm(cot_prompt.format(article_text=article)))
# 实验 5: 用推理模型 (o1-mini / deepseek-reasoner)
print("\n=== 推理模型 ===")
print(call_llm(f"总结这篇文章:{article}", model="o1-mini"))
你会发现:从实验 1 到实验 4,输出质量逐步提升。而推理模型(实验 5)在不需要复杂 Prompt 的情况下就能给出高质量结果——验证了上一篇讲的内容。
关键收获
通过这个实战项目,你应该体会到以下几点:
Prompt Engineering 技巧是叠加使用的。实际项目中不是只用一个技巧,而是 System Prompt + Few-shot + CoT + Structured Output 组合起来,每个技巧解决一个层面的问题。
Temperature 不是越高越好。摘要、分类这类任务需要确定性输出,Temperature 设低(0.2~0.5)。创意写作可以设高(0.8~1.2)。
结构化输出让 LLM 可编程。当输出是 JSON 格式时,你可以用代码解析、存储、传递——这是后面做 Agent 时工具调用的基础。
不同模型适合不同任务。快速摘要用普通模型,复杂推理用推理模型。选对模型比调 Prompt 更重要。
第一阶段总结
恭喜你完成了第一阶段的全部学习!回顾一下你学到的东西:
| 篇目 | 核心知识 |
|---|---|
| 第 1 篇 | LLM 是逐 token 预测的概率机器,Transformer 架构、Tokenization、Context Window |
| 第 2 篇 | 6 大 Prompt Engineering 技巧:Zero-shot、Few-shot、CoT、Self-Consistency、System Prompt、Structured Output |
| 第 3 篇 | 推理模型通过 test-time compute 自主推理,和 CoT Prompt 有本质区别 |
| 第 4 篇 | 动手搭建 LLM 应用,组合使用各种技巧,对比不同方案的效果 |
这些知识构成了你理解 Agent 的基础。接下来第二阶段,我们会进入 Loop Engineering——让 LLM 不只是回答一个问题,而是自主循环执行任务。你会学到 ReAct 范式、Function Calling、以及从 Tool 到 Skill 的封装思维。
准备好了就进入第二阶段吧!
扩展练习
想继续提升?试试这些练习:
- 加入 Self-Consistency:对同一篇文章生成 5 个摘要,投票选出最佳版本
- 接入 RAG:先检索相关文章片段,再生成摘要(预习第三阶段内容)
- 做成 Web 应用:用 Gradio 或 Streamlit 给摘要器加一个界面
- 对比不同模型:用同一组文章测试 GPT-4o-mini、DeepSeek-V3、Qwen 的表现差异