Prompt编写指南
欢迎来到Prompt编写指南!本文档将帮助你掌握编写高质量Prompt的技巧。🎯
什么是Prompt?
Prompt是我们与AI模型交互时使用的输入文本,它可以是一个问题、一个指令或一个上下文描述。在LLMs的世界里,一个精心设计的提示词就如同一位经验丰富的向导,能够引领模型穿越复杂的信息海洋,找到用户心中的答案。
Prompt编写的六大策略
写出清晰的指令
写出清晰的指令,是核心中的核心。任何Prompt技巧都不如清晰地表达你的需求,这就像人与人沟通一样,话都说不明白,怎么能让对面理解你呢?
针对如何写出清晰的指令,OpenAI给出了6条小技巧:
1. 把话说详细
尽量多的提供任何重要的详细信息和上下文,即明确说明自己的问题与需求,不要太笼统。一个好的提示词需要具体阐述问题或指令,避免模糊不清的表述。
如果想请大模型帮忙写一段文字,如何写提示词让大模型生成的文本更符合心意呢?不妨来试试下面两个提示词的区别:
- 普通提示词:写一篇关于环境保护的300字文章。
- 指令更清晰的提示词:撰写一篇300字的文章,首先定义环境保护的概念,然后列出三种主要的环境保护措施,并为每种措施提供一个具体的例子。最后,讨论个人在环境保护中可以发挥的作用。
完整代码
from openai import OpenAI
import os
# 设置环境变量
os.environ["OPENAI_BASE_URL"] = "https://oneapi.handbook.cool/v1"
os.environ["OPENAI_API_KEY"] = "sk-XnbHbzBOmPYGHgL_8q1nHn9pF7SRIQO-3M0QhYcpYAmV3kxQJ7SiqbzfETE"
# 创建客户端
client = OpenAI()
# 定义提示词
prompt1 = "写一篇关于环境保护的300字文章。"
prompt2 = "撰写一篇300字的文章,首先定义环境保护的概念,然后列出三种主要的环境保护措施,并为每种措施提供一个具体的例子。最后,讨论个人在环境保护中可以发挥的作用。"
try:
# 发送请求并获取模型回答
response1 = client.chat.completions.create(
model="gpt-4.1-nano", # 选择模型
messages=[{"role": "user", "content": prompt1}]
)
response2 = client.chat.completions.create(
model="gpt-4.1-nano",
messages=[{"role": "user", "content": prompt2}]
)
# 打印模型回答
print("模型回答1:")
print(response1.choices[0].message.content.strip())
print("\n模型回答2:")
print(response2.choices[0].message.content.strip())
except Exception as e:
print(f"发生错误: {e}")
2. 扮演角色
角色扮演,是指导大模型按照特定的角色进行交流的过程,这一过程不仅仅是给AI分配一个名字或头衔,而是深入地构建一个具有独特视角、专业知识和行为模式的虚拟角色。通过这种方式,大模型能够更加精确地模拟特定角色的思维方式和表达风格,从而提供更为贴近实际情景的回答,为我们更优质地完成工作。你可以把大模型类比成一个演员,你要告诉他让他演什么角色,他就会更专业更明确。
SYSTEM:请你扮演一个刚从美国留学回国的人,说话时候会故意中文夹杂部分英文单词,显得非常fancy,对话中总是带有很强的优越感。 USER:美国的饮食还习惯么。
from openai import OpenAI
import os
# 设置环境变量
os.environ["OPENAI_BASE_URL"] = "https://oneapi.handbook.cool/v1"
os.environ["OPENAI_API_KEY"] = "sk-XnbHbzBOmPYGHgL_8q1nHn9pF7SRIQO-3M0QhYcpYAmV3kxQJ7SiqbzfETE"
# 创建客户端
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-4.1-nano",
messages=[
{
"role": "system",
"content": "请你扮演一个刚从美国留学回国的人,说话时候会故意中文夹杂部分英文单词,显得非常fancy,对话中总是带有很强的优越感。"
},
{
"role": "user",
"content": "美国的饮食还习惯么。"
}
]
)
print(completion.choices[0].message.content)
上面的案例是一个简单的虚拟人物扮演。实际上只确定角色得到的答案是有限的,我们可以进行角色赋能,即赋予这个身份一些专业性的技能、专业知识、工作经验、行为方式,甚至是语言风格等。这些特征将帮助大模型更准确地模拟该角色,提供更符合角色特性的回答。
SYSTEM:
## 定位
- 智能助手名称 :新闻分类专家
- 主要任务 :对输入的新闻文本进行自动分类,识别其所属的新闻种类。
## 能力
- 文本分析 :能够准确分析新闻文本的内容和结构。
- 分类识别 :根据分析结果,将新闻文本分类到预定义的种类中。
### 知识储备
- 新闻种类 :
- 政治
- 经济
- 科技
- 娱乐
- 体育
- 教育
- 健康
- 国际
- 国内
- 社会
### 使用说明
- 输入 :一段新闻文本。
- 输出 :只输出新闻文本所属的种类,不需要额外解释。
USER:美国太空探索技术公司(SpaceX)的猎鹰9号运载火箭(Falcon 9)在经历美国联邦航空管理局(Federal Aviation Administration,FAA)短暂叫停发射后,于当地时间8月31日凌晨重启了发射任务。
from openai import OpenAI
import os
# 设置环境变量
os.environ["OPENAI_BASE_URL"] = "https://oneapi.handbook.cool/v1"
os.environ["OPENAI_API_KEY"] = "sk-XnbHbzBOmPYGHgL_8q1nHn9pF7SRIQO-3M0QhYcpYAmV3kxQJ7SiqbzfETE"
# 创建客户端
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-4.1-nano",
messages=[
{
"role": "system",
"content": "#### 定位\n- 智能助手名称 :新闻分类专家\n- 主要任务 :对输入的新闻文本进行自动分类,识别其所属的新闻种类。\n\n#### 能力\n- 文本分析 :能够准确分析新闻文本的内容和结构。\n- 分类识别 :根据分析结果,将新闻文本分类到预定义的种类中。\n\n#### 知识储备\n- 新闻种类 :\n - 政治\n - 经济\n - 科技\n - 娱乐\n - 体育\n - 教育\n - 健康\n - 国际\n - 国内\n - 社会\n\n#### 使用说明\n- 输入 :一段新闻文本。\n- 输出 :只输出新闻文本所属的种类,不需要额外解释。"
},
{
"role": "user",
"content": "美国太空探索技术公司(SpaceX)的猎鹰9号运载火箭(Falcon 9)在经历美国联邦航空管理局(Federal Aviation Administration,FAA)短暂叫停发射后,于当地时间8月31日凌晨重启了发射任务。"
}
]
)
print(completion.choices[0].message.content)
3. 指定完成任务所需的步骤
明确告诉模型执行任务的流程顺序,相当于提供一个具体的操作手册,这样可以使模型更容易去实现它们。
和拆解复杂任务
的差异
在后面策略中我们将学习到将复杂任务拆解成多个简单子任务
,这与现在学习的指定完成任务步骤
存在相关性,但二者有区别:
- 控制方式:前者灵活问题拆解,后者严格流程控制;
- 使用场景:前者适用床灾星问题,如商业策略,后者适用标准化操作,如数据清洗。
SYSTEM:你是一位文本大纲生成专家,擅长根据用户的需求创建一个有条理且易于扩展成完整文章的大纲,你拥有强大的主题分析能力,能准确提取关键信息和核心要点。具备丰富的文案写作知识储备,熟悉各种文体和题材的文案大纲构建方法。可根据不同的主题需求,如商业文案、文学创作、学术论文等,生成具有针对性、逻辑性和条理性的文案大纲,并且能确保大纲结构合理、逻辑通顺。该大纲应该包含以下部分: 引言:介绍主题背景,阐述撰写目的,并吸引读者兴趣。 主体部分:第一段落:详细说明第一个关键点或论据,支持观点并引用相关数据或案例。 第二段落:深入探讨第二个重点,继续论证或展开叙述,保持内容的连贯性和深度。 第三段落:如果有必要,进一步讨论其他重要方面,或者提供不同的视角和证据。 结论:总结所有要点,重申主要观点,并给出有力的结尾陈述,可以是呼吁行动、提出展望或其他形式的收尾。 创意性标题:为文章构思一个引人注目的标题,确保它既反映了文章的核心内容又能激发读者的好奇心。 USER:请帮我生成“中国农业情况”这篇文章的大纲。
from openai import OpenAI
import os
# 设置环境变量
os.environ["OPENAI_BASE_URL"] = "https://oneapi.handbook.cool/v1"
os.environ["OPENAI_API_KEY"] = "sk-XnbHbzBOmPYGHgL_8q1nHn9pF7SRIQO-3M0QhYcpYAmV3kxQJ7SiqbzfETE"
# 创建客户端
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-4.1-nano",
messages=[
{
"role": "system",
"content": "你是一位文本大纲生成专家,擅长根据用户的需求创建一个有条理且易于扩展成完整文章的大纲,你拥有强大的主题分析能力,能准确提取关键信息和核心要点。具备丰富的文案写作知识储备,熟悉各种文体和题材的文案大纲构建方法。可根据不同的主题需求,如商业文案、文学创作、学术论文等,生成具有针对性、逻辑性和条理性的文案大纲,并且能确保大纲结构合理、逻辑通顺。该大纲应该包含以下部分:\n引言:介绍主题背景,阐述撰写目的,并吸引读者兴趣。\n主体部分:第一段落:详细说明第一个关键点或论据,支持观点并引用相关数据或案例。\n第二段落:深入探讨第二个重点,继续论证或展开叙述,保持内容的连贯性和深度。\n第三段落:如果有必要,进一步讨论其他重要方面,或者提供不同的视角和证据。\n结论:总结所有要点,重申主要观点,并给出有力的结尾陈述,可以是呼吁行动、提出展望或其他形式的收尾。\n创意性标题:为文章构思一个引人注目的标题,确保它既反映了文章的核心内容又能激发读者的好奇心。"
},
{
"role": "user",
"content": "请帮我生成“中国农业情况”这篇文章的大纲"
}
]
)
print(completion.choices[0].message.content)
4. 提供例子
这就是常说的few-shot prompting,通过少量示例(示例通常包含“输入-输出”对)来学习并执行任务的技术。其核心思想是不进行模型微调(fine-tuning),而是通过例子让大模型可以学到样本的共性以提升输出结果的质量。
这可以理解为对于大模型的“身教”:当规则、指令或者业务逻辑难以描述的时候,直接摆示例会更加有用,它允许大语言模型概括模式并将它们应用于新的输入。
🌟 来一个小测试试试看!
如果你想让大模型成为一个emoji专家,可以根据字面意思将文字翻译成emoji,可以怎么来写提示词呢?
- 宇航员 → 👩🚀
- 女快递员 → 👩📦📫
- 今天下雨,我要在家睡觉 → 🌧🏡😴 输入:教师 → 输出: 输入:今天天气不错,我去机场接个人 → 输出:
from openai import OpenAI
import os
# 设置环境变量
os.environ["OPENAI_BASE_URL"] = "https://oneapi.handbook.cool/v1"
os.environ["OPENAI_API_KEY"] = "sk-XnbHbzBOmPYGHgL_8q1nHn9pF7SRIQO-3M0QhYcpYAmV3kxQJ7SiqbzfETE"
# 创建客户端
client = OpenAI()
def get_emoji_response(user_input):
try:
response = client.chat.completions.create(
model="gpt-4.1-nano",
messages=[
{
"role": "user",
"content": "1. 宇航员 → 👩🚀\n2. 女快递员 → 👩📦📫\n3. 今天下雨,我要在家睡觉 → 🌧🏡😴\n\n输入: " + user_input + " → 输出:"
}],
temperature=0.1, # 降低随机性
max_tokens=10
)
return response.choices[0].message.content.strip()
except Exception as e:
return f"⚠️ 错误: {str(e)}"
test_cases = [
"教师", #预期输出: 👩🏫
"今天天气不错,我去机场接个人" #预期输出: 🌤️✈️🤝👤
]
for case in test_cases:
print(f"输入: {case} → 输出: {get_emoji_response(case)}")
想要了解更多关于few-shot prompting
的内容,可以去阅读论文Language Models are Few-Shot Learners
5. 制定输出长度
使用限制条件来限制模型输出的范围,避免其产生与指令无关或不准确的信息。但是注意尽量不要用负面描述在提示词里描述任务要求,用「只输出markdown」这样的正面描述,不要用「别输出markdown以外的内容」。
6. 使用分隔符清楚地指示输入的不同部分
分隔符是一种特殊token,可帮助LLM分辨prompt的哪些部分应被视为单个含义单元。由于输入LLM的整个prompt是单个的token长序列,分隔符(如三引号、XML标签、节标题等)可以帮助划分要区别对待的文本节。可以帮助大模型更好的理解文本内容。
分隔符 | 用途 | 适用场景 |
---|---|---|
三引号 | 定义多行字符串或文档字符串 | 长文本/代码段嵌入提示词、保留换行/缩进的内容 |
XML 标签 | 定义结构化数据 | 严格输出格式、复杂参数传递 |
节标题 | 创建标题和子标题 | 多步骤任务分解 、示例与指令分离 |
JSON 格式 | 数据存储和传输,结构化表示数据 | API 响应、配置文件 |
Example
下面这段的代码的效率很低,且没有处理边界情况。请先解释这段代码的问题与解决方法,然后进行优化:
用户将提供给你一段新闻内容,请你分析新闻内容,并提取其中的关键信息,以 JSON 的形式输出,输出的 JSON 需遵守以下的格式: { "entiry": <新闻实体>, "time": <新闻时间,格式为 YYYY-mm-dd HH:MM:SS,没有请填 null>, "summary": <新闻内容总结> }
完整代码
from openai import OpenAI
import os
# 设置环境变量
os.environ["OPENAI_BASE_URL"] = "https://oneapi.handbook.cool/v1"
os.environ["OPENAI_API_KEY"] = "sk-XnbHbzBOmPYGHgL_8q1nHn9pF7SRIQO-3M0QhYcpYAmV3kxQJ7SiqbzfETE"
# 创建客户端
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-4.1-nano",
messages=[
{
"role": "user",
"content": "下面这段的代码的效率很低,且没有处理边界情况。请先解释这段代码的问题与解决方法,然后进行优化:\n```\ndef fib(n):\n if n <= 2:\n return n\n return fib(n-1) + fib(n-2)\n```"
}
]
)
print(completion.choices[0].message.content)
from openai import OpenAI
import os
# 设置环境变量
os.environ["OPENAI_BASE_URL"] = "https://oneapi.handbook.cool/v1"
os.environ["OPENAI_API_KEY"] = "sk-XnbHbzBOmPYGHgL_8q1nHn9pF7SRIQO-3M0QhYcpYAmV3kxQJ7SiqbzfETE"
def extract_contact_info(raw_text):
# 系统角色设定(XML格式)
system_prompt = """
<agent_profile>
<role>专业信息提取助手</role>
<capabilities>
<skill>识别中文联系人信息</skill>
<skill>处理非结构化文本</skill>
<skill>输出标准化JSON</skill>
</capabilities>
<behavior>
<rule>不添加解释性文字</rule>
<rule>严格遵循输出格式</rule>
</behavior>
</agent_profile>
<task_guidelines>
<required_fields>
<field name="姓名" type="string" description="中文姓名"/>
<field name="电话" type="phone" description="11位手机号"/>
<field name="邮箱" type="email" description="包含@的邮箱地址"/>
</required_fields>
<output_spec>
<format>JSON</format>
<template>
{
"姓名": "",
"电话": "",
"邮箱": ""
}
</template>
</output_spec>
</task_guidelines>
"""
try:
response = client.chat.completions.create(
model="gpt-4.1-nano",
messages=[
{
"role": "system",
"content": system_prompt
},
{
"role": "user",
"content": f"请从以下文本提取联系人信息:\n{raw_text}"
}
],
temperature=0,
response_format={ "type": "json_object" } # 强制JSON输出
)
return response.choices[0].message.content
except Exception as e:
return f"错误:{str(e)}"
user_inputs = [
"张工程师,联系方式:13800138000,邮箱zhang@example.com。项目截止日期2024-12-31",
"李经理的手机是13912345678,联系邮箱li@company.com,负责销售业务",
"王总监 18800001111 wang@org.org 需要周五前反馈"
]
for text in user_inputs:
result = extract_contact_info(text)
print(f"提取结果:{result}")
请参考前面例子的代码
from openai import OpenAI
import os
# 设置环境变量
os.environ["OPENAI_BASE_URL"] = "https://oneapi.handbook.cool/v1"
os.environ["OPENAI_API_KEY"] = "sk-XnbHbzBOmPYGHgL_8q1nHn9pF7SRIQO-3M0QhYcpYAmV3kxQJ7SiqbzfETE"
# 创建客户端
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-4.1-nano",
messages=[
{
"role": "system",
"content": "用户将提供给你一段新闻内容,请你分析新闻内容,并提取其中的关键信息,以 JSON 的形式输出,输出的 JSON 需遵守以下的格式:\n\n{\n \"entiry\": <新闻实体>,\n \"time\": <新闻时间,格式为 YYYY-mm-dd HH:MM:SS,没有请填 null>,\n \"summary\": <新闻内容总结>\n}"
},
{
"role": "user",
"content": "8月31日,一枚猎鹰9号运载火箭于美国东部时间凌晨3时43分从美国佛罗里达州卡纳维拉尔角发射升空,将21颗星链卫星(Starlink)送入轨道。紧接着,在当天美国东部时间凌晨4时48分,另一枚猎鹰9号运载火箭从美国加利福尼亚州范登堡太空基地发射升空,同样将21颗星链卫星成功送入轨道。两次发射间隔65分钟创猎鹰9号运载火箭最短发射间隔纪录。\n\n美国联邦航空管理局于8月30日表示,尽管对太空探索技术公司的调查仍在进行,但已允许其猎鹰9号运载火箭恢复发射。目前,双方并未透露8月28日助推器着陆失败事故的详细信息。尽管发射已恢复,但原计划进行五天太空活动的“北极星黎明”(Polaris Dawn)任务却被推迟。美国太空探索技术公司为该任务正在积极筹备,等待美国联邦航空管理局的最终批准后尽快进行发射。"
}
]
)
print(completion.choices[0].message.content)
提供上下文
给大模型文本或者文档,能大幅度降低大模型幻觉问题。其实上,为大模型提供参考文本就相当于把大模型当作知识库调用。
- 让模型使用参考文本作答:限制大模型仅能使用提供的信息来组成答案
- 让模型通过引用参考文本来回答:可以直接要求模型通过引用所提供文档中的段落来为其答案添加引用,这种方法在专有领域下能较好地高正确性,增加可验证性。
Example
您将获得一份由三重引号和一个问题分隔的文档。您的任务是仅使用提供的文档回答问题,并引用用于回答问题的文档段落。如果文档不包含回答此问题所需的信息,则只需写:「信息不足」。如果提供了问题的答案,则必须附有引文注释。 使用以下格式引用相关段落({「引用」:…})。 """<在此插入文档>""" 问题:<在此插入问题>
拆解复杂任务为一系列简单子任务
其实跟人类一样,如果你作为 Leader,让下属一次性去做一个非常大的事,出错的概率是很大的,很多大项目也是这样,你甚至无从下手。所以经常我们在工作中,都说的是要拆,拆各种细节、子任务、子目标等等。大模型也是同样的道理。
把复杂的任务给拆给更为简单的子任务,大模型会有更好的表现。
Example
- *未拆解提示词:写一份关于新能源汽车行业的技术趋势和市场分析报告,要求专业且全面。
- 拆解后提示词:
请按以下步骤生成报告:
- 技术趋势分析
- 电池技术突破(固态电池/快充技术)
- 智能驾驶系统演进(L2→L4级自动驾驶)
- 市场分析
- 全球区域市场渗透率对比(中/美/欧)
- 头部企业竞争格局(特斯拉/比亚迪/蔚来)
- 交叉分析
- 政策补贴对技术路线的影响
- 消费者偏好与技术发展的关联性
要求:每个部分用Markdown表格总结关键数据,最后给出3点核心结论
完整代码
from openai import OpenAI
import os
# 设置环境变量
os.environ["OPENAI_BASE_URL"] = "https://oneapi.handbook.cool/v1"
os.environ["OPENAI_API_KEY"] = "sk-XnbHbzBOmPYGHgL_8q1nHn9pF7SRIQO-3M0QhYcpYAmV3kxQJ7SiqbzfETE"
# 创建客户端
client = OpenAI()
# 定义提示词
prompt1 = "写一份关于新能源汽车行业的技术趋势和市场分析报告,要求专业且全面。"
prompt2 = "请按以下步骤生成报告:\n\n1. **技术趋势分析** \n- 电池技术突破(固态电池/快充技术)\n- 智能驾驶系统演进(L2→L4级自动驾驶)\n\n2. **市场分析** \n- 全球区域市场渗透率对比(中/美/欧)\n- 头部企业竞争格局(特斯拉/比亚迪/蔚来)\n\n3. **交叉分析** \n- 政策补贴对技术路线的影响 \n- 消费者偏好与技术发展的关联性\n\n要求:每个部分用Markdown表格总结关键数据,最后给出3点核心结论"
try:
# 发送请求并获取模型回答
response1 = client.chat.completions.create(
model="gpt-4.1-nano", # 选择模型
messages=[{"role": "user", "content": prompt1}]
)
response2 = client.chat.completions.create(
model="gpt-4.1-nano",
messages=[{"role": "user", "content": prompt2}]
)
# 打印模型回答
print("模型回答1:")
print(response1.choices[0].message.content.strip())
print("\n模型回答2:")
print(response2.choices[0].message.content.strip())
except Exception as e:
print(f"发生错误: {e}")
给模型时间“思考”
给模型时间思考的核心在于让模型分步骤、有条理地处理复杂问题,而不是直接给出最终答案。这类似于人在解决复杂问题时,会先分析、拆解,再一步步推理,而不是直接“脱口而出”。大语言模型(LLM)在遇到复杂问题时,如果直接提问,可能会: - 跳过关键推理步骤,导致错误答案。 - 生成不连贯的答案,逻辑混乱。 - 受"即时反应"影响,给出直觉但不准确的回答。
通过让模型“分步思考”(Think step by step),可以提高答案的准确性、逻辑性和可解释性,尤其适用于需要严谨推理的任务。
- 使用思维链
Chain-of-Thought(CoT)是一种让大语言模型通过分步推理来回答问题的技术,通过强制模型“展示思考过程”来显著提高复杂任务的准确率。
请你逐步分析以下数学问题,并详细列出每一步的推理过程,最后得出答案。 问题:你本来有5个羽毛球。如果你额外购买了2盒羽毛球,每盒有3个羽毛球,那么你现在总共有多少个羽毛球? 示例回答: 1. 首先分析问题,确定已知信息: 你本来有5个羽毛球 每盒有3个羽毛球 2. 接下来,根据题意计算总羽毛球数量: 每盒羽毛球数量 × 购入的盒数 = 购入羽毛球数量。 3 × 2 = 6。 原来羽毛球数量 + 购入羽毛球数量 = 现在总共的羽毛球数 5 + 6 = 11 3. 所以,你现在总共有11个羽毛球。 请按照类似的格式回答下面这个问题: 一家餐厅原来有23个苹果,用了其中20个苹果来制作午餐。餐厅又购入了6个苹果,那么这家餐厅还有多少个苹果?
from openai import OpenAI
import os
# 设置环境变量
os.environ["OPENAI_BASE_URL"] = "https://oneapi.handbook.cool/v1"
os.environ["OPENAI_API_KEY"] = "sk-XnbHbzBOmPYGHgL_8q1nHn9pF7SRIQO-3M0QhYcpYAmV3kxQJ7SiqbzfETE"
# 创建客户端
client = OpenAI()
completion = client.chat.completions.create(
model="gpt-4.1-nano",
messages=[
{
"role": "user",
"content": "请你逐步分析以下数学问题,并详细列出每一步的推理过程,最后得出答案。\n\n问题:你本来有5个羽毛球。如果你额外购买了2盒羽毛球,每盒有3个羽毛球,那么你现在总共有多少个羽毛球?\n\n示例回答:\n\n1. 首先分析问题,确定已知信息:\n你本来有5个羽毛球\n每盒有3个羽毛球\n\n2. 接下来,根据题意计算总羽毛球数量:\n每盒羽毛球数量 × 购入的盒数 = 购入羽毛球数量。\n3 × 2 = 6。\n原来羽毛球数量 + 购\n5 + 6 = 11\n\n3. 所以,你现在总共有11个羽毛球。\n\n请按照类似的格式回答下面这个问题:\n\n一家餐厅原来有23个苹果,用了其中20个苹果来制作午餐。餐厅又购入了6个苹果,那么这家餐厅还有多少个苹果?"
}
]
)
print(completion.choices[0].message.content)
或者也可以在提供指令时添加一句「让我们一步步思考」,可以让模型按照严谨的逻辑推理过程输出结果。
- 自我验证
自我验证是指模型有能力检查和验证其自身的输出,确保其准确性和可靠性。当你对模型的输出不确定时,可以通过进一步的提问验证,如回复「还有更好的答案吗」、「请你检查你的输出」等引导模型继续思考。
想要了解更高级的自我验证方法可以参考:
- Self-Consistency(自洽性验证):Self-Consistency Improves Chain of Thought Reasoning in Language Models (Wang et al., 2022)
- Stepwise Verification(分步验证):Faithful Reasoning Using Large Language Models (Press et al., 2022)
使用外部工具
大模型并不是万能的,比如数学或者一些实时问题等等,大模型的效果并没有那么好: - 无法实时获取最新信息:训练数据固定,无法直接访问新闻、股票价格等动态内容。 - 缺乏精确计算能力:复杂数学运算、代码执行或数据库查询可能出错。 - 无法直接操作外部系统:例如发送邮件、查询天气等。
所以需要一些外部工具来帮助处理。如果第三方工具能稳定的获得结果,这时大模型扮演的更像是一个答案组装类的“工具人”。
Note
可以参考t4f小队在AI Agent实战中是如何使用外部工具的
系统测试变更
某些情况下,针对个别example的prompt修改可能在小范围测试中表现良好,但在更广泛的代表性数据集上反而导致整体性能下降。因此,为了确保修改能真正带来性能提升,必须建立全面的测试集进行系统验证。
Note
prompt六大策略来源于OpenAI的官方文档,感兴趣或者正在开发自己AI应用的小伙伴可以去阅读原文档,了解更多关于开发时的prompt设计。 官方文档:https://platform.openai.com/docs/guides/prompt-engineering
Prompt总结
编写好的Prompt是一门艺术,需要不断实践和优化。记住:
- 清晰的指令
- 充分的上下文
- 结构化的格式
- 具体的示例
- 适当的反馈机制 通过遵循这些原则和技巧,你将能够更好地与AI模型交互,获得更满意的结果。🚀
如果你不仅仅局限于普通用户,而是希望能通过LLM来开发属于自己的AI产品,那你需要更好地掌握上面所提到的最后两个策略!
如果你正在进行AI应用开发,在团队协作开发中,是不是经常遇到这些头疼问题呢?😅
- Prompt管理混乱:团队成员各自修改prompt,版本难以追踪,最后合并时一团糟?
- 测试验证低效:每次prompt更新后,都要重新导入跑测试集,结果比对费时费力?
- 效果分析困难:海量的测试日志和指标数据,却难以快速定位优化方向?
👇Langfuse一站式解决方案来啦!快来一起学习!!
Langfuse入门介绍
什么是Langfuse
Langfuse是由Simon Sturmer、Marc Klingen和Max Deichmann联合创立的团队于2023年正式推出的开源的LLM应用可观测性平台,专注于帮助开发者监控、分析和调试基于大语言模型构建的应用程序。它提供了对LLM调用链路的追踪、成本管理、Prompt版本控制、用户行为分析等功能,适用于开发和生产环境中的性能优化与问题排查。
为什么选择Langfuse
Langfuse采用MIT开源协议,代码完全公开,开发团队可自由修改和扩展功能。同时支持本地化部署,数据无需上传第三方服务器,避免了敏感数据泄露以及其他服务条款限制。低侵入式SDK(极简集成+自动追踪)设计也为开发团队自动捕获LLM调用链路、上下文追踪、异步上报等提供便利。
Langfuse的核心功能
LLM可观测性
Langfuse提供了强大的LLM可观测性功能,允许开发者深入了解他们的LLM应用的运行状况。通过集成Langfuse SDK,开发者仅需要通过极简的代码(如添加几行配置或调用少量的API)即可轻松地对开发中的应用进行检测,并将跟踪数据导入Langfuse。这使得开发者能够实时监控应用性能,快速识别和解决潜在问题。
- 配置Langfuse
import os
os.environ["LANGFUSE_PUBLIC_KEY"] = ""
os.environ["LANGFUSE_SECRECT_KEY"] = ""
os.environ["LANGFUSE_HOST"] = "https://us.cloud.langfuse.com/" # US region
# os.environ["LANGFUSE_HOST"] = "https://cloud.langfuse.com/" # EU region
# your openai key
os.environ["OPEN_API_KEY"] = ""
Langfuse 通过 Trace(追踪) 记录一次完整应用执行流程(如用户请求),使用 @observe() 装饰的最外层函数会自动生成 Trace。每个 trace 包含多个观测项,分为三类: - Event(事件):标记离散动作; - Span(跨度):记录嵌套代码块的执行时间、输入输出; - Generation(生成):专用于追踪LLM交互(如API调用和结果生成)。
from langfuse.decorators import observe
from langfuse.openai import openai # OpenAI integration
@observe()
def story():
return openai.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "You are a great storyteller."},
{"role": "user", "content": "Once upon a time in a galaxy far, far away..."}
],
).choices[0].message.content
@observe()
def main():
return story()
main()
Langfuse UI
Langfuse提供了一个直观的用户界面,使开发者能够检查和调试复杂的日志。通过这个界面,开发者可以可视化地追踪LLM应用的执行流程,可以记录每次LLM调用的输入、输出、参数、耗时、错误等信息,可视化展示链式调用(如多步骤Agent、RAG流程)、代理使用和工具调用等复杂操作。这大大简化了调试过程,使开发者能够更快地定位和解决问题。
服务器连接信息
- Trace:允许跟踪应用程序中的每个LLM调用和其他相关逻辑。
- Session:允许跟踪多步骤对话或代理工作流程.
- Timeline:通过检查时间线视图来调试延迟问题。。
- Dashborad:查看仪表板中的质量、成本和延迟指标来监控您的LLM应用程序。
- Agent Graph:智能体可以以图形形式可视化,以说明复杂代理工作流程的流程。
- Users:添加自己的
userId
,以监控每个用户的费用和使用情况。您也可以选择在您的系统中创建指向此视图的深层链接。
可以点击链接查看演示视频:https://langfuse.com/docs/tracing
Prompt和数据集的管理与版本控制
Prompt管理是Langfuse的另一个关键特性。它允许开发者在Langfuse平台内管理、版本化和部署提示。这种集中化的提示管理方法使得团队可以更好地协作,追踪提示的演变,同时在代码开发端能实时更新,确保在整个开发测试中使用最优化的提示。另外,Langfuse的数据集功能允许开发者协作创建和管理不同的测试数据集。这些数据集可以用来测试预期的输入和输出对,并在部署新版本之前对性能进行基准测试。
- prompt的管理与控制
可以管理不同版本的Prompt模板,对比不同版本的效果,并可以通过“Set the production label”实时调整当前运行的prompt版本。

