关注 : 提示词怎么优化?

学习目标 :

  1. 理解什么是提示词工程(Prompt Engineering)

  2. 掌握提示词的核心组成结构

  3. 掌握常见提示词设计技巧(Zero-shot / Few-shot / CoT 等)

  4. 掌握角色提示词

一、什么是提示词工程

提示词(Prompt)是用户提供给AI模型的输入指令,用于指导其生成特定输出。提示词工程则是设计、优化这些指令的过程,旨在提升输出的准确性、相关性和可用性。

核心价值:

降低幻觉(Hallucination):通过明确约束,减少AI“胡编乱造”。

提升效率 : 减少迭代次数, 一次性获的可用结果。

解锁潜能 :引导模型完成复杂推理、创意生成等高阶任务。

二、提示词的基本结构

一个完整的Prompt,一般包含一下几个部分:

1、角色(Role)

定义模型是谁

示例:

你是一名资深金融分析专家

2、任务(Tsak)

告诉模型要做什么

示例:

请对财务数据进行分类

3、输入(Input)

提供数据

示例:

用户问题:我退款怎么还没到账

4、输出格式(Output Format)

规定输出长什么样

示例:

请以JSON格式输出

5、约束(Constraint)

限制模型行为

示例:

不要编造信息,只能基于输入判断

6、示例(Example)

给模型“参考答案”

三、提示词的核心技巧

1、角色设定(Role Prompting)

不同角色 -> 输出风格完全不同

示例 :

你是客服 -> 更礼貌

你是分析师 -> 更理性

你是老师 -> 更有解释性

2、约束控制

控制模型“不要乱说”

示例:

不要编造

不确定请返回“无法判断”

只从给定内容中回答

3、Zero-shot(零样本)

不提供示例,直接让模型做

适合:简单任务

示例:

请判断这句话的情绪是证明还是负面

import os
from openai import OpenAI
from dotenv import load_dotenv
​
env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), ".env")
load_dotenv(env_path)
​
MODEL_API_KEY = os.getenv("MODEL_API_KEY")
MODEL_BASE_URL = os.getenv("MODEL_BASE_URL")
MODEL_NAME = os.getenv("MODEL_NAME")
client = OpenAI(api_key=MODEL_API_KEY, base_url=MODEL_BASE_URL)
​
def llm_response(user_prompt):
    response = client.chat.completions.create(
        model=MODEL_NAME,
        messages=[{"role": "user", "content": user_prompt}],
        stream=False,
        max_tokens=1024,
        temperature=0.7
    )
    return response.choices[0].message.content
​
def zero_shot_sentiment(text: str) -> str:
    """Zero-shot 情感:根据用户输入的一句话返回模型输出(仅任务说明,无样例)。"""
    prompt = f"""你是文本情感分析助手。
任务:判断下面这句话的情感倾向,只能从以下标签中选一个:正面、负面、中性。
待分析文本:{text}
输出要求:只输出一个标签,不要解释。"""
    return llm_response(prompt)
​
if __name__ == "__main__":
    user_text = "这家店的包装很用心,但配送比预计慢了一天。"
    print(zero_shot_sentiment(user_text))

4、Few-shot(少样本)

提供给模型几个示例

适合:分类、风格控制

示例:
输入:这个东西很好用 → 输出:正面
输入:太垃圾了 → 输出:负面
​
请判断:
输入:一点都不好 → 输出:
代码如下:
import os
from openai import OpenAI
from dotenv import load_dotenv
​
env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), ".env")
load_dotenv(env_path)
​
MODEL_API_KEY = os.getenv("MODEL_API_KEY")
MODEL_BASE_URL = os.getenv("MODEL_BASE_URL")
MODEL_NAME = os.getenv("MODEL_NAME")
client = OpenAI(api_key=MODEL_API_KEY, base_url=MODEL_BASE_URL)
​
​
def llm_response(user_prompt):
    response = client.chat.completions.create(
        model=MODEL_NAME,
        messages=[{"role": "user", "content": user_prompt}],
        stream=False,
        max_tokens=1024,
        temperature=0.7
    )
    return response.choices[0].message.content
