news 2026/2/2 18:36:08

【大模型应用开发】第一阶段:提示工程与上下文学习 (Prompt Engineering ICL)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【大模型应用开发】第一阶段:提示工程与上下文学习 (Prompt Engineering ICL)

第一阶段:提示工程与上下文学习 (Prompt Engineering & ICL)

“In-Context Learning is meta-learning without gradient descent.” —— 上下文学习本质上是一种无需梯度更新的元学习。本章将深入探讨如何在不更新模型参数的情况下,通过提示工程(Prompt Engineering)和上下文学习(In-Context Learning)激发大模型的潜能,构建复杂的应用系统。


目录

  • 第一节:提示工程最佳实践
    • 1.1 结构化提示词 (Structured Prompt)
    • 1.2 角色与约束 (Role & Constraints)
    • 1.3 输出控制 (Output Format)
  • 第二节:上下文学习 (In-Context Learning)
    • 2.1 Few-Shot Learning 原理
    • 2.2 动态示例选择 (Dynamic Few-Shot)
    • 2.3 实战:构建 Few-Shot 文本分类器
  • 第三节:思维链推理 (Chain-of-Thought)
    • 3.1 Zero-Shot CoT
    • 3.2 Manual CoT
    • 3.3 Least-to-Most Prompting
  • 第四节:RAG 系统设计模式预览
    • 4.1 为什么需要 RAG?
    • 4.2 基础 RAG 流程
    • 4.3 模块化 RAG 架构
  • 第五节:实战:从零构建智能对话系统
    • 5.1 系统架构设计
    • 5.2 核心 Prompt 编排
    • 5.3 完整代码实现
  • 第六节:进阶应用:SetFit 与 语义聚类
    • 6.1 SetFit:少样本分类微调
    • 6.2 BERTopic:语义主题建模
  • 本章小结
  • 思考练习
  • 参考资料

第一节:提示工程最佳实践

提示工程(Prompt Engineering)并非玄学,而是与模型沟通的编程语言。SOTA 的提示词设计通常遵循清晰的结构化原则。

1.1 结构化提示词 (Structured Prompt)

一个优秀的 Prompt 应该像代码一样具备模块化结构,通常包含以下要素:

  1. Role (角色):定义 AI 的身份和能力边界。
  2. Context (背景):提供任务背景信息。
  3. Instruction (指令):清晰、动词导向的任务描述。
  4. Data (数据):输入的数据内容。
  5. Output Indicator (输出指引):期望的输出格式。

代码示例

PROMPT_TEMPLATE=""" ### Role 你是一位资深的数据分析师,擅长从非结构化文本中提取关键商业洞察。 ### Context 我们收到了一批用户关于"智能咖啡机"的产品反馈,需要整理用户的核心痛点。 ### Instruction 请分析以下用户评论,提取出: 1. 情感倾向 (Positive/Negative/Neutral) 2. 核心关键词 (最多3个) 3. 问题摘要 (一句话) ### Data 用户评论:"{user_review}" ### Output Format 请仅输出 JSON 格式,不要包含Markdown标记: {{ "sentiment": "...", "keywords": ["...", "..."], "summary": "..." }} """

1.2 角色与约束 (Role & Constraints)

角色设定不仅是“扮演游戏”,它实际上是在潜在空间(Latent Space)中锁定模型的生成模式。

  • 弱角色:“帮我写个代码。”
  • 强角色:“你是一位 Google L5 级别的 Python 工程师,遵循 PEP8 规范,代码需包含类型提示(Type Hints)和 Google 风格的 Docstring。”

约束技巧

  • 负向约束(Negative Constraints):明确告诉模型不要做什么(例如:“不要使用礼貌用语”、“不要解释代码”)。
  • 长度约束:指定字数或段落数。

1.3 输出控制 (Output Format)

在工程化应用中,稳定的输出格式至关重要。

  • JSON Mode:现代 LLM(如 GPT-4o, DeepSeek-V3)通常支持response_format={"type": "json_object"}
  • Structure Prompting:在 Prompt 末尾给出明确的 Schema 定义。
# 使用 Pydantic 定义输出结构 (配合 Instructor 库)frompydanticimportBaseModelfromtypingimportListclassAnalysisResult(BaseModel):sentiment:strkeywords:List[str]summary:str# 这种方式能确保 100% 的格式稳定性

第二节:上下文学习 (In-Context Learning)

核心问题:如何不重新训练模型,就能让它理解复杂任务?
答案:In-Context Learning (ICL)。利用模型强大的短期记忆(Context Window),直接在 Prompt 中提供示例。