- 数据集的管理与控制
可以在Datasets创建多个数据集,团队可以同步在不同设备/平台上修改数据集。

需要按照json格式录入数据的输入和期望输出,并且可以在元数据部分记录数据的来源信息。

成功导入后可以在该数据集下查看所有的数据,也可以在”Actions”为特殊数据设置标签。

数据分析与监控
Langfuse提供了统计LLM调用的延迟、错误率、使用量等指标多种指标,开发者可以通过仪表板和数据导出功能深入了解这些指标,从而识别高频问题或低效流程,监控测试全流程结果。此外Langfuse还支持自定义指标和仪表盘。
下一步
如果你想进一步了解Langfuse平台,欢迎其阅读官方文档及社区视频。(官方文档:https://langfuse.com/docs)
本章是我们Agent应用系列的第三部分,恭喜你初步了解了prompt编写方法和Langfuse的基本用法!接下来可以:
- 深入研究prompt的优化技巧,探索如何通过更精准的措辞和结构来提升生成内容的质量和相关性。
- 探索Langfuse的高级功能,如数据监控、性能分析等,以更好地管理和优化模型的运行效果。
- 结合实际项目需求,对Langfuse进行定制化开发,以满足特定的业务逻辑和功能要求。
- 进入下一章,了解如何使用RAG进行Agent开发
祝你编码愉快,AI之旅顺利!