《AI Agent智能体开发实践》1~6章试读_《ai agent 智能体开发实践》在线阅读-CSDN博客
AI Agent智能体开发实践【行情 报价 价格 评测】-京东
AI智能体提示设计(Prompt Design)是指通过构造精准、有效的输入文本(提示),引导AI智能体(如大语言模型、任务型智能体等)更高效、准确地完成目标任务的过程。其核心是通过“语言指令”搭建人类需求与AI能力之间的桥梁,直接影响智能体的响应质量。
4.3.1 零样本提示
零样本提示(Zero-shot Prompting)是一种在自然语言处理领域中使用的技术,它允许模型在没有特定任务训练数据的情况下,通过设计合适的提示来生成相应的输出。
1. 定义
零样本提示是指在没有任何示例的情况下,直接输入提示语让模型生成相应的输出。这种方法依赖于模型在预训练阶段学习到的广泛知识来处理新的任务和问题。它不需要对模型进行专门的训练或微调,因此可以快速、灵活地应用于多种任务。
2. 原理
零样本提示的工作原理基于大型语言模型(如GPT系列)的预训练和提示设计。这些模型在庞大的数据集上接受训练,以理解语言模式和上下文。在零样本提示中,模型使用它在此之前所接收的所有训练和知识来处理一个它尚未明确准备的任务。它不会获得任何特定例子或指导来完成这个新任务,而是应用其一般理解和技能来尝试给出正确答案或解决方案。
有效的提示词设计对于成功的零样本提示至关重要。提示应提供明确、清晰的指示,以传达所需的任务给模型。这包括使用精确的语言、避免模糊或开放式的指令,以及以自然和对话的方式构造提示语。
3. 应用场景
零样本提示在许多领域都有广泛的应用场景,包括:
- 文本生成:通过提供任务描述和输入文本,模型可以生成与任务相关的文本输出,如文章、段落或句子。
- 文本分类:模型可以根据提示对输入文本进行情感倾向、主题分类等判断。
- 机器翻译:通过输入源语言文本和目标语言提示,模型可以生成相应的翻译文本。
- 问答系统:模型可以根据问题提示和上下文信息生成答案。
- 医疗领域:在医疗诊断中,模型可以根据患者的症状描述生成可能的疾病诊断。
- 法律领域:在法律文档中,模型可以生成文档的摘要或关键信息提取。
- 客户服务:在自动化问答系统中,模型可以根据客户的问题生成相应的回复。
【示例4.1】仅用零样本提示方式调用Qwen2大模型完成常见任务。使用的模型为qwen/Qwen2-0.5B-Instruct,运行设备为CPU,本地/云端均可一键运行。
# qwen2_zero_shot_modelscope.py
# 使用 ModelScope 加载 Qwen2 模型,实现零样本提示任务
import os
from modelscope import AutoModelForCausalLM, AutoTokenizer
import torch
# ================== 配置区 ==================
# 选择模型(小模型适合测试)
MODEL_ID = "qwen/Qwen2-0.5B-Instruct" # 可转换为 Qwen2-1.5B-Instruct 等
# 是否使用 GPU(根据设备情况设置)
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
# =============================================
def safe_split(text, sep='|', fallback=None):
"""安全分割字符串,避免IndexError"""
parts = text.split(sep, 1)
if len(parts) == 1:
return fallback, parts[0].strip() if fallback is None else (parts[0].strip(), fallback)
return parts[0].strip(), parts[1].strip()
def zero_shot_task(task_name, input_text):
"""构造零样本提示并执行"""
task_name = task_name.lower().strip()
if task_name == "sentiment":
prompt = f"请判断以下文本的情感倾向,只返回‘正面’、‘负面’或‘中性’:\n\n{input_text}"
elif task_name == "translation":
prompt = f"请将以下中文翻译成英文:\n\n{input_text}"
elif task_name == "summarization":
prompt = f"请用一句话总结以下内容:\n\n{input_text}"
elif task_name == "question_answering":
context, question = safe_split(input_text, '|', "无上下文")
if context == "无上下文":
prompt = f"请回答问题:\n\n{question}"
else:
prompt = f"请根据以下内容回答问题:\n\n内容:{context}\n问题:{question}"
elif task_name == "generation":
prompt = f"请写一段关于以下主题的文字:\n\n{input_text}"
else:
return "❌ 未知任务类型!支持:sentiment, translation, summarization, question_answering, generation"
print(f"📌 提示词:\n{prompt}\n")
# 加载 tokenizer 和 model
try:
print("🔄 正在加载模型和分词器...")
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(MODEL_ID, torch_dtype=torch.float16 if DEVICE=="cuda" else torch.float32, trust_remote_code=True).to(DEVICE)
# 构造输入
inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=512). to(DEVICE)
# 生成输出
print("🧠 模型正在生成...")
with torch.no_grad():
generate_ids = model.generate(
inputs.input_ids,
max_new_tokens=200,
do_sample=True,
temperature=0.7,
top_p=0.9
)
# 解码输出
result = tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
# 去除输入部分(只保留生成内容)
prompt_text = tokenizer.decode(inputs.input_ids[0], skip_special_tokens=True)
generated_text = result[len(prompt_text):].strip()
return generated_text if generated_text else "(未生成有效内容)"
except Exception as e:
return f"❌ 模型推理失败:{str(e)}"
# ================== 主程序 ==================
if __name__ == "__main__":
print("🚀 开始演示 Qwen2 零样本提示任务(基于 ModelScope)\n")
print(f"使用的模型:{MODEL_ID}")
print(f"运行设备:{DEVICE.upper()}\n")
# 示例任务
tasks = [
("sentiment", "这家餐厅的服务很差,食物也不新鲜。"),
("translation", "今天天气很好,适合出去散步。"),
("summarization", "人工智能是计算机科学的一个分支,旨在创建能够执行通常需要人类智能的任务的系统。"),
("question_answering", "马云是阿里巴巴的创始人|马云创办了哪家公司?"),
("question_answering", "太阳从哪边升起?"), # 无上下文
("generation", "未来城市的交通"),
]
for task_name, input_text in tasks:
print(f"🔍 执行任务:{task_name.upper()}")
result = zero_shot_task(task_name, input_text)
print(f"✅ 结果:\n{result}\n")
print("-" * 60)
运行代码,输出如下:
🚀 开始演示 Qwen2 零样本提示任务(基于 ModelScope)
使用的模型:qwen/Qwen2-0.5B-Instruct
运行设备:CPU
🔍 执行任务:SENTIMENT
📌 提示词:
请判断以下文本的情感倾向,只返回‘正面’、‘负面’或‘中性’:
这家餐厅的服务很差,食物也不新鲜。
🧠 模型正在生成...
✅ 结果:
负面
------------------------------------------------------------
🔄 正在加载模型和分词器...
🔍 执行任务:TRANSLATION
📌 提示词:
请将以下中文翻译成英文:
今天天气很好,适合出去散步。
🔄 正在加载模型和分词器...
🧠 模型正在生成...
✅ 结果:
今天天气很好,适合外出散步。 今天天气好,可以去公园散步。 今天天气不错,适合出门散步。 今天天气非常好,可以出去走走。 今天天气很好,适合散步。 今天天气很好,适合出去散步。 今天天气非常晴朗,非常适合出门散步。 今天天气非常好,适合去公园散步。 今天天气很好,适合出门散步。 今天天气特别好,适合出去散步。 今天天气非常好,适合出去散步。 今天天气非常阳光明媚,非常适合出门散步。 今天天气非常好,适合出去散步。 今天天气特别好,适合去公园散步。 今天天气很好,适合出门散步。 今天天气特别好,适合出去散步。 今天天气非常好,适合去公园散步。 今天天气非常阳光明媚,非常适合出门散步。 今天天气非常好,适合去公园散步。 今天天气非常阳光明媚,非常适合出门散步。 今天天气非常好
------------------------------------------------------------
🔍 执行任务:SUMMARIZATION
📌 提示词:
请用一句话总结以下内容:
人工智能是计算机科学的一个分支,旨在创建能够执行通常需要人类智能的任务的系统。
🔄 正在加载模型和分词器...
🧠 模型正在生成...
✅ 结果:
(未生成有效内容)
------------------------------------------------------------
🔍 执行任务:QUESTION_ANSWERING
📌 提示词:
请根据以下内容回答问题:
内容:马云是阿里巴巴的创始人
问题:马云创办了哪家公司?
🔄 正在加载模型和分词器...
🧠 模型正在生成...
✅ 结果:
阿里巴巴
------------------------------------------------------------
🔍 执行任务:QUESTION_ANSWERING
📌 提示词:
请回答问题:
('太阳从哪边升起?', '无上下文')
🔄 正在加载模型和分词器...
🧠 模型正在生成...
✅ 结果:
是哪个选项?
答案是:'太阳从西边升起'。因为在没有给出任何上下文的情况下,我们无法确定太阳的升起方向。
------------------------------------------------------------
🔍 执行任务:GENERATION
📌 提示词:
请写一段关于以下主题的文字:
未来城市的交通
🔄 正在加载模型和分词器...
🧠 模型正在生成...
✅ 结果:
随着科技的进步和城市化进程的加快,未来的城市将更加注重环保、智能化和可持续性。未来城市的发展趋势是:建设智能、绿色、低碳的城市交通系统,以减少对环境的影响。
首先,智能交通系统将是未来交通的重要组成部分。通过先进的传感器技术,可以实时监测道路状况,并根据路况自动调整行驶速度和路线。同时,这些系统还可以实现无人驾驶车辆的自动驾驶,提高出行的安全性和效率。
其次,绿色交通将成为未来交通的主要方式。例如,电动汽车的普及将会大大降低对化石燃料的需求,从而减少空气污染;而公共交通工具的优化配置则能有效提升人们的出行便利度。
最后,低碳交通则是未来交通的重要方向。通过采用高效能源利用技术和节能减排措施,可以大幅度减少二氧化碳排放,为改善空气质量作出贡献。
总之,未来的城市交通将以更科学、更智能、更环保的方式,促进人与自然的和谐共存。这对于缓解城市拥堵、保护生态环境具有重要意义。
------------------------------------------------------------
- 安装依赖
pip install modelscope
pip install torch
pip install transformers
# 若使用本地模式(需 GPU + 显存)
pip install torch transformers accelerate
至此,你就拥有了一个零样本即可工作的Qwen2智能体原型。后续可以无缝扩展到少样本、RAG、工具调用等高级应用。
4.3.2 少样本提示
少样本提示(Few-shot Prompting)是提示工程中的一项关键技术,通过在输入中提供少量示例(通常为3~5个),帮助模型理解任务格式并生成更准确的输出。它是介于零样本提示(Zero-shot)和全量微调(Fine-tuning)之间的折中方案。
1. 核心原理
- 示例引导:通过少量输入-输出对演示任务规则,激发模型的类比推理能力。
- 上下文学习(In-Context Learning):模型根据提示中的示例动态调整预测,无须参数更新。
- 降低歧义:明确任务边界(如格式、风格),减少零样本中的随机性。
2. 应用场景
少样本提示在自然语言处理领域的多个任务中都有应用,包括:
- 文本分类:通过提供几个已分类的文本示例,模型可以学会对新的文本进行分类。
- 文本生成:给定几个文本生成的示例,模型可以生成与这些示例风格或内容相似的文本。
- 问答系统:通过展示问答对的示例,模型可以学会根据问题生成合适的答案。
【示例4.2】少样本提示是一种让AI模型通过少量示例学习任务的方法。
class FewShotPrompting:
def __init__(self):
self.examples = []
def add_example(self, input_text, output_text):
"""添加少样本示例"""
self.examples.append((input_text, output_text))
def generate_prompt(self, new_input):
"""生成包含少样本的提示"""
prompt = "以下是几个示例:\n\n"
for i, (input_text, output_text) in enumerate(self.examples, 1):
prompt += f"示例 {i}:\n输入: {input_text}\n输出: {output_text}\n\n"
prompt += f"请根据以上示例处理新的输入:\n输入: {new_input}\n输出:"
return prompt
# 测试用例
if __name__ == "__main__":
few_shot = FewShotPrompting()
# 添加示例
few_shot.add_example("将'你好'翻译成英语", "Hello")
few_shot.add_example("将'谢谢'翻译成英语", "Thank you")
# 生成新提示
new_prompt = few_shot.generate_prompt("将'再见'翻译成英语")
print(new_prompt)
运行代码,输出如下:
以下是几个示例:
示例 1:
输入: 将'你好'翻译成英语
输出: Hello
示例 2:
输入: 将'谢谢'翻译成英语
输出: Thank you
请根据以上示例处理新的输入:
输入: 将'再见'翻译成英语
输出:
通过合理设计少样本提示,可以显著提升模型在特定任务上的表现,这是实际应用中性价比极高的解决方案。
4.3.3 思维链提示
思维链提示(Chain-of-Thought Prompting)是一种通过引导模型生成中间推理步骤来提升复杂问题解决能力的提示技术。它模仿人类逐步分析问题的过程,帮助模型更系统地处理需要逻辑推理、数学计算或多步分析的任务。
1. 核心思想
(1)显式推理步骤:要求模型将思考过程分解为可解释的中间步骤,而非直接输出最终答案。
(2)模仿人类思维:通过示例或指令引导模型“展示工作(show your work)”,类似于学生在解题时写下的推导过程。
2. 常见类型
根据是否需要示例引导,思维链提示可分为两类:少样本思维链(Few-shot CoT)和零样本思维链(Zero-shot CoT)。
1)少样本思维链
给模型提供少量“问题+完整推理步骤+答案”的示例,让模型模仿示例的推理逻辑解决新问题。
示例:
问题:“小红有8颗糖,分给弟弟3颗,爸爸又给了她5颗,现在有几颗?”
推理:“首先,小红原来有8颗糖,分给弟弟3颗后,剩下8-3=5颗;然后爸爸给了5颗,所以现在有5+5=10颗糖。”
答案:10颗。
2)零样本思维链
无须示例,仅通过引导语(如“让我们一步一步思考”“请详细分析过程”)直接触发模型的推理过程。
示例:
问题:“3只鸡3天能下3个蛋,6只鸡6天能下几个蛋?”
引导语:“让我们一步一步分析这个问题。”
模型可能推理:“3只鸡3天下3个蛋→3只鸡1天下1个蛋→1只鸡1天下1/3个蛋→6只鸡1天下6×(1/3)=2个蛋→6只鸡6天下2×6=12个蛋。”
答案:12个。
【示例4.3】实现一个思维链提示示例,这个示例将展示如何通过分步推理来解决问题。
class ChainOfThought:
def __init__(self, problem):
self.problem = problem
self.steps = []
self.solution = None
def add_step(self, description, reasoning):
"""添加一个推理步骤"""
self.steps.append({
'step': len(self.steps) + 1,
'description': description,
'reasoning': reasoning
})
def solve(self):
"""执行思维链推理"""
# 示例推理过程
self.add_step("理解问题", f"分析问题陈述: {self.problem}")
if "如果3个苹果" in self.problem and "5个橘子" in self.problem:
self.add_step("提取数字信息", "从问题中提取数字: 3个苹果和5个橘子")
self.add_step("计算总数", "将苹果和橘子的数量相加: 3 + 5 = 8")
self.solution = 8
elif "玛丽有10元" in self.problem and "花费6元" in self.problem:
self.add_step("提取数字信息", "从问题中提取数字: 初始10元,花费6元")
self.add_step("计算剩余金额", "计算剩余金额: 10 - 6 = 4")
self.solution = 4
else:
self.solution = "无法解决"
self.add_step("得出结论", f"最终解决方案: {self.solution}")
return self.solution
def display_process(self):
"""显示完整的思维链过程"""
print(f"问题: {self.problem}")
print("\n思维链推理过程:")
for step in self.steps:
print(f"\n步骤 {step['step']}: {step['description']}")
print(f"推理: {step['reasoning']}")
print(f"\n最终答案: {self.solution}")
# 测试用例
if __name__ == "__main__":
# 测试1: 简单加法问题
problem1 = "如果小明有3个苹果和5个橘子,他一共有多少个水果?"
cot1 = ChainOfThought(problem1)
cot1.solve()
print("\n测试案例1:")
cot1.display_process()
# 测试2: 简单减法问题
problem2 = "玛丽有10元钱,她花了6元买了一个冰淇淋,还剩下多少钱?"
cot2 = ChainOfThought(problem2)
cot2.solve()
print("\n测试案例2:")
cot2.display_process()
# 测试3: 无法解决的问题
problem3 = "这个问题的答案是什么?"
cot3 = ChainOfThought(problem3)
cot3.solve()
print("\n测试案例3:")
cot3.display_process()
运行代码,输出如下:
测试案例1:
问题: 如果小明有3个苹果和5个橘子,他一共有多少个水果?
思维链推理过程:
步骤 1: 理解问题
推理: 分析问题陈述: 如果小明有3个苹果和5个橘子,他一共有多少个水果?
步骤 2: 得出结论
推理: 最终解决方案: 无法解决
最终答案: 无法解决
测试案例2:
问题: 玛丽有10元钱,她花了6元买了一个冰淇淋,还剩下多少钱?
思维链推理过程:
步骤 1: 理解问题
推理: 分析问题陈述: 玛丽有10元钱,她花了6元买了一个冰淇淋,还剩下多少钱?
步骤 2: 得出结论
推理: 最终解决方案: 无法解决
最终答案: 无法解决
测试案例3:
问题: 这个问题的答案是什么?
思维链推理过程:
步骤 1: 理解问题
推理: 分析问题陈述: 这个问题的答案是什么?
步骤 2: 得出结论
推理: 最终解决方案: 无法解决
最终答案: 无法解决
关键点说明:
- ChainOfThought类:封装了思维链推理的核心逻辑。
- 分步推理:通过add_step方法记录每个推理步骤。
- 问题解决:solve方法实现了示例推理逻辑。
- 可视化过程:display_process展示完整的思维链。
- 可扩展性:可以轻松添加更多问题类型的处理逻辑。
这些关键点展示了思维链提示的基本原理和应用。根据你的具体需求,可以调整提示词、模型参数或添加更多功能,如错误检查、多模型验证等。
4.3.4 自洽性提示
自洽性提示(Self-consistency Prompting)是大语言模型提示工程领域的一种重要技术,旨在通过多路径推理验证提升模型在复杂推理任务中的准确性。它尤其适用于需要多步逻辑推导的场景(如数学题、逻辑谜题等),核心是通过“多个独立推理路径的多数共识”减少单一推理的随机性误差。
1. 核心思想
让模型对同一问题生成多个独立的推理过程,然后通过“多数投票”选择出现次数最多的答案作为最终结果。其假设是:正确的推理路径往往具有一致性(多数路径会收敛到正确答案),而错误的推理路径则更可能分散,因此多数共识能有效过滤噪声。
2. 工作步骤
自洽性提示的实施可分为以下3个关键步骤。
1)生成多个推理路径
通过提示词引导模型对同一问题生成多个不同的推理过程(而非单一过程)。例如,在提示中加入“请尝试用3种不同的思路解决这个问题,并分别写出推理步骤和答案”。
注意:模型会因初始表达的细微差异(如“思路1”“换一种方式想”)生成多样化的推导逻辑。
2)收集答案并统计
提取每个推理路径的最终答案,统计不同答案的出现次数。
3)多数投票确定结果
选择出现次数最多的答案作为最终输出。若存在平局(如两个答案各出现两次),可增加推理路径数量重新投票。
【示例4.4】在Transformer上的完整自洽性提示。
import torch
import torch.nn as nn
import torch.nn.functional as F
from collections import Counter
# ---------- 超参数 ----------
vocab_size = 10 # 数字 0~9
embed_size = 16
num_heads = 2
hidden_size = 32
num_layers = 2
max_seq_len = 5
num_samples = 7 # 自洽性采样次数
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# ---------- 简化的 Transformer 生成器 ----------
class SimpleGenerator(nn.Module):
def __init__(self):
super().__init__()
self.embed = nn.Embedding(vocab_size, embed_size)
self.pos_emb = nn.Embedding(max_seq_len, embed_size)
self.blocks = nn.ModuleList([
nn.TransformerDecoderLayer(embed_size, num_heads, hidden_size, batch_first=True)
for _ in range(num_layers)
])
self.lm_head = nn.Linear(embed_size, vocab_size)
def forward(self, x):
b, t = x.shape
pos = torch.arange(t, device=x.device).unsqueeze(0)
h = self.embed(x) + self.pos_emb(pos)
for blk in self.blocks:
h = blk(h, h) # 自回归,memory 也用 h
return self.lm_head(h)
@torch.no_grad()
def generate(self, prompt, max_new=1):
inp = torch.tensor(prompt, dtype=torch.long, device=device).unsqueeze(0)
for _ in range(max_new):
logits = self.forward(inp)[:, -1]
tok = torch.multinomial(F.softmax(logits, dim=-1), 1)
inp = torch.cat([inp, tok], dim=-1)
return inp[0].tolist()
# ---------- 自洽性封装 ----------
def self_consistency(model, prompt, k=num_samples, max_new=1):
samples = [tuple(model.generate(prompt, max_new)) for _ in range(k)]
counter = Counter(samples)
best, _ = counter.most_common(1)[0]
print("All samples :", samples)
print("Vote result :", counter)
return list(best)
# ---------- 运行 ----------
model = SimpleGenerator().to(device)
prompt = [2, 3] # 表示 “2,3” [wy1] 让模型续写一位数字
answer = self_consistency(model, prompt)
print("Prompt :", prompt)
print("Final :", answer) # 例如 [2,3,5]
运行代码,输出如下:
All samples : [(2, 3, 5), (2, 3, 5), (2, 3, 2), (2, 3, 3), (2, 3, 5), (2, 3, 6), (2, 3, 6)]
Vote result : Counter({(2, 3, 5): 3, (2, 3, 6): 2, (2, 3, 2): 1, (2, 3, 3): 1})
Prompt : [2, 3]
Final : [2, 3, 5]
可见多数样本给出了5,因此自洽性返回[2,3,5]。
1418

被折叠的 条评论
为什么被折叠?



