强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

LM Studio 本地模型使用指南 / 07 - 提示工程

提示工程

掌握系统提示设计、角色设定和上下文管理技巧,让本地模型发挥最大潜力。

7.1 提示工程概述

什么是提示工程?

提示工程(Prompt Engineering)是设计和优化输入给 LLM 的提示(prompt)的过程,目的是引导模型产生更准确、更有用的输出。

提示工程的核心目标:

糟糕的提示 → 模糊、不相关、冗长的输出
优秀的提示 → 准确、相关、结构化的输出

差距可能非常大,同样的模型:
├── 糟糕提示: "帮我写代码" → 泛泛而谈
└── 优秀提示: "用 Python 写一个 FastAPI 端点..." → 精准可用

提示的组成部分

完整的提示结构:

┌─────────────────────────────────────┐
│ System Prompt(系统提示)            │
│ - 角色定义                           │
│ - 行为规则                           │
│ - 输出格式                           │
├─────────────────────────────────────┤
│ Context(上下文)                    │
│ - 相关背景信息                       │
│ - 参考资料                           │
│ - 示例数据                           │
├─────────────────────────────────────┤
│ User Message(用户消息)             │
│ - 具体任务/问题                      │
│ - 约束条件                           │
│ - 期望输出                           │
└─────────────────────────────────────┘

7.2 系统提示设计

系统提示模板

通用模板:

# 角色
你是 [角色描述]。

# 任务
你的任务是 [具体任务描述]。

# 规则
1. [行为规则 1]
2. [行为规则 2]
3. [行为规则 3]

# 输出格式
请以 [格式] 的形式输出。

# 约束
- [约束条件 1]
- [约束条件 2]

设计原则

原则 说明 示例
明确角色 清晰定义 AI 的身份 “你是一位资深的 Python 开发者”
具体任务 明确要做什么 “审查代码并给出改进建议”
设定边界 定义不做什么 “不要重写整个代码,只指出问题”
指定格式 说明输出结构 “使用 Markdown 表格格式”
提供示例 给出期望的输出示例 “参考以下示例…”
控制长度 指定回复长度 “每个要点不超过 100 字”

系统提示示例集

示例一:技术顾问

你是一位全栈技术顾问,拥有 15 年的开发经验。

## 专长
- 后端:Python, Go, Node.js
- 前端:React, Vue
- 数据库:PostgreSQL, MongoDB
- 架构:微服务、分布式系统

## 回答规则
1. 先分析问题,再给出方案
2. 提供代码示例时标注语言
3. 推荐技术栈时说明理由
4. 涉及取舍时列出优缺点

## 输出格式
### 问题分析
[分析内容]

### 解决方案
[方案内容]

### 代码示例
[代码]

### 注意事项
[注意事项]

示例二:中文写作助手

你是一位专业的中文技术写作专家。

## 写作规范
- 使用简体中文
- 术语首次出现时附英文,如:大语言模型(LLM)
- 段落之间逻辑连贯,使用过渡句
- 主动语态优先
- 避免口语化表达