2.1 Few-Shot Learning 原理

Few-Shot Learning(少样本学习)是指在 Prompt 中提供Input-Output 对作为示例。

为什么有效?
模型通过注意力机制(Self-Attention)"读取"这些示例,捕捉输入与输出之间的映射关系,并在推理时模仿这种模式。这本质上是一种无需梯度更新的元学习

示例对比

  • Zero-Shot:
    这句评论是正面的还是负面的? "快递慢得像乌龟。"
  • Few-Shot:
    判断评论情感: 输入:"屏幕清晰度很高。" 输出:正面 输入:"电池用了半天就没电了。" 输出:负面 输入:"快递慢得像乌龟。" 输出:

2.2 动态示例选择 (Dynamic Few-Shot)

当任务复杂且示例池很大时,固定示例效果不佳。最佳实践是根据 Query 动态检索最相似的示例

架构设计

  1. 建立一个示例库 (Example Store)(Input-Output Pairs)。
  2. 为示例库中的 Input 计算 Embeddings,存入向量库。
  3. 用户输入 Query 时,先检索 Top-K 最相似的 Input 示例。
  4. 将这 K 个示例组装进 Prompt。

代码逻辑

fromsentence_transformersimportSentenceTransformer,util embedder=SentenceTransformer('BAAI/bge-large-zh-v1.5')# 示例库: 输入-输出对example_corpus=["屏幕清晰度很高。","电池用了半天就没电了。","物流速度超快!"]example_labels=["正面","负面","正面"]example_embeddings=embedder.encode(example_corpus)defget_dynamic_prompt(query):query_emb=embedder.encode(query)# 检索最相似的 3 个示例hits=util.semantic_search(query_emb,example_embeddings,top_k=3)prompt="参考以下相似案例进行回答:\n\n"forhitinhits[0]:idx=hit['corpus_id']prompt+=f"示例输入:{example_corpus[idx]}\n示例输出:{example_labels[idx]}\n\n"prompt+=f"当前输入:{query}\n输出:"returnprompt

2.3 实战:构建 Few-Shot 文本分类器

利用 ICL,我们可以快速构建一个高精度的意图分类器,无需任何训练。

(此部分整合了原章节的分类实战内容,但侧重于 Prompt 实现)

# 核心 Prompt 模板CLASSIFICATION_PROMPT=""" 你是一个智能客服意图识别助手。请参考以下示例,确定用户问题的类别。 类别列表:[账号问题, 支付失败, 物流查询, 售后退换] 示例 1: 用户: "怎么还没发货?都三天了" 类别: 物流查询 示例 2: 用户: "充值成功了但是余额没变" 类别: 支付失败 示例 3: 用户: "我想修改绑定的手机号" 类别: 账号问题 用户: "{query}" 类别: """

第三节:思维链推理 (Chain-of-Thought)

3.1 为什么需要 CoT?(数学视角)

在直觉上,CoT (Chain-of-Thought)是让模型"慢下来思考"。但在数学上,它的本质是引入了隐变量 (Latent Variable)来解构复杂概率分布。

1. 贝叶斯视角
对于复杂问题(如数学题),直接建模P ( a n s w e r ∣ q u e s t i o n ) P(answer|question)P(answerquestion)是非常困难的,因为输入空间到输出空间的映射极其非线性。
CoT 引入了中间推理步骤z zz(rationale):
P ( a ∣ q ) = ∑ z P ( a ∣ z , q ) ⋅ P ( z ∣ q ) P(a|q) = \sum_{z} P(a|z, q) \cdot P(z|q)P(aq)=zP(az,q)P(zq)
其中:

  • P ( z ∣ q ) P(z|q)P(zq):给定问题,生成推理步骤的概率(这一步往往更符合自然语言逻辑,容易建模)。
  • P ( a ∣ z , q ) P(a|z, q)P(az,q):给定推理步骤,生成答案的概率(这一步通常是确定性的)。

2. 计算复杂度视角
Transformer 模型的计算深度(层数)是固定的。对于需要N NN步逻辑推理的问题,如果只输出一个 token 的答案,模型必须在有限的层数内完成所有计算。
CoT 允许模型生成T TT个 token 的推理过程,这相当于将计算时间线性扩展,用更多的 FLOPs (浮点运算) 换取更高的准确率。

3.2 经典 CoT 模式

(1) Zero-Shot CoT

最著名的"魔法咒语":

“Let’s think step by step.” (让我们一步步思考)

这句话会显著改变模型的生成概率分布,使其倾向于输出逻辑连接词(如 “First”, “Therefore”),从而触发内部的推理电路。

