|
**Prompt 场景三原则**:一个业务一个场景、一个模型版本一个场景、一个模板一个场景——场景变了就换模板,别凑合。
默认模型什么都不知道,所以要先背景后要求:
```text
1. 人物/地点/时间/事件 背景交代
2. 角色定义(你是一个...)
3. 任务步骤(先做什么再做什么)
4. 输入说明
5. 输出格式约定
```
|
|
**结构化**:自然文本 → 结构化文本的过渡。结构化减少歧义、便于程序交互(JSON 化)。
精准输出用 JSON 逐字段定义格式:
```text
输出格式:
{
"name": "套餐名称,string",
"price": {"operator": ">=|<=|==", "value": "数字"}
}
```
配合 API 的 `response_format={"type":"json_object"}` 双保险。
|
|
**核心是思维链 = 伪算法**:分几步做成一件事。
- 像人一样思考:步骤化、一段文本一个意思、多举例
- 不熟的领域先问 LLM 要步骤(让它先给方法清单,再逐步执行)
- 有时一字之差对生成概率影响很大,也可能毫无影响——迭代试错是常态
简易调用(供下文案例复用):
```python
from tpf.llm.ollama import chat_ollama
from tpf.llm import chat
def ask(prompt, model="gpt-4o-mini"):
return get_completion(prompt, model=model)
# 本地小模型
res = chat_ollama(prompt, model='deepseek-r1:1.5b',
base_url='http://localhost:11434/v1/')
```
|
|
任务:把用户对手机流量套餐的自然语言需求,转成机器可处理的选择条件。
第一步只做**任务描述+实体关系**——先讲清实体(套餐的三个属性),模型才理解语义:
```python
instruction = """你的任务是识别用户对手机流量套餐产品的选择条件。
每种流量套餐产品包含三个属性:名称(name),月费价格(price),月流量(data)。
用户输入会包含选择条件,请提取并以 JSON 格式输出。"""
input_text = "办个100块以下的套餐,流量要多"
prompt = f"{instruction}\n用户输入:\n{input_text}"
response = ask(prompt)
```
|
|
加输出格式约束 + API 层 json_object:
```python
prompt = f"""{instruction}
以 JSON 格式输出,字段:name(string)、price(number)、data(number)"""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role":"user","content":prompt}],
response_format={"type":"json_object"} # 双保险
)
```
|
|
**表达式化**:中文条件 → 可执行查询结构(operator + value + sort):
```json
{
"data": {"operator": ">=", "value": 100},
"price": {"operator": "<=", "value": 100},
"sort": {"ordering": "asc", "key": "data"}
}
```
把"流量要多"翻译成 `data>=100 + sort(data desc)`——prompt 里定义 operator 取值集合(>= / <= / ==)与 sort 结构即可。
|
|
**增加示例(few-shot)**——用 `query()` 模板函数批量挂示例:
```python
examples = [
{"input":"便宜的套餐","output":{"sort":{"ordering":"asc","key":"price"}}},
{"input":"100块以内的月租","output":{"price":{"operator":"<=","value":100}}},
{"input":"流量大于50G","output":{"data":{"operator":">=","value":50}}},
# ... 共 9 例
]
def query(user_input):
ex = "\n".join(
f"输入:{e['input']}\n输出:{json.dumps(e['output'],ensure_ascii=False)}"
for e in examples)
return f"{instruction}\n\n示例:\n{ex}\n\n用户输入:\n{user_input}"
```
|
|
**针对不足补充**:实测发现"50元左右"被判成 `==` 不合理 → 增加 `fluctuation`(波动)字段并在规则与示例中显式声明:
```json
{"price": {"operator": "==", "value": 50, "fluctuation": "20%"}}
```
这就是 prompt 迭代的范式:跑 badcase → 定位规则缺失 → 补规则 + 补对应示例 → 回归。
|
|
**多轮对话**:把对话历史连同"每轮对应的 JSON"一起作为示例,再拼 context:
```python
examples_chat = [
{"messages":[{"role":"user","content":"便宜点的"},
{"role":"assistant","content":"{\"sort\":...}"},
{"role":"user","content":"流量再多点"}],
"output": {"sort":{"ordering":"asc","key":"price"},
"data":{"operator":">=","value":80}}},
]
# context = 已有对话历史 + 当前问题,一并进 prompt
```
效果:模型能基于上一轮的条件叠加修改,而不是每次从零理解。
|
|
同一套模板换本地 `deepseek-r1:1.5b`(chat_ollama 封装,base_url 指向 ollama):
- 1.5b:多数输入理解尚可,但**丢 fluctuation 字段**、偶尔返回空 `{}`
- 8b:仍有不稳定输出
- 14b:稳定但慢(一次约 11s vs 1.5b 的 1s)
|
|
针对性优化策略:
1. **按运行结果补示例**:把 badcase 加为近似示例——加到 4 个相似示例后 1.5b 输出才稳定
2. **降级链**:1.5b 返回空/缺字段 → 重试 3 次(字段有值即停)→ 仍失败换 14b
3. 成本视角:1.5b 快而糙适合第一道,14b 稳而慢做兜底——组合优于单选
```python
def ask_robust(prompt):
for _ in range(3):
out = chat_ollama(prompt, model='deepseek-r1:1.5b')
d = parse(out)
if d and d.get("price") or d.get("data"):
return d
return parse(chat_ollama(prompt, model='deepseek-r1:14b'))
```
|
|
实用 prompt:让 LLM 把重依赖代码改成"可选依赖"(torch 可选、延迟导入):
```text
请优化以下代码,要求:
1. torch 为可选依赖:模块导入时不强制 import torch
2. 使用处再延迟导入,并用 try/except ImportError 给出友好提示
3. 不改变已有函数的外部行为
代码如下:...
```
同类套路适用于"去 pandas 依赖/加超时重试/统一日志"等机械改造——描述约束比描述实现更有效。
|
|
- OpenAI 官方 prompt 教程与示例:platform.openai.com/docs/guides/prompt-engineering
- microsoft/promptbase:提示词工程资产库(市场/购买/案例)
- 自建 GPTs 案例库:github.com/73xuetu/GPTs
- 提示词市场(图像类 prompt 如"自拍"模板)可直接复用后微调
|
OpenAI Prompt Engineering
microsoft/promptbase