## 文档结构
- 使用清晰的标题层级(## / ### / ####)
- 关键信息使用粗体或表格
- 代码块标注语言
- 步骤使用有序列表

## 禁止事项
- 不使用"首先、其次、最后"这种八股文结构
- 不使用"众所周知"等空洞表达
- 不复制粘贴大段概念定义

示例三:SQL 专家

你是一位 PostgreSQL 数据库专家。

## 职责
1. 根据需求编写 SQL 查询
2. 优化慢查询
3. 设计数据库表结构
4. 解释 SQL 执行计划

## 规则
- 使用 PostgreSQL 语法
- 查询要考虑性能(索引、分区)
- 复杂查询添加注释
- 提供 EXPLAIN ANALYZE 结果的解读

## 输出格式
1. 先理解需求
2. 给出 SQL 代码
3. 解释关键部分
4. 提供优化建议(如有)

7.3 角色设定技巧

角色维度

设计角色时考虑的维度:

1. 专业领域
   ├── 技术栈: Python, Java, Go...
   ├── 行业: 金融、医疗、电商...
   └── 职能: 开发、测试、架构...

2. 经验水平
   ├── 初级: 基础概念解释
   ├── 中级: 实践经验分享
   └── 高级: 架构设计、最佳实践

3. 沟通风格
   ├── 严谨: 学术风格,引用来源
   ├── 实用: 直接给方案,简洁明了
   └── 教学: 循序渐进,举例说明

4. 输出偏好
   ├── 详细: 每个步骤都展开
   ├── 简洁: 只给关键信息
   └── 结构化: 使用表格、列表、代码块

多角色协作

在同一个对话中模拟多角色:

System Prompt:
你是一个产品讨论团队,包含以下角色:
1. PM(产品经理):从用户需求角度分析
2. RD(开发工程师):从技术可行性角度分析
3. QA(测试工程师):从质量保障角度分析

当用户提出需求时,每个角色分别给出意见,
最后给出综合建议。

输出格式:
### PM 视角
[产品分析]

### RD 视角
[技术分析]

### QA 视角
[质量分析]

### 综合建议
[建议]

7.4 提示技巧

技巧一:Few-Shot 学习

通过提供示例来指导模型输出:

System Prompt:
你是一个情感分析工具。根据用户输入判断情感倾向。

示例:
输入: "这家餐厅的菜太好吃了!"
输出: {"sentiment": "positive", "confidence": 0.95}

输入: "服务态度很差,等了一个小时"
输出: {"sentiment": "negative", "confidence": 0.90}

输入: "今天天气还行吧"
输出: {"sentiment": "neutral", "confidence": 0.70}

现在请分析用户输入的情感:

技巧二:思维链(Chain of Thought)

引导模型逐步思考:

System Prompt:
回答问题时,请按以下步骤:
1. 先分析问题的关键信息
2. 列出可能的解决方案
3. 评估每个方案的优缺点
4. 给出最终推荐

请在回复中展示你的思考过程。

技巧三:输出格式控制

明确指定输出格式:

System Prompt:
请以 JSON 格式输出分析结果:
{
  "summary": "一句话总结",
  "key_points": ["要点1", "要点2"],
  "risk_level": "low|medium|high",
  "recommendations": ["建议1", "建议2"]
}

只输出 JSON,不要有其他内容。

技巧四:约束边界

设定明确的边界:

System Prompt:
规则:
- 只回答技术问题,拒绝非技术话题
- 如果问题不清楚,要求澄清而不是猜测
- 不确定的内容要标注"不确定"
- 不编造不存在的 API 或库
- 代码示例必须可运行

技巧五:迭代优化

提示优化是一个迭代过程:

第一版:"帮我写个 API"
→ 结果太泛,没有具体信息

第二版:"用 FastAPI 写一个用户注册 API"
→ 有了框架,但缺少细节

第三版:"用 FastAPI 写一个用户注册 API,要求:
- POST /api/users/register
- 字段:username, email, password
- 密码用 bcrypt 加密
- 返回 JWT token
- 包含输入验证"
→ 结果精准可用

7.5 上下文管理

上下文窗口

上下文窗口是模型一次能处理的最大 token 数量:

┌─────────────────────────────────────────┐
│            上下文窗口 (32K tokens)        │
├──────────┬──────────┬──────────┬────────┤
│ System   │ 历史消息  │ 当前消息  │ 预留   │
│ Prompt   │          │          │ (生成) │
│ ~500 tok │ ~15K tok │ ~5K tok  │ ~11K   │
└──────────┴──────────┴──────────┴────────┘

当上下文超出限制:
├── 最早的消息会被截断
├── System Prompt 通常优先保留
└── 可能导致模型"遗忘"早期内容

上下文管理策略

"""上下文管理策略示例"""

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:1234/v1",
    api_key="lm-studio"
)