(2) Manual CoT (Few-Shot)

在 Few-Shot 示例中,显式写出推理过程。

示例

问题:Roger 有 5 个网球,他又买了两罐网球,每罐有 3 个。他现在一共有多少个网球? 思考过程: 1. Roger 起始有 5 个球。 2. 2 罐网球,每罐 3 个,共 2 * 3 = 6 个球。 3. 总数为 5 + 6 = 11 个。 答案:11

3.3 CoT 的缺陷与改进

1. 缺陷 A:错误级联 (Error Cascading)
由于P ( a ∣ z ) P(a|z)P(az)强依赖于z zz,如果推理链中的某一步z t z_tzt出现幻觉,后续的所有推理都会基于这个错误前提。

2. 缺陷 B:事后合理化 (Post-hoc Rationalization)
这是一种更隐蔽的缺陷,揭示了理论理想与实践现实的差距

  • 理论模型(贝叶斯视角):CoT 应该遵循P ( a ∣ z , q ) ⋅ P ( z ∣ q ) P(a|z,q) \cdot P(z|q)P(az,q)P(zq)的链式推理,即先生成推理步骤z zz,再基于z zz推导答案a aa
  • 实践现实(Post-hoc):模型可能因为训练数据中存在某种"捷径",直接通过P ( a ∣ q ) P(a|q)P(aq)先"蒙"出了正确答案,然后为了满足 CoT 格式的要求,事后编造一段看似合理的推理过程。

现象:推理过程z zz充满错误逻辑,但最终答案a aa竟然是对的。此时 CoT 的数学分解失效,变成了"马后炮"。这说明贝叶斯分解是 CoT 的理想工作机制,但在实际应用中,模型并不总是严格遵循这一机制。

3. 改进方案:Self-Consistency (自洽性)
利用温度采样(Temperature > 0)生成K KK条不同的推理路径,然后对最终答案进行投票 (Majority Vote)
a ^ = arg ⁡ max ⁡ a ∑ k = 1 K I ( a k = a ) \hat{a} = \arg\max_{a} \sum_{k=1}^K \mathbb{I}(a_k = a)a^=argamaxk=1KI(ak=a)
这利用了大数定律消除了单条推理路径的随机噪声。

3. 进阶结构:Tree of Thoughts (ToT)
将线性的 CoT 扩展为树状结构,允许模型在推理过程中:

  • 分支:探索多种可能性。
  • 回溯:如果当前路径不可行,退回上一步。
  • 评估:对每一步的状态进行自我打分。

3.4 Least-to-Most Prompting

对于极度复杂的问题,采用**“拆解-解决”**策略:

  1. Decomposition: 先让模型把大问题拆解为子问题列表。
  2. Sequential Solving: 逐个解决子问题,把上一步的答案作为下一步的输入。

从推理到检索:CoT 的局限性

CoT 强化了模型的推理能力,但它依然无法解决一个根本问题:知识的边界。无论推理链多么完善,如果模型的参数中没有存储相关知识(例如最新的市场数据、企业内部文档),它只能基于"幻觉"进行推理。

这就引出了下一个核心问题:如何让模型访问外部知识?这正是 RAG (Retrieval-Augmented Generation) 的使命——将模型的生成能力与外部知识库的检索能力相结合。

第四节:RAG 系统设计模式预览

虽然 RAG (Retrieval-Augmented Generation) 也是提示工程的一种延伸(将检索结果作为 Context),但它已发展为独立领域。本节简要预览,详细内容见下一章。

4.1 为什么需要 RAG?

  • 幻觉 (Hallucination):模型会一本正经地胡说八道。
  • 时效性 (Cutoff Date):模型知识有截止日期(如 2023 年)。
  • 私有数据 (Private Data):模型不知道企业内部文档。

4.2 基础 RAG 流程与代码

Query -> Search(Vector DB) -> Context -> Augmented Prompt -> LLM -> Answer

极简代码示例

# 1. 检索 (Retrieve)docs=vector_db.similarity_search("公司Q3营收",k=3)context="\n".join([d.page_contentfordindocs])# 2. 增强 (Augment)prompt=f"基于以下上下文回答问题:\n{context}\n\n问题:公司Q3营收是多少?"# 3. 生成 (Generate)response=client.chat.completions.create(model="gpt-4",messages=[{"role":"user","content":prompt}])

4.3 模块化 RAG 架构

  • RRR 模式:Rewrite (改写问题) -> Retrieve (检索) -> Read (阅读回答)。
  • HyDE:先假设一个答案,用假设答案去检索,再生成真实答案。

第五节:实战:从零构建智能对话系统