​
​
def few_shot_intent(user_text: str) -> str:
    few_shot_prompt = f"""
    你是电商客服对话的意图识别助手。

5、Chain of Thought(思维链)

引导模型一步一步思考

示例:

请一步一步分析问题,并给出最终答案

作用:

提高复杂问题准确率

降低“胡说八道”

import os
from openai import OpenAI
from dotenv import load_dotenv
​
env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), ".env")
load_dotenv(env_path)
​
MODEL_API_KEY = os.getenv("MODEL_API_KEY")
MODEL_BASE_URL = os.getenv("MODEL_BASE_URL")
MODEL_NAME = os.getenv("MODEL_NAME")
client = OpenAI(api_key=MODEL_API_KEY, base_url=MODEL_BASE_URL)
​
def llm_response(user_prompt: str, max_tokens: int = 1024) -> str:
    response = client.chat.completions.create(
        model=MODEL_NAME,
        messages=[{"role": "user", "content": user_prompt}],
        stream=False,
        max_tokens=max_tokens,
        temperature=0.7,
    )
    return response.choices[0].message.content
​
def cot_word_problem(question: str) -> str:
    """Chain-of-Thought:要求模型先分步推理,再给出最终答案(适合算术/逻辑应用题)。"""
    prompt = f"""你是一名擅长应用题解析的助教。
​

6、结构化输出(JSON)

用于工程化场景

示例: 请严格按照以下 JSON 输出: {  "intent": "",  "confidence": "" }
import json
import os
from typing import Any
​
from dotenv import load_dotenv
from openai import OpenAI
​
env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), ".env")
load_dotenv(env_path)
​
MODEL_API_KEY = os.getenv("MODEL_API_KEY")
MODEL_BASE_URL = os.getenv("MODEL_BASE_URL")
MODEL_NAME = os.getenv("MODEL_NAME")
client = OpenAI(api_key=MODEL_API_KEY, base_url=MODEL_BASE_URL)
​
def llm_json_response(user_prompt: str, max_tokens: int = 1024) -> str:
    """要求模型只输出合法 JSON 对象(需兼容接口的 response_format)。"""
    response = client.chat.completions.create(
        model=MODEL_NAME,
        messages=[{"role": "user", "content": user_prompt}],
        stream=False,
        max_tokens=max_tokens,
        temperature=0.3,
        response_format={"type": "json_object"},
    )
    return response.choices[0].message.content
​
def classify_ticket_json(user_issue: str) -> dict[str, Any]:
    """
    将用户工单打成结构化 JSON,并在本地 json.loads 校验。
    若网关不支持 json_object,可把 response_format 一行去掉,仅靠提示约束。
    """
    prompt = f"""你是一名客服工单分析助手。请根据用户描述,输出一个 JSON 对象(不要 markdown 代码块,不要多余说明文字)。
​
JSON 的键必须严格如下,类型与取值说明:
- "category": 字符串,只能是 "退款问题" | "物流问题" | "商品问题" | "其他"
- "confidence": 数字,0 到 1 之间,表示你对分类的把握
- "summary": 字符串,一句话概括用户诉求(不超过 50 字)
​
用户工单:
{user_issue}
"""
    raw = llm_json_response(prompt)
    return json.loads(raw)
​
if __name__ == "__main__":
    issue = "上周买的鞋子码数偏小,能换大一码吗?运费谁出?"
    data = classify_ticket_json(issue)
    print(json.dumps(data, ensure_ascii=False, indent=2))

四、角色提示词

1、三种角色解释

调用对话式接口时,请求里的 messages 每条都有 role,用来区分这段话是谁说的。必须掌握的是三种:systemuserassistant

(1)system prompt(系统)

放在最前面,写相对稳定的设定:身份、规则、语气、输出格式等。具体某条工单、某句待分类原文更适合放在 user,不要塞进 system,否则每条业务数据都要改 system,难维护也费 token。

