大模型应用开发教程06 | 高级提示词策略(Few-shot / CoT / 结构化)
理论部分在第 5 篇我们已经能用 “System角色/规则 User任务/输入” 把模型输出变得可控。但很多真实业务还会遇到两类问题同一个任务输出仍然会漂移格式不稳定、细节忽多忽少、偶尔跑题输出难以被程序消费我们想拿结果去写入数据库、调用工具、做后续计算但模型给的是一段“看起来对”的自然语言这时候就需要更“工程化”的提示词策略。最常用的三类是Few-shot、CoT、结构化输出。1Few-shot少样本提示Few-shot 的核心思想是给模型看我们想要的“示例”让示例变成隐性的规则。它特别适合我们要模型模仿某种输出格式例如固定字段、固定段落结构我们要模型保持口径一致例如统一的分类标准、统一的评分维度示例一般放在user内容里或作为多条消息放入messages常见形式是输入A → 输出A’输入B → 输出B’现在输入C → 请按同样方式输出C’2CoTChain-of-Thought思维链CoT 的核心思想是让模型把复杂任务分解成步骤再输出结果。它特别适合推理/规划型任务数学、逻辑、步骤规划、长文本分析需要“过程正确”才能保证“结果正确”的任务但要注意不是所有任务都需要 CoT信息抽取这类任务通常更需要“结构化输出”在产品场景里你更常见的做法是让模型在内部推理但只输出最终结果避免把中间过程暴露给用户3结构化输出Structured Output结构化输出的核心思想是我们先定义一个输出 Schema字段名/类型/含义再要求模型严格按 Schema 返回。它特别适合信息抽取简历解析、合同关键字段提取、发票/工单解析工具调用把模型输出当作函数参数后续要做程序处理验证、入库、统计、检索结构化输出常见两种实现方式强提示约束在 Prompt 里明确声明 JSON 结构、缺失字段填 null、禁止输出解释文字协议级约束如果模型/SDK 支持例如response_format{type: json_object}或 JSON Schema 模式本项目采用的是“强提示约束”的方式适配性更强所有兼容的模型都能用。实践部分本案例做什么实现一个“简历解析助手”输入一段乱糟糟的简历文本让模型输出一份严格 JSON 格式的结构化结果姓名、工作年限、技能、公司、学历、电话、以及一句话总结如果字段找不到填null输出只能是 JSON不能夹带解释文字主要代码本篇直接使用项目脚本src/2.2_structured_output.pyimportosimportjsonfromdotenvimportload_dotenvfromopenaiimportOpenAI load_dotenv()clientOpenAI(api_keyos.getenv(ZHIPUAI_API_KEY),base_urlos.getenv(ZHIPUAI_BASE_URL))defextract_resume_info(resume_text): 使用 LLM 提取简历信息为 JSON # 定义期望的 JSON 结构 (Schema)# 这一步非常关键你描述得越清楚模型提取越准schema_desc { name: 姓名, years_of_experience: 工作年限(数字), skills: [技能列表], companies: [工作过的公司列表], education: 最高学历, phone: 联系电话, summary: 一句话总结求职者的特点 } system_promptf 你是一个专业的 HR 简历解析助手。 请分析用户的输入提取关键信息并以 JSON 格式输出。 输出必须严格遵守以下 JSON 结构{schema_desc}注意 1. 如果某个字段在文本中找不到请填 null。 2. 不要输出任何 JSON 以外的解释性文字如“好的这是结果...”。 3. 直接返回 JSON 字符串。 messages[{role:system,content:system_prompt},{role:user,content:resume_text}]print( 正在解析简历...)# 调用模型# 注如果模型支持 json_object 模式建议开启 response_format{type: json_object}# 智谱 glm-4-flash 目前主要靠 prompt 约束我们这里通过 prompt 强力约束responseclient.chat.completions.create(modelglm-4-flash,messagesmessages,temperature0.1,# 信息提取类任务温度要低越严谨越好)contentresponse.choices[0].message.content# 清洗数据有时候模型可能会把 JSON 包裹在 json ... 里需要去掉ifjsonincontent:contentcontent.replace(json,).replace(,)returncontentdefmain():print( 智能简历解析助手 (JSON版) )# 模拟一段乱糟糟的简历文本default_resume 你好我叫李四。 之前在字节跳动干了3年后端主要用 Go 和 Python。 后来去了腾讯做了一年架构师。 我的电话是 186-1234-5678。 本科毕业于浙江大学。 希望能找个不加班的工作。 print(f\n原始文本:\n{default_resume})print(-*30)try:json_strextract_resume_info(default_resume)# 尝试将字符串解析为 Python 字典验证是否为合法 JSONdatajson.loads(json_str)print(\n✅ 解析成功! 结构化数据如下:\n)# 美化打印 JSONprint(json.dumps(data,indent4,ensure_asciiFalse))# 演示一下怎么用这个数据print(\n[后续代码调用示例])print(f候选人:{data.get(name)})print(f技能栈:{, .join(data.get(skills,[]))})exceptjson.JSONDecodeError:print(\n❌ 解析失败模型返回的不是标准 JSON。)print(模型原始返回:,json_str)exceptExceptionase:print(f\n❌ 发生错误:{e})if__name____main__:main()运行方式在项目根目录执行python3 src/2.2_structured_output.py运行结果示例正常情况下我们会看到模型输出的结构化 JSON字段值可能略有不同 智能简历解析助手 (JSON版) 原始文本: ... ------------------------------ ✅ 解析成功! 结构化数据如下: { name: 李四, years_of_experience: 4, skills: [ Go, Python ], companies: [ 字节跳动, 腾讯 ], education: 本科, phone: 186-1234-5678, summary: ... }如果出现解析失败模型返回的不是标准 JSON通常是模型在 JSON 前后输出了额外文字。这个脚本已经做了基础清洗去掉 json 包裹但也可以进一步加强约束更严格地声明“只能输出 JSON”并把温度保持在较低水平。总结这一篇我们掌握了三类常用的高级提示词策略Few-shot用示例让模型“照着做”CoT让复杂任务更容易推理正确结构化输出让结果可验证、可解析、可直接给程序使用