本节我们将综合运用 Role, Few-Shot, CoT 技术,构建一个基于文档的智能问答助手

5.1 系统架构设计

系统分为三层:

  1. 输入处理层:Prompt 优化、意图识别。
  2. 上下文层:管理对话历史 (Memory)、检索知识库。
  3. 生成层:调用 LLM API,结构化输出。

5.2 核心 Prompt 编排

SYSTEM_PROMPT=""" Role: 你是一个专业的金融文档助手。你的任务是依据提供的上下文(Context)回答用户关于财报的问题。 Constraints: 1. 只能基于 Context 回答,不要使用你的外部知识。 2. 如果 Context 中没有答案,请直接回答"根据当前文档无法回答",不要编造。 3. 保持客观、专业,引用 Context 中的数据时要保留 2 位小数。 Thinking Process (CoT): 请先分析用户的意图,然后在 Context 中寻找相关段落,最后整合成答案。 """

5.3 完整代码实现

fromopenaiimportOpenAI client=OpenAI()defchat_bot(user_query,context_chunks):# 1. 构建 Context 字符串context_str="\n---\n".join(context_chunks)# 2. 组装 Promptmessages=[{"role":"system","content":SYSTEM_PROMPT},{"role":"user","content":f"Context:\n{context_str}\n\nQuestion:{user_query}"}]# 3. 调用 LLMresponse=client.chat.completions.create(model="gpt-4o",messages=messages,temperature=0.3# 降低随机性,提高事实准确度)returnresponse.choices[0].message.content# 模拟运行docs=["Q3财报显示,公司营收达到 10.52 亿元,同比增长 15.3%。","净利润为 2.1 亿元,主要得益于云服务业务的扩展。"]print(chat_bot("公司Q3营收表现如何?",docs))

第六节:进阶应用:SetFit 与 语义聚类

为了弥补传统 Prompt 在小样本高精度场景下的不足,我们可以引入更重的工程方案。这是连接 Prompt Engineering 与 Fine-tuning 的桥梁。

(本节保留了原“文本分类”章节的精华内容,作为高级实战案例)

6.1 SetFit:少样本分类微调

SetFit (Sentence Transformer Fine-tuning)是一种无需大规模标注数据的高效分类框架。

  • 原理:先对 Embedding 模型进行对比学习微调(Contrastive Learning),再训练一个分类头(Classification Head)。
  • 优势:在只有 8 个样本/类的情况下,性能可媲美全量微调的 BERT。
fromsetfitimportSetFitModel,SetFitTrainerfromdatasetsimportload_dataset# 1. 加载少样本数据 (每类仅需8条)dataset=load_dataset("SetFit/emotion",split="train[:32]")# 示例# 2. 初始化模型model=SetFitModel.from_pretrained("sentence-transformers/paraphrase-mpnet-base-v2")# 3. 训练 (极快, CPU上几分钟)trainer=SetFitTrainer(model=model,train_dataset=dataset,loss_class="CosFaceLoss",metric="accuracy",batch_size=16,num_iterations=20,# 对比学习迭代次数)trainer.train()# 4. 推理preds=model(["This movie is so boring..."])print(preds)

6.2 BERTopic:语义主题建模

当没有标签时,如何理解大规模文本数据?Prompt Engineering 很难处理全量数据聚类,这时需要BERTopic

代码实战

frombertopicimportBERTopicfromsklearn.datasetsimportfetch_20newsgroups# 1. 加载数据docs=fetch_20newsgroups(subset='all')['data'][:1000]# 2. 训练模型 (Embed -> UMAP -> HDBSCAN -> c-TF-IDF)topic_model=BERTopic(language="english",calculate_probabilities=True)topics,probs=topic_model.fit_transform(docs)# 3. 查看主题topic_model.get_topic_info().head(3)# 输出: Topic 0: [game, team, ball...], Topic 1: [key, chip, encryption...]

对比:

  • Prompt: 适合处理单条数据的精细理解。
  • BERTopic: 适合对百万级数据进行宏观鸟瞰。

本章小结

本章是应用开发的起点,我们完成了从指令设计系统构建的跨越:

  1. Prompt Engineering:不只是写句子,而是结构化编程(Role, Context, Constraints)。
  2. In-Context Learning:利用Few-Shot动态示例检索,无需训练即可通过图灵测试。
  3. CoT:通过显式思维链,解锁了模型的复杂推理能力。
  4. 实战落地:通过SetFit等工具,我们将 Prompt 的思想延伸到了轻量级训练领域。

核心心法

“不要试图让模型’猜’你的意图,要像写代码一样,给它清晰、明确、结构化的指令。”