(2)user prompt(用户)

用户输入框里的内容,或程序拼出来的任务说明加数据。一轮里可以有多条 user,常与 assistant 交替;最后一条 user 往往是本次要模型针对回答的那段。任务说明和样例也可以全写在一个长 user 里;若拆成多条 user / assistant,在模型眼里更像「有轮次的对话」,便于做对话式 few-shot。

(3)assistant(助手)

模型上一轮已经生成的回复,下一轮请求里要带上,多轮才有上下文。也可以人工写一条 assistant 当标准答案,前面配 user 当例题,用来教格式或分类边界。

2、三种角色怎么配合

习惯上 system 在最前,后面 user 与 assistant 交替。新请求里带上此前相关轮次(注意 token 上限),再追加最新 user。概括:system 定规矩,user 给当前输入,assistant 是模型说过的话或你给的示范。

注意:

1)在 LangChain 里常写成 SystemMessageHumanMessageAIMessage,含义与上面三种 role 一致。

2)system 并非绝对约束,重要规则可配合格式约定或程序校验。单次任务说明(如「只输出标签」)有人放 user 顶部、有人放 system,团队统一即可。

3、代码实现

(1)多轮对话展示

通过以下代码,展示多轮对话实现。

import os
from typing import Any
​
from dotenv import load_dotenv
from openai import OpenAI
​
env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), ".env")
load_dotenv(env_path)
​
MODEL_API_KEY = os.getenv("MODEL_API_KEY")
MODEL_BASE_URL = os.getenv("MODEL_BASE_URL")
MODEL_NAME = os.getenv("MODEL_NAME")
client = OpenAI(api_key=MODEL_API_KEY, base_url=MODEL_BASE_URL)
​
​
def chat(messages: list[dict[str, Any]], max_tokens: int = 1024, temperature: float = 0.7) -> str:
    """messages 为 OpenAI 格式:[{"role": "system"|"user"|"assistant", "content": "..."}, ...]"""
    response = client.chat.completions.create(
        model=MODEL_NAME,
        messages=messages,
        stream=False,
        max_tokens=max_tokens,
        temperature=temperature,
    )
    return response.choices[0].message.content
​
​
def demo_system_and_user() -> str:
    """system 定规则 + user 提问题(最常用组合)。"""
    messages = [
        {
            "role": "system",
            "content": (
                "你是电商客服助手。回答不超过三句话,语气礼貌;"
                "若涉及赔偿或法律问题,请建议用户联系人工客服。"
            ),
        },
        {"role": "user", "content": "我的快递显示已签收但我没收到货,怎么办?"},
    ]
    return chat(messages)
​
​
def demo_multi_turn_with_assistant() -> str:
    """
    多轮:必须把上一轮的 assistant 内容放进 messages,再接新的 user。
    这里 assistant 内容模拟「上一轮模型已说过的话」。
    """
    messages = [
        {
            "role": "system",
            "content": "你是电商客服助手,回答简短。",
        },
        {"role": "user", "content": "你们支持 7 天无理由退货吗?"},
        {
            "role": "assistant",
            "content": "支持。签收次日起 7 天内,商品未使用且吊牌完好可申请无理由退货。",
        },
        {"role": "user", "content": "那运费谁承担?"},
    ]
    return chat(messages)
​
​
if __name__ == "__main__":
    print("=== 示例 1:system + user ===")
    print(demo_system_and_user())
    print()
    print("=== 示例 2:system + user + assistant + user(多轮追问)===")
    print(demo_multi_turn_with_assistant())

(2)多轮对话展示 few shot

通过以下代码,我们展示通过多轮对话的形式展示few shot实现。

