
最大化语言模型输出:使用元提示技术优化提示的 5 个步骤
在这篇文章中,我将带您了解如何优化基本提示以提高来自语言模型的输出质量。
我将使用一个改编的示例,总结新闻文章,以演示其工作原理,来自OpenAI 食谱。
什么是元提示?
元提示是一种技术,其中一个语言模型(LLM)用于生成或优化另一个语言模型的提示。
通常,使用一个 更 先进的模型 (o1-preview) 来优化一个 不太复杂 的模型 (GPT-4o) 的提示。
目标是创建更清晰、更有结构的提示,更好地引导目标模型生成高质量、相关的响应。
通过利用像 o1-preview 这样的模型的高级 推理 能力,我们可以系统地增强提示,以确保它们在引导所需输出方面更有效。
为什么使用元提示?
这种技术简化了与大语言模型一起工作的开发过程,使得实现更好的结果变得更加容易。
它特别适用于摘要、问答或任何需要精确度的场景。
它是如何工作的
我将从一个简单提示开始,旨在总结新闻文章。
然后,使用 o1-preview,我将逐步分析和完善它,增加 清晰度 和 细节 以提高其有效性。
最后,系统地评估输出,以衡量我们更改的影响。
下面的代码执行必要的安装和导入。它也会提示您输入您的 OpenAI API 密钥。
!pip install datasets openai pandas tqdm
import pandas as pd
import getpass
import matplotlib.pyplot as plt
from concurrent.futures import ThreadPoolExecutor, as_completed
from tqdm import tqdm
from pydantic import BaseModel
from datasets import load_dataset
api_key = getpass.getpass("输入您的 OpenAI API 密钥: ")
client = openai.OpenAI(api_key=api_key)
ds = load_dataset("RealTimeData/bbc_news_alltime", "2024-08")
df = pd.DataFrame(ds['train']).sample(n=100, random_state=1)
df.head()
以下是加载到应用程序中的数据的顶部部分。
首先,我们将使用下面定义的简单提示来提示 o1-preview
。
为了改善简单提示,需要为 o1-preview
模型提供指导和背景,以实现期望的结果。
simple_prompt = "总结这篇新闻文章: {article}"
meta_prompt = """
改进以下提示以生成更详细的摘要。
遵循提示工程最佳实践。
确保结构清晰且直观,并包含新闻类型、标签和情感分析。
{simple_prompt}
仅返回提示。
"""
def get_model_response(messages, model="o1-preview"):
response = client.chat.completions.create(
messages=messages,
model=model,
)
return response.choices[0].message.content
complex_prompt = get_model_response([{"role": "user", "content": meta_prompt.format(simple_prompt=simple_prompt)}])
complex_prompt
这是我们高级或更优模型生成的增强 提示:
请阅读以下新闻文章,并提供包含以下内容的详细摘要:
- **新闻类型**:对文章进行分类(例如,政治、科技、体育、商业等)。
- **标签**:列出与文章相关的关键词或短语。
- **情感分析**:分析整体基调(例如,积极、消极、中立)并提供简要解释。
确保摘要结构良好且易于理解。
**文章**:
{article}
好的,现在我们有了简单提示和增强提示。因此,我们可以在您的数据集上使用简单和增强提示并比较结果。
我们现在正在对我们较差的模型运行提示。
def generate_response(prompt):
messages = [{"role": "user", "content": prompt}]
response = get_model_response(messages, model="gpt-4o-mini")
return response
def generate_summaries(row):
simple_itinerary = generate_response(simple_prompt.format(article=row["content"]))
complex_itinerary = generate_response(complex_prompt + row["content"])
return simple_itinerary, complex_itinerary
generate_summaries(df.iloc[0])
比较简单提示和增强提示的摘要显示出显著的改善。
虽然初始摘要提供了一个广泛的概述,但增强版本进一步提供了详细的分解,分类新闻类型,列出相关标签,甚至分析情感。
现在测试整个数据集……
df['simple_summary'] = None
df['complex_summary'] = None
with ThreadPoolExecutor() as executor:
futures = {executor.submit(generate_summaries, row): index for index, row in df.iterrows()}
for future in tqdm(as_completed(futures), total=len(futures), desc="生成行程"):
index = futures[future]
simple_itinerary, complex_itinerary = future.result()
df.at[index, 'simple_summary'] = simple_itinerary
df.at[index, 'complex_summary'] = complex_itinerary
df.head()
结果是……
评估结果
为了比较两个提示的性能,采用结构化的方法,让语言模型本身作为评判者。
这意味着大语言模型将根据准确性、清晰度和相关性等特定标准评估输出,提供一个没有人类偏见的客观评估。有关更多详细信息,请查看OpenAI 食谱。
evaluation_prompt = """
You are an expert editor tasked with evaluating the quality of a news article summary. Below is the original article and the summary to be evaluated:
**Original Article**:
{original_article}
**Summary**:
{summary}
Please evaluate the summary based on the following criteria, using a scale of 1 to 5 (1 being the lowest and 5 being the highest). Be critical in your evaluation and only give high scores for exceptional summaries:
1. **Categorization and Context**: Does the summary clearly identify the type or category of news (e.g., Politics, Technology, Sports) and provide appropriate context?
2. **Keyword and Tag Extraction**: Does the summary include relevant keywords or tags that accurately capture the main topics and themes of the article?
3. **Sentiment Analysis**: Does the summary accurately identify the overall sentiment of the article and provide a clear, well-supported explanation for this sentiment?
4. **Clarity and Structure**: Is the summary clear, well-organized, and structured in a way that makes it easy to understand the main points?
5. **Detail and Completeness**: Does the summary provide a detailed account that includes all necessary components (type of news, tags, sentiment) comprehensively?
Provide your scores and justifications for each criterion, ensuring a rigorous and detailed evaluation.
"""
class ScoreCard(BaseModel):
justification: str
categorization: int
keyword_extraction: int
sentiment_analysis: int
clarity_structure: int
detail_completeness: int
评估在数据框中运行并存储。
def evaluate_summaries(row):
simple_messages = [{"role": "user", "content": evaluation_prompt.format(original_article=row["content"], summary=row['simple_summary'])}]
complex_messages = [{"role": "user", "content": evaluation_prompt.format(original_article=row["content"], summary=row['complex_summary'])}]
simple_summary = client.beta.chat.completions.parse(
model="gpt-4o",
messages=simple_messages,
response_format=ScoreCard)
simple_summary = simple_summary.choices[0].message.parsed
complex_summary = client.beta.chat.completions.parse(
model="gpt-4o",
messages=complex_messages,
response_format=ScoreCard)
complex_summary = complex_summary.choices[0].message.parsed
return simple_summary, complex_summary
df['simple_evaluation'] = None
df['complex_evaluation'] = None
with ThreadPoolExecutor() as executor:
futures = {executor.submit(evaluate_summaries, row): index for index, row in df.iterrows()}
for future in tqdm(as_completed(futures), total=len(futures), desc="Evaluating Summaries"):
index = futures[future]
simple_evaluation, complex_evaluation = future.result()
df.at[index, 'simple_evaluation'] = simple_evaluation
df.at[index, 'complex_evaluation'] = complex_evaluation
df.head()
结果如下…
结果已绘制成图…
import matplotlib.pyplot as plt
df["simple_scores"] = df["simple_evaluation"].apply(lambda x: [score for key, score in x.model_dump().items() if key != 'justification'])
df["complex_scores"] = df["complex_evaluation"].apply(lambda x: [score for key, score in x.model_dump().items() if key != 'justification'])
criteria = [
'Categorisation',
'Keywords and Tags',
'Sentiment Analysis',
'Clarity and Structure',
'Detail and Completeness'
]
simple_avg_scores = df['simple_scores'].apply(pd.Series).mean()
complex_avg_scores = df['complex_scores'].apply(pd.Series).mean()
avg_scores_df = pd.DataFrame({
'Criteria': criteria,
'Original Prompt': simple_avg_scores,
'Improved Prompt': complex_avg_scores
})
ax = avg_scores_df.plot(x='Criteria', kind='bar', figsize=(6, 4))
plt.ylabel('平均分')
plt.title('简单提示与复杂提示模型性能比较')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
plt.show()
结果如下…
https://platform.openai.com/docs/api-reference/chat/create#chat-create-reasoning_effort