ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

大语言模型推理实战:情感分析、信息提取与逻辑链推理的提示词设计

大语言模型推理实战:情感分析、信息提取与逻辑链推理的提示词设计 1. 这篇文章真正要解决的问题如果你正在学习或使用大语言模型尤其是参与一些AI应用开发那么“推理”这个词你一定不陌生。但你是否遇到过这样的困境官方文档里讲得天花乱坠各种技术名词层出不穷可一到自己动手面对一个具体的任务比如让模型分析用户情绪、从长文档里提取关键信息或者进行多步骤的逻辑判断却不知道从哪里开始构建提示词最后要么模型答非所问要么输出一堆没用的废话。这就是典型的“知道概念但不会实操”。本文要解决的正是这个核心痛点。我们不空谈“推理”的宏大意义而是聚焦于三个最实用、最高频的推理任务场景为你提供可以直接“抄作业”的解决方案。这三个任务分别是情感分析如何让模型不仅判断“正面”或“负面”还能理解更细腻的情绪如“失望”、“期待”、“讽刺”。信息提取如何从一篇杂乱的长文如新闻、报告、用户反馈中精准、结构化地抽取出我们关心的特定信息。逻辑链推理如何引导模型像人一样进行多步骤的思考解决需要常识和分步推导的问题例如“如果明天下雨比赛取消如果比赛取消门票退款。今天预报明天有雨那么门票会退款吗”。读完本文你将获得对这三种推理任务本质的清晰理解知道它们分别解决什么问题。三套经过验证的、可直接复用的提示词Prompt模板与调用代码。了解每种方法的局限性、常见“翻车”场景以及如何优化。获得举一反三的能力能够将这些模式应用到自己的业务场景中。2. 基础概念什么是大语言模型的“推理”在讨论具体任务前我们需要统一认识。在AI和大语言模型的语境下“推理”并非指模型像人类一样进行真正的逻辑思考。它更像是一种基于海量文本数据训练出的、强大的“模式匹配”与“信息关联”能力。你可以把它想象成一个超级“文本补全专家”。当你给它一段输入提示词它会根据训练时见过的无数类似文本模式预测出最可能、最合理的后续文字。我们设计的提示词本质上是在“引导”模型激活我们想要的那种“文本模式”。因此“推理任务”的成功90%取决于提示词的设计。好的提示词能清晰地定义任务、提供范例、约束输出格式从而让模型的“模式匹配”能力为我们所用。而糟糕的提示词则会让模型陷入混乱产生无关或错误的输出。下面这个表格对比了三种推理任务的核心差异任务类型核心目标输入特点理想输出类比情感分析识别并分类文本中的主观情绪和态度。一段带有感情色彩的文本如评论、微博、客服对话。结构化的情感标签如积极/消极/中立或更细的维度如喜悦、愤怒、失望。像一位经验丰富的心理咨询师或产品经理快速读懂文字背后的情绪。信息提取从非结构化文本中抽取出结构化的、预定义的信息片段。长文档、报告、文章等包含大量信息的文本。一个结构化的列表、JSON对象或表格包含特定字段如人名、时间、事件、金额。像一位高效的数据录入员或情报分析员从海量文字中精准抓取关键数据点。逻辑链推理基于给定的信息和规则进行多步推导得出结论或解决需要思考的问题。一个包含事实、条件和问题的描述。一个清晰的结论通常伴随简短的推导步骤思考链。像一位遵循规则下棋的棋手或者解答数学应用题的学生一步步推导出答案。理解了这些我们就可以进入实战环节了。3. 环境准备与前置条件在开始“抄答案”之前你需要准备好“纸和笔”。这里纸笔就是你的开发环境。1. 基础环境Python 3.8这是与大多数AI库兼容的版本。可以在终端输入python --version或python3 --version检查。pipPython的包管理工具通常随Python安装。2. 关键依赖库我们将使用openai这个官方库来调用模型例如GPT-3.5/4同时用json和pydantic来更好地处理结构化输出。通过以下命令安装pip install openai pydantic3. 获取API密钥你需要一个OpenAI的账户并创建API密钥。访问 OpenAI平台 创建。请务必妥善保管你的密钥不要直接硬编码在代码中或上传到公开仓库。4. 设置环境变量推荐方式将你的API密钥设置为环境变量这是最安全、最方便的做法。在Linux/macOS的终端或Windows的PowerShell中临时设置# Linux/macOS export OPENAI_API_KEY你的-api-key-here # Windows (PowerShell) $env:OPENAI_API_KEY你的-api-key-here更持久的方法是将其添加到你的 shell 配置文件如~/.bashrc,~/.zshrc或系统环境变量中。5. 选择模型本文示例将使用gpt-3.5-turbo因为它性价比高足以完成这些推理任务。如果你有权限和预算gpt-4或gpt-4-turbo在复杂逻辑推理上表现会更出色。你可以在代码中轻松切换模型名称。4. 任务一情感分析——从“粗糙”到“细腻”基础的情感分析正面/负面/中立已经很简单。但实际业务中我们往往需要更细的颗粒度。比如客服系统需要区分用户是“愤怒”还是“失望”以分配不同的处理优先级产品反馈需要识别出用户是“期待新功能”还是“对现有功能满意”。核心思路我们不直接问“这是什么情绪”而是通过“少样本学习”和“结构化输出”来引导模型。1. 基础版三分类情感分析import openai import os from pydantic import BaseModel from typing import Literal # 假设你已经通过环境变量设置了 OPENAI_API_KEY client openai.OpenAI() class Sentiment(BaseModel): sentiment: Literal[positive, negative, neutral] confidence: float # 置信度0到1之间 key_phrases: list[str] # 支撑该情感判断的关键短语 def analyze_sentiment_basic(text: str) - Sentiment: prompt f 请分析以下文本的情感倾向。 文本{text} 请严格按照以下JSON格式输出不要有任何其他解释 {{ sentiment: positive, negative, 或 neutral, confidence: 一个0到1之间的浮点数, key_phrases: [支撑判断的短语1, 短语2] }} response client.chat.completions.create( modelgpt-3.5-turbo, messages[{role: user, content: prompt}], temperature0.1, # 低温度输出更确定、更一致 ) # 解析返回的JSON字符串 import json result json.loads(response.choices[0].message.content) return Sentiment(**result) # 测试 if __name__ __main__: test_text “这款手机的屏幕真是太惊艳了续航也不错就是价格有点高。” result analyze_sentiment_basic(test_text) print(f情感: {result.sentiment}) print(f置信度: {result.confidence:.2f}) print(f关键短语: {result.key_phrases})代码解释我们定义了一个Sentiment数据类来规范输出。提示词明确要求了任务和输出格式。temperature0.1使输出更稳定适合需要确定结果的分类任务。模型会返回一个JSON字符串我们将其解析为Sentiment对象。2. 进阶版细粒度情感分析当三分类不够用时我们需要给模型更具体的选项。from typing import Literal # 定义更细的情感标签 FineGrainedSentiment Literal[ “joy”, “gratitude”, “expectation”, # 积极类 “anger”, “disappointment”, “frustration”, # 消极类 “neutral”, “confusion”, “sarcasm” # 中性及其他复杂类 ] class FineSentiment(BaseModel): primary_sentiment: FineGrainedSentiment secondary_sentiment: FineGrainedSentiment | None # 次要情绪可能没有 reasoning: str # 模型做出判断的简要理由 def analyze_sentiment_fine(text: str) - FineSentiment: prompt f 你是一个情感分析专家。请分析以下文本中蕴含的深层情感。 可供选择的情感标签包括 - 积极类joy喜悦, gratitude感激, expectation期待 - 消极类anger愤怒, disappointment失望, frustration沮丧 - 其他neutral中性, confusion困惑, sarcasm讽刺 文本{text} 请逐步思考 1. 文本中表达了哪些情绪 2. 哪种情绪是主导的 3. 是否有次要情绪 最后请严格按照以下JSON格式输出 {{ “primary_sentiment”: “从上述列表中选择一个主导情感标签”, “secondary_sentiment”: “从上述列表中选择一个次要情感标签如果没有则填null”, “reasoning”: “你的思考过程简短说明” }} response client.chat.completions.create( model“gpt-3.5-turbo”, messages[{“role”: “user”, “content”: prompt}], temperature0.3, # 稍高的温度允许一点灵活性来捕捉复杂情绪 ) import json result json.loads(response.choices[0].message.content) # 处理可能的null if result[“secondary_sentiment”] “null”: result[“secondary_sentiment”] None return FineSentiment(**result) # 测试复杂文本 if __name__ “__main__”: test_texts [ “说好的月底更新这都月中了连个影子都没见真是服了。失望” “哈哈你这方案可真是‘天才’居然能想到用这么复杂的方法解决一个简单问题。讽刺” ] for txt in test_texts: result analyze_sentiment_fine(txt) print(f“文本: {txt}”) print(f“主要情绪: {result.primary_sentiment}”) print(f“次要情绪: {result.secondary_sentiment}”) print(f“理由: {result.reasoning}\n”)设计要点提供选项直接给出情感标签列表限制模型“胡思乱想”。引导思考链通过“请逐步思考”引导模型内部推理这通常能提升最终判断的准确性。输出理由要求输出reasoning字段这不仅让结果更可信也便于我们调试和改进提示词。5. 任务二信息提取——把非结构化文本变成结构化数据从一篇产品发布会新闻稿里提取所有提到的产品名称和核心卖点或者从一堆用户访谈记录中提取所有的“痛点”和“需求”手工做起来费时费力。用大模型自动化提取关键在于定义清晰的结构。核心思路使用 Pydantic 模型来严格定义我们希望提取的数据结构然后通过函数调用Function Calling或结构化输出Structured Outputs让模型直接返回填充好的对象。1. 定义数据结构假设我们要从科技新闻中提取实体信息。from pydantic import BaseModel, Field from typing import List, Optional from datetime import date class Company(BaseModel): name: str Field(description“公司全称”) mentioned_as: str Field(description“在文中被提及的角色如‘发布者’、‘合作方’、‘竞争对手’”) class Product(BaseModel): name: str Field(description“产品名称”) category: Optional[str] Field(defaultNone, description“产品类别如‘智能手机’、‘AI芯片’”) key_feature: List[str] Field(description“文中提到的核心特性或卖点列表”) class NewsExtraction(BaseModel): 从科技新闻中提取的结构化信息 main_topic: str Field(description“新闻的核心主题”) companies: List[Company] Field(description“文中提到的公司列表”) products: List[Product] Field(description“文中提到的产品列表”) release_date: Optional[date] Field(defaultNone, description“如有产品发布日期请提取”) summary: str Field(description“对新闻内容的简要总结不超过100字”)2. 执行信息提取我们使用OpenAI API的response_format参数来请求结构化JSON输出注意此功能对模型版本有要求如gpt-4-turbo-preview。def extract_news_info(news_text: str) - NewsExtraction: prompt f 请从以下科技新闻中提取关键的结构化信息。 新闻内容 “{news_text}” 请仔细阅读并提取出所有相关的公司、产品、日期等信息。 try: # 注意结构化输出需要特定模型支持如 gpt-4-turbo-preview # 如果使用 gpt-3.5-turbo可能需要通过函数调用或提示词约束JSON格式来实现 response client.beta.chat.completions.parse( model“gpt-4-turbo-preview”, # 使用支持 .parse() 的模型 messages[{“role”: “user”, “content”: prompt}], response_formatNewsExtraction, # 直接传入Pydantic模型 ) extracted_data response.choices[0].message.parsed return extracted_data except Exception as e: # 降级方案使用传统提示词JSON解析 print(f“使用结构化输出时出错降级为传统方式: {e}”) return _extract_fallback(news_text) def _extract_fallback(news_text: str) - NewsExtraction: 降级方案通过强提示词要求JSON输出 prompt f 请从以下科技新闻中提取关键信息并严格按照给定的JSON格式输出不要有任何其他文字。 需要的JSON结构如下 {{ “main_topic”: “新闻核心主题”, “companies”: [{{“name”: “公司名”, “mentioned_as”: “角色”}}], “products”: [{{“name”: “产品名”, “category”: “类别”, “key_feature”: [“特性1”, “特性2”]}}], “release_date”: “YYYY-MM-DD 或 null”, “summary”: “简要总结” }} 新闻内容 “{news_text}” response client.chat.completions.create( model“gpt-3.5-turbo”, messages[{“role”: “user”, “content”: prompt}], temperature0, ) import json raw_output response.choices[0].message.content # 清理输出确保是纯JSON json_str raw_output.strip().strip(“”).replace(“json\n”, “”) data_dict json.loads(json_str) # 将日期字符串转换为date对象如果存在 if data_dict[“release_date”]: data_dict[“release_date”] date.fromisoformat(data_dict[“release_date”]) return NewsExtraction(**data_dict) # 测试 if __name__ “__main__”: sample_news “”” 在今日举行的春季发布会上科技巨头深蓝公司正式推出了其新一代人工智能芯片‘星云N100’。 该芯片主打高能效比采用5nm制程专为大规模数据中心和边缘计算场景设计。 同时深蓝公司宣布与云计算服务商腾云科技达成战略合作腾云科技将首批部署基于‘星云N100’的AI算力集群。 竞争对手星河科技对此未予置评。新产品预计将于2024年第三季度正式上市。 “”” result extract_news_info(sample_news) print(f“核心主题: {result.main_topic}”) print(f“涉及公司:”) for comp in result.companies: print(f“ - {comp.name} ({comp.mentioned_as})”) print(f“涉及产品:”) for prod in result.products: print(f“ - {prod.name} [{prod.category}] 特性: {‘ ‘.join(prod.key_feature)}”) print(f“发布日期: {result.release_date}”) print(f“总结: {result.summary}”)关键点结构化定义先行先用Pydantic清晰定义你要什么字段含义是什么。这本身就是一种给模型的强约束。利用高级特性优先使用API提供的原生结构化输出功能如.parse()它更稳定、格式错误更少。准备降级方案考虑到模型版本和API更新准备一个通过提示词强约束JSON格式的备选方案是工程上的最佳实践。后处理对提取出的日期、数字等字段进行必要的格式转换和验证。6. 任务三逻辑链推理——让模型“一步一步想”对于需要多步推理的问题直接提问“零样本”往往得到的是错误答案。因为模型可能会跳过中间步骤直接匹配一个看似合理的最终答案。解决方案是“思维链”提示。核心思路在提示词中明确要求模型“逐步推理”或者提供几个“逐步推理”的例子少样本学习强制模型展示其思考过程。1. 零样本思维链通过指令要求模型展示步骤。def chain_of_thought_zero_shot(question: str) - str: prompt f 请解答以下问题。请确保逐步展示你的推理过程最后给出最终答案。 问题{question} 让我们一步一步思考。 response client.chat.completions.create( model“gpt-3.5-turbo”, messages[{“role”: “user”, “content”: prompt}], temperature0, ) return response.choices[0].message.content # 测试一个逻辑问题 logic_question “”” 书架上有三层。中层比上层多5本书下层比中层多3本书。 已知下层有20本书请问上层有多少本书 “”” print(chain_of_thought_zero_shot(logic_question))输出示例已知下层有20本书。下层比中层多3本书所以中层有 20 - 3 17 本书。中层比上层多5本书所以上层有 17 - 5 12 本书。最终答案上层有12本书。2. 少样本思维链对于一些更复杂或容易出错的推理模式提供一两个例子效果更好。def chain_of_thought_few_shot(question: str) - str: prompt f 请根据示例的推理方式解答下面的问题。 示例1 问题一个篮子里有一些苹果。小明拿走了三分之一然后小红又拿走了剩下的苹果的一半。最后篮子里还剩4个苹果。最初篮子里有多少苹果 推理设最初有X个苹果。 小明拿走三分之一后剩下 (2/3)X 个。 小红拿走剩下的一半后还剩 (1/2) * (2/3)X (1/3)X 个。 已知最后剩4个所以 (1/3)X 4。 解得 X 12。 答案最初有12个苹果。 示例2 问题如果所有机器人都是高效的并且有些助手是机器人那么是否有些助手是高效的 推理前提1所有机器人都是高效的。 前提2有些助手是机器人。 从前提2可知存在至少一个助手它是机器人。 根据前提1这个助手因为是机器人是高效的。 因此存在至少一个助手是高效的。 答案是的有些助手是高效的。 现在请解答以下问题并严格按照“推理... 答案...”的格式输出。 问题{question} response client.chat.completions.create( model“gpt-3.5-turbo”, messages[{“role”: “user”, “content”: prompt}], temperature0, ) return response.choices[0].message.content # 测试一个混合了数学和逻辑的问题 complex_question “”” 运动会上参加百米赛跑的有30人参加跳远的有25人两项都参加的有8人。 请问只参加了一项比赛的学生有多少人 “”” print(chain_of_thought_few_shot(complex_question))设计要点示例质量提供的例子必须清晰、正确并且与目标问题的推理类型相似。格式一致要求模型按照示例的格式输出便于后续程序化解析“答案”部分。适用场景思维链特别适用于数学应用题、逻辑推理、常识推理等需要多步推导的问题。7. 运行结果与效果验证运行上述代码你应该能得到结构化的输出。验证效果时不要只看单个例子是否成功而要进行系统性的评估功能验证针对每个任务准备5-10个具有代表性的测试用例。情感分析包含明确情感、混合情感、讽刺、中性等不同维度的文本。信息提取包含不同长度、不同结构、信息密度各异的文本。逻辑推理包含不同难度等级的逻辑和数学问题。准确性检查人工核对模型的输出是否符合预期。对于情感和信息提取可以计算准确率、召回率等指标如果已有标注数据。格式验证确保输出能被程序正确解析没有JSON格式错误、字段缺失或类型不匹配。边界测试输入空文本、极端长的文本、完全不相关的文本观察模型的反应和错误处理机制是否健壮。一个简单的验证脚本框架def validate_extraction(): test_cases [ { “input”: “测试新闻文本1...”, “expected_topic”: “预期的主题”, “expected_companies_count”: 2 }, # ... 更多测试用例 ] for i, tc in enumerate(test_cases): result extract_news_info(tc[“input”]) # 进行断言或比较 assert result.main_topic tc[“expected_topic”], f“用例{i}主题不匹配” assert len(result.companies) tc[“expected_companies_count”], f“用例{i}公司数量不匹配” print(f“用例{i} 通过”)8. 常见问题与排查思路在实际使用中你可能会遇到以下问题问题现象可能原因排查方式解决方案API调用失败返回认证错误API密钥未设置或错误密钥余额不足。1. 检查环境变量OPENAI_API_KEY是否正确设置。2. 登录OpenAI平台检查密钥状态和余额。1. 重新设置正确的环境变量。2. 充值或更换密钥。模型输出格式不符合预期不是JSON提示词中对输出格式的约束不够强模型未遵循指令。1. 检查提示词中是否明确要求了JSON格式并提供了示例。2. 检查temperature参数是否过高建议分类任务设为0-0.3。1. 强化提示词使用“请严格按照以下JSON格式输出不要有任何其他解释”等指令。2. 使用response_format{ “type”: “json_object” }参数部分模型支持。3. 使用前文提到的client.beta.chat.completions.parse方法。信息提取时漏掉或错提了实体提示词中对实体的定义不够清晰文本过于复杂或模糊。1. 检查Pydantic模型中的字段描述是否精准。2. 用一个简单文本测试看是否是复杂文本导致的问题。1. 优化字段的description使其更无歧义。2. 尝试将复杂任务分解先让模型总结段落再从总结中提取。3. 考虑使用更强大的模型如GPT-4。逻辑推理答案错误模型进行了“直觉跳跃”没有执行逐步推理。检查输出是否包含了“逐步思考”的过程。1. 务必在提示词中加入“让我们一步一步思考”或“请展示你的推理步骤”等指令。2. 使用“少样本学习”提供1-2个正确的推理示例。处理长文本时超时或丢失信息输入文本超过了模型的上下文窗口限制。确认输入文本的长度字符数/Token数。1. 对长文本进行分割分别处理后再合并结果。2. 使用具有更长上下文窗口的模型如gpt-4-turbo支持128K。3. 先让模型对长文进行摘要再从摘要中提取关键信息。代码解析JSON时出错模型输出包含了非JSON的标记如json或解释性文字。打印出模型的原始输出raw_output进行检查。在解析前对输出进行清洗json_str raw_output.strip().strip(‘’).replace(‘json\n’, ‘’)9. 最佳实践与工程建议将这三个“推理答案”应用到生产环境或严肃项目中还需要注意以下几点提示词工程是迭代过程不要指望一次写出完美的提示词。根据测试结果不断调整你的指令、示例和格式要求。将有效的提示词版本化管理起来。温度参数的权衡低温度0-0.3适合分类、提取、事实问答等需要确定性和一致性的任务。本文中的任务大多适用。高温度0.7-1.0适合创意写作、头脑风暴、生成多样化内容。结构化输出优先只要模型支持尽量使用官方的结构化输出功能。它比用文本提示约束JSON更可靠并能利用模型的底层能力。添加验证与后处理永远不要完全信任模型的原始输出。对于提取出的日期、数字、分类标签添加逻辑验证。例如检查日期是否合理数字是否在预期范围内情感标签是否在允许的列表中。考虑成本与延迟gpt-3.5-turbo成本低、速度快适合大多数简单到中等复杂度的推理。gpt-4系列更聪明、更守指令但成本高、速度慢。根据任务关键性和对准确性的要求做选择。构建评估体系建立一个小型的黄金测试集定期运行你的提示词监控其性能变化。这能帮你发现模型更新或业务数据变化带来的影响。异常处理与降级在你的代码中必须对API调用失败、网络超时、输出解析失败等情况进行妥善处理。例如前文代码中的try...except块和_extract_fallback函数就是一种降级策略。关注数据隐私与安全切勿向模型发送敏感个人信息、公司机密或受监管数据。了解你所使用模型的数据处理政策。掌握了情感分析、信息提取和逻辑链推理这三个核心模式你就已经能够解决大语言模型应用中一大部分的实际问题。真正的关键不在于记住这些具体的提示词而在于理解其背后的设计模式用清晰的结构定义任务用巧妙的提示引导模型用严谨的程序处理输出。你可以将这些模式组合使用。例如先对用户反馈做细粒度情感分析再从中提取具体的产品功能和问题描述最后判断这些问题是否需要复杂的逻辑流程来处理。下一步你可以探索更高级的推理技术如“自我验证”、“思维树”或者将这些能力嵌入到你的应用程序中构建一个能够理解、分析和推理用户需求的智能助手。
返回列表