import os
from typing import Any
​
from dotenv import load_dotenv
from openai import OpenAI
​
env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), ".env")
load_dotenv(env_path)
​
MODEL_API_KEY = os.getenv("MODEL_API_KEY")
MODEL_BASE_URL = os.getenv("MODEL_BASE_URL")
MODEL_NAME = os.getenv("MODEL_NAME")
client = OpenAI(api_key=MODEL_API_KEY, base_url=MODEL_BASE_URL)
​
​
def chat(messages: list[dict[str, Any]], max_tokens: int = 256, temperature: float = 0.3) -> str:
    response = client.chat.completions.create(
        model=MODEL_NAME,
        messages=messages,
        stream=False,
        max_tokens=max_tokens,
        temperature=temperature,
    )
    return response.choices[0].message.content
​
​
def few_shot_intent_via_messages(user_text: str) -> str:
    """
    用 user/assistant 交错给出示例,最后一条 user 为真实待分类句子。
    assistant 只输出意图标签(与 __003__ 同一套标签,便于对照)。
    """
    system = """你是电商客服意图识别助手。
用户会发来一句话,你只输出一个意图标签,不要解释。
标签只能是:查询物流、申请退款、咨询商品、其他。"""
​
    shot_pairs = [
        ("我的快递到哪了?", "查询物流"),
        ("这件衣服洗一次就起球了,我要退钱。", "申请退款"),
        ("这款耳机防水吗?", "咨询商品"),
        ("今天天气不错。", "其他"),
    ]
​
    messages: list[dict[str, Any]] = [{"role": "system", "content": system}]
    for u, a in shot_pairs:
        messages.append({"role": "user", "content": u})
        messages.append({"role": "assistant", "content": a})
    messages.append({"role": "user", "content": user_text})
​
    return chat(messages)
​
​
if __name__ == "__main__":
    sample = "上周买的鞋子码数偏小,能换大一码吗?"
    print("待分类:", sample)
    print("模型输出:", few_shot_intent_via_messages(sample))

(3)langchain代码显示多轮对话

以下代码显示了langchain的形式进行多轮对话。

import os
​
from dotenv import load_dotenv
from langchain_core.messages import AIMessage, HumanMessage, SystemMessage
from langchain_openai import ChatOpenAI
​
env_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), ".env")
load_dotenv(env_path)
​
MODEL_API_KEY = os.getenv("MODEL_API_KEY")
MODEL_BASE_URL = os.getenv("MODEL_BASE_URL")
MODEL_NAME = os.getenv("MODEL_NAME")
​
llm = ChatOpenAI(
    api_key=MODEL_API_KEY,
    base_url=MODEL_BASE_URL,
    model=MODEL_NAME,
    temperature=0.7,
    max_tokens=1024,
)
​
​
def demo_system_and_user() -> str:
    """system 定规则 + user 提问题。"""
    messages = [
        SystemMessage(
            content=(
                "你是电商客服助手。回答不超过三句话,语气礼貌;"
                "若涉及赔偿或法律问题,请建议用户联系人工客服。"
            )
        ),
        HumanMessage(content="我的快递显示已签收但我没收到货,怎么办?"),
    ]
    return llm.invoke(messages).content
​
​
def demo_multi_turn_with_assistant() -> str:
    """多轮:含上一轮 assistant(AIMessage),再接新的 user。"""
    messages = [
        SystemMessage(content="你是电商客服助手,回答简短。"),
        HumanMessage(content="你们支持 7 天无理由退货吗?"),
        AIMessage(
            content="支持。签收次日起 7 天内,商品未使用且吊牌完好可申请无理由退货。"
        ),
        HumanMessage(content="那运费谁承担?"),
    ]
    return llm.invoke(messages).content
​
​
if __name__ == "__main__":
    print("=== 示例 1:SystemMessage + HumanMessage ===")
    print(demo_system_and_user())
    print()
    print("=== 示例 2:System + Human + AIMessage + Human(多轮追问)===")
    print(demo_multi_turn_with_assistant())

总结:

1、提示词工程本质是“用输入控制输出” ​

2、一个好的 Prompt = 角色 + 任务 + 输入 + 输出 + 约束 ​

3、Few-shot 和 CoT 是提升效果的关键手段 ​

4、Prompt 需要不断调试和演化

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