上个月让 DeepSeek 帮我写个 Python 脚本,处理 Excel 里的日期格式。我的提问是:“帮我写个脚本处理日期”。结果出来的代码——用正则表达式硬拆字符串,完全不考虑 pandas 的 to_datetime,还自作聪明加了时区转换,直接把我的数据搞乱了。
后来我把问题改成:“写个 Python 脚本,用 pandas 读取 sales.xlsx 中的‘下单时间’列,把格式从‘2025/12/31’统一成‘2025-12-31’,处理时忽略空值,输出新文件”。一次跑通,没出任何幺蛾子。
这事让我意识到:不是 AI 不够聪明,是我没问对问题。
于是开始系统研究提示词工程(Prompt Engineering)。三个月下来,踩了不少坑,也攒了些心得。这篇笔记就是我的实战记录,不讲虚的,全是能直接用的技巧。
一、先搞明白:提示词到底是个啥?
官方定义我就不抄了,说人话:
提示词就是你跟 AI 沟通的“说明书”——告诉它你是谁、要干啥、干成啥样、别干啥。
很多新手把 AI 当许愿池:“写个博客系统”、“做个电商网站”——结果出来的东西完全不能用。这就像对着 ATM 喊“给爷吐钱”,不给你报错都算 AI 脾气好。
| 维度 | 作用 | 例子 |
|---|---|---|
| System提示词 | 设定AI人格与行为准则 | “你是有10年经验的算法架构师” |
| User提示词 | 提出具体需求 | “设计支持千人并发的推荐系统架构” |
关系隐喻:System是游戏规则说明书,User是玩家操作指令。
二、两大模型,两种玩法
DeepSeek-R1:推理型选手
DeepSeek-V3:聊天型选手
- 特点:速度快、适合通用任务
- 黄金法则:结构要清晰
- 适合:代码生成、文本重写、摘要、快速迭代
- 数学题、复杂规划、策略分解 → 用 R1(零样本,少说话)
- 写代码、写周报、日常问答 → 用 V3(结构清晰就行)
三、基础语法:三段式框架
经过大量测试,我发现最好用的结构是[角色定义] + [任务描述] + [输出规范]。
3.1 角色定义
text
[角色]:具有5年经验的微服务架构师,精通Spring Cloud生态
测试数据显示,具体化的经验描述可使技术方案可行性提升35%。
3.2 任务描述
text
任务:实现用户登录接口 STEP 1: 验证用户名密码(从MySQL查询) STEP 2: 生成JWT token(有效期2小时) STEP 3: 返回token和用户基本信息
3.3 输出规范
text
输出规范: - 格式:Markdown表格 - 内容:包含接口名称、方法、路径、参数说明、示例 - 风格:技术文档风格,避免营销话术
四、进阶技巧:让 AI 写“能用的代码”
4.1 用注释引导生成(Cue 思维)
这是我最常用的技巧:先写注释,再让 AI 补全。
python
# 读取销售数据,按月份统计各品类销售额,找出前3名 # 输入:sales_2025.csv(列:日期、品类、金额) # 输出:top3_by_month.csv
注释写得越清楚,生成的代码越靠谱。这其实就是 Trae 的 Cue 功能背后的逻辑——AI 从注释里理解你要干什么。
4.2 I/O 规范 + 测试用例
对于函数生成,直接用测试用例当验收标准:
text
编写一个Python函数 `normalize_name(s: str) -> str` 约束: - 修剪空白、折叠多个空格、标题大小写单词 - 保留连字符和撇号 - 仅ASCII;将非ASCII替换为最接近的 测试用例: - " mary ann o'brien " -> "Mary Ann O'Brien" - "JOSE-LUIS" -> "Jose-Luis" - "Zoë" -> "Zoe"
这种方式让 AI 一次性通过测试的概率提升到 90% 以上。
4.3 否定约束:告诉 AI 别干啥
有时候“不做什么”比“做什么”更重要:
text
生成API文档,要求: - 包含所有接口参数说明 - 禁止使用过时术语(如"EJB") - 避免营销话术 - !NOT_DO 使用存储过程(针对SQL生成场景)
4.4 动态参数控制
不同任务需要不同的“创造性”:
| 场景 | temperature | 说明 |
|---|---|---|
| 代码生成 | 0.1-0.3 | 确定性优先,别瞎编 |
| Bug修复 | 0.2-0.4 | 稳定为主 |
| 代码重构 | 0.3-0.5 | 适度创新 |
| 写注释/文档 | 0.3-0.5 | 准确第一 |
| 单元测试 | 0.2-0.4 | 覆盖边界就行 |
可以在提示词里直接嵌参数:
text
[角色:Python工程师]
任务:优化以下代码性能
参数设置:
- temperature: 0.2(严谨模式)
- max_tokens: 800
代码:{code}
五、避坑指南:那些我踩过的坑
坑1:过度提示,适得其反
现象:提示词写了三四百字,结果 AI 输出僵化、缺乏灵活性。
原因:对 R1 这类推理模型,过度约束会压制它的内部推理能力。
text
[核心要求]:实现用户登录功能(JWT + MySQL) [可选扩展]: - 添加验证码(优先级低) - 支持第三方登录(优先级中)
坑2:上下文太长,信息丢失
现象:对话到后面,AI 忘了前面说过什么。
原因:DeepSeek-R1 有 4096 tokens 的上下文窗口,分配不合理。
- 输入信息 ≤ 60%(约 2457 tokens)
- 示例对话 ≤ 25%(约 1024 tokens)
- 输出缓冲区预留 15%(约 615 tokens)
坑3:语义冲突,指令打架
现象:角色设定说“要严谨”,任务描述又说“要有创意”,AI 不知道怎么执行。
坑4:把 API Key 写死在代码里
现象:代码传到 GitHub,Key 被人拿去乱用。
解决:永远用环境变量:
python
import os
API_KEY = os.environ.get("DEEPSEEK_API_KEY") # 从系统环境变量读
六、实战案例:从需求到代码的全流程
案例1:写一个带缓存的用户查询接口
原始提示词(错误示范):
text
写个用户查询接口
优化后提示词:
text
[角色]:5年经验的Python后端工程师,熟悉FastAPI和Redis [任务]:实现用户信息查询接口 STEP 1: 定义数据模型(Pydantic) STEP 2: 从MySQL查询用户基础信息 STEP 3: 添加Redis缓存(过期时间5分钟) STEP 4: 返回JSON响应 [约束]: - 使用async/await - 添加错误处理(用户不存在返回404) - 包含类型注解 - !NOT_DO 使用同步数据库驱动 [输出]:完整的可运行代码 + 依赖列表
效果:一次生成,直接可跑,缓存逻辑正确,错误处理完整。
案例2:重构一段烂代码
原始代码:
python
def process_data(d):
r = []
for i in range(len(d)):
if d[i] > 10:
r.append(d[i] * 2)
return r
优化提示词:
text
[角色]:代码审查专家,擅长Python性能优化
[任务]:重构以下代码,提升可读性和性能
要求:
1. 改用列表推导式
2. 添加函数类型注解
3. 解释修改的理由(不超过3句话)
4. 保留原有功能不变
代码:{上面那段}
输出:
python
from typing import List
def process_data(data: List[float]) -> List[float]:
"""过滤大于10的值并翻倍"""
return [x * 2 for x in data if x > 10]
# 修改理由:
# 1. 列表推导式比显式循环更简洁且性能更好
# 2. 类型注解提高了代码可读性
# 3. 变量命名更清晰(d→data)
七、建立自己的提示词库
用多了就会发现,很多场景的提示词是可复用的。我建了个文件夹,按场景分类:
text
/prompts
├── code/
│ ├── api_endpoint.md # REST接口生成
│ ├── db_query.md # 数据库查询
│ └── unit_test.md # 单元测试生成
├── docs/
│ ├── readme.md # README生成
│ └── api_docs.md # API文档
├── debug/
│ ├── error_explain.md # 报错解释
│ └── performance.md # 性能优化
└── templates/
├── system_roles.json # 常用角色定义
└── constraints.md # 常用约束条件
每个模板包含:
- 适用场景
- 完整提示词(带占位符)
- 实测效果
- 踩坑记录
八、几点感悟
8.1 提示词是“认知投影仪”
你对 AI 输出的质量,本质上是你思维清晰度的投影。模糊的提示词只能得到似是而非的结果。
8.2 少即是多
顶尖的提示词工程师都懂“少即是多”。一句“用苏格拉底式提问帮我理解量子力学”,胜过千字冗长说明。
8.3 AI 是搭档,不是许愿池
它不会替你思考业务逻辑,不会替你设计系统架构。你得告诉它做什么、怎么做、做完检查。