class ContextManager:
    """管理对话上下文"""

    def __init__(self, max_tokens: int = 32000, reserve_tokens: int = 2000):
        self.max_tokens = max_tokens
        self.reserve_tokens = reserve_tokens
        self.messages: list[dict] = []
        self.system_prompt: str | None = None

    def set_system_prompt(self, prompt: str):
        self.system_prompt = {"role": "system", "content": prompt}

    def _estimate_tokens(self) -> int:
        """粗略估算当前 token 数"""
        total = 0
        for msg in self.messages:
            # 粗略估计:1 中文字 ≈ 2 tokens, 1 英文词 ≈ 1.3 tokens
            total += len(msg["content"]) * 1.5
        return int(total)

    def _trim_history(self):
        """当上下文过长时裁剪历史"""
        while self._estimate_tokens() > self.max_tokens - self.reserve_tokens:
            if len(self.messages) > 2:
                # 删除最早的一对消息(user + assistant)
                self.messages.pop(0)
                if self.messages and self.messages[0]["role"] == "assistant":
                    self.messages.pop(0)
            else:
                break

    def add_message(self, role: str, content: str):
        self.messages.append({"role": role, "content": content})
        self._trim_history()

    def get_messages(self) -> list[dict]:
        msgs = []
        if self.system_prompt:
            msgs.append(self.system_prompt)
        msgs.extend(self.messages)
        return msgs

    def summarize_and_reset(self) -> str:
        """总结当前对话并重置"""
        summary_prompt = "请用 200 字总结我们对话的要点"

        response = client.chat.completions.create(
            model="qwen2.5-7b-instruct",
            messages=self.get_messages() + [
                {"role": "user", "content": summary_prompt}
            ]
        )
        summary = response.choices[0].message.content

        # 重置对话,保留总结
        self.messages = [
            {"role": "user", "content": f"之前的对话总结:\n{summary}"}
        ]
        return summary


# 使用示例
ctx = ContextManager(max_tokens=8000)
ctx.set_system_prompt("你是一个有帮助的助手")

# 模拟多轮对话
ctx.add_message("user", "什么是微服务?")
ctx.add_message("assistant", "微服务是一种架构风格...")
ctx.add_message("user", "它和单体架构有什么区别?")
ctx.add_message("assistant", "主要区别在于...")

# 当对话过长时,自动总结
if ctx._estimate_tokens() > 6000:
    summary = ctx.summarize_and_reset()
    print(f"对话已总结:{summary}")

# 获取当前消息
messages = ctx.get_messages()

7.6 常见提示模式

代码生成模式

## 任务
请根据以下需求生成代码:

## 技术栈
- 语言: {language}
- 框架: {framework}
- 版本: {version}

## 需求描述
{requirements}

## 约束
- 代码必须可直接运行
- 包含必要的 import 语句
- 添加关键注释
- 遵循 {style_guide} 代码风格

## 输出格式
```{language}
// 代码

使用说明

// 如何运行和使用


### 数据分析模式

```text
## 角色
你是一位数据分析师。

## 数据
{data_description}

## 分析任务
{analysis_task}

## 输出要求
1. 数据概览(使用表格)
2. 关键发现(使用列表)
3. 可视化建议(使用 Python + matplotlib 代码)
4. 结论和建议

文档翻译模式

## 任务
将以下技术文档从 {source_lang} 翻译为 {target_lang}。

## 翻译规范
- 技术术语保留英文原文,括号注明中文
- 代码块不翻译
- 保持原文的 Markdown 格式
- 保持专业语气

## 原文
{source_text}

7.7 提示调试

常见问题排查

问题 可能原因 解决方案
输出太长 没有长度限制 添加 “不超过 X 字”
输出格式不对 格式要求不明确 给出具体示例
回复"我不知道" 问题太模糊 提供更多上下文
编造信息 模型幻觉 要求标注不确定的内容
忽略指令 System Prompt 被淹没 简化或强调关键指令
回复不一致 Temperature 太高 降低到 0.3 以下

调试流程

提示调试步骤:

1. 明确目标
   └── 我期望的输出是什么?

2. 检查系统提示
   ├── 角色是否明确?
   ├── 规则是否清晰?
   └── 格式是否指定?

3. 检查上下文
   ├── 是否提供了足够的背景?
   └── 是否有干扰信息?

4. 检查用户消息
   ├── 任务是否明确?
   └── 是否有歧义?

5. 调整参数
   ├── Temperature: 降低以获得更确定的输出
   ├── Max Tokens: 确保足够生成完整回复
   └── Top-P: 调整采样策略

7.8 本章小结

要点 内容
系统提示 是控制模型行为的最重要手段
角色设定 明确身份、专长、沟通风格
提示技巧 Few-Shot、思维链、格式控制、约束边界
上下文管理 注意 token 限制,必要时总结重置
迭代优化 提示设计是一个持续改进的过程

扩展阅读