思考练习

1. Prompt 逆向工程:如何反推 System Prompt?
要反推优秀回答的 Prompt,通常可以从其输出结构和回复语气入手。

语气:如果非常专业且严谨,可能包含 You are an expert… 或 Avoid filler words。

格式:如果输出总是带有清晰的分级标题和加粗,说明有 Use Markdown hierarchy 的指令。

边界:如果你问它违法或敏感问题它能礼貌拒绝,说明包含 Refuse to provide medical/legal advice 的安全约束。

技巧:可以尝试直接问 AI:“为了生成刚才那样的回答,我应该给你什么样的指令最有效?”

2. CoT 陷阱:什么情况下 CoT 反而有害?
简单常识任务:如“天空是什么颜色?”,增加推理过程反而增加了出错几率(错误级联)且浪费 Token 成本。

纯知识检索任务:如果模型根本不知道某个生僻事实,强行要求它“一步步思考”只会导致它一本正经地胡说八道(增加幻觉的连贯性)。

窄任务/固定格式输出:当需要极其简短的输出(如“是/否”)时,CoT 的中间过程可能导致解析 JSON 或特定格式失败。

3. Few-Shot 鲁棒性:Label Noise 有影响吗?
结论:LLM 对 Few-Shot 中的标签错误具有惊人的容忍度。

说明了什么?:研究表明,Few-Shot 示例的主要作用并非通过标签教会模型新知识,而是通过示例的分布和格式告诉模型“输入长什么样”以及“输出的候选项有哪些”。

关键点:示例中的“输入空间分布”(Input Space Distribution)和“输出格式规范”比“输入-标签映射”的准确性更重要。这说明模型更像是在“对齐”现有的知识,而非学习新映射。


参考资料

  1. OpenAI Prompt Engineering Guide: platform.openai.com/docs/guides/prompt-engineering
  2. Chain-of-Thought Paper: “Chain-of-Thought Prompting Elicits Reasoning in Large Language Models” (Wei et al., 2022)
  3. SetFit: https://github.com/huggingface/setfit
  4. Lilian Weng Blog: “Prompt Engineering” (lilianweng.github.io)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/2 18:30:36

基于SpringBoot+Vue的健康管理系统

🍅 作者主页:Selina .a 🍅 简介:Java领域优质创作者🏆、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行交流合作。 主要内容:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据…

作者头像 李华
网站建设 2026/2/2 18:28:29

【IEEE出版、快速EI检索】2026年人工智能、教育技术与应用国际学术会议(AIETA 2026)

随着人工智能(AI)的迅速发展,其与教育的深度融合正在重塑全球教育生态系统。诸如智能辅导系统、个性化学习和教育大数据分析等创新应用为教育公平、质量提升和教学变革开辟了新的途径。为促进全球学者、教育工作者和技术专家之间的跨学科合作…

作者头像 李华
网站建设 2026/2/2 18:27:45

A股大洗牌:六记重拳整顿量化交易,散户的春天来了?

一场迟来的“正义”对于在A股市场中拼搏的普通散户而言,面对拥有顶级硬件和速度优势的高频量化交易,时常会有一种无力感和不公平感。然而,一场颠覆性的游戏规则大改已经落地。监管机构祭出组合重拳,旨在给那些靠技术优势在市场中“…

作者头像 李华
网站建设 2026/2/2 18:21:03

双向链表是什么?和单向链表区别详解

双向链表是数据结构中链表的一种重要形式,它在每个节点中不仅包含指向下一个节点的指针,还包含指向前一个节点的指针。这种设计使得双向链表在数据操作上比单向链表更加灵活,但也带来了额外的存储开销。在实际开发中,双向链表常用…

作者头像 李华
网站建设 2026/2/2 18:18:42

Flutter艺术探索-Flutter Shader编程:着色器与特效实现

Flutter Shader编程:用着色器打造炫酷特效 引言:不止于Widget的图形渲染 平时做Flutter开发,我们习惯用各种Widget堆叠界面,设置动画和样式——这能解决大部分视觉需求。但当你想要一个流动的动态背景、一种特殊的模糊效果&…

作者头像 李华
网站建设 2026/2/2 18:15:16

基于Spring Boot的农产品直卖平台的设计与实现

背景及意义 在乡村振兴战略深入推进与农业数字化转型加速的背景下,传统农产品流通模式因中间环节繁杂、信息不对称严重,常出现农民收益受损、消费者难获优质溯源农产品的双重困境,而现有农产品电商平台多存在功能模块零散、数据管理效率低、系…

作者头像 李华