1. 项目概述从概念到实践的AI应用新范式最近和不少同行交流发现一个挺有意思的现象大家聊起AI大模型已经从最初的“ChatGPT真牛”的惊叹逐渐转向了更实际的问题——“这东西到底怎么用起来才能真帮我们干活” 这背后反映的正是整个行业从技术尝鲜到价值落地的关键转折。今天我想聊的就是这个“用起来”的核心三角大模型LLM、智能体Agent和提示词Prompt。这不仅仅是三个时髦的术语更是构建下一代AI应用的基础架构。简单来说你可以把这三者的关系想象成一次精密的太空任务。大模型LLM是那台功能强大的主控计算机它拥有海量的知识库和强大的推理能力是任务的“大脑”。智能体Agent则是搭载了这台计算机的航天器它具备感知环境读取文件、调用API、自主规划拆解任务步骤、执行动作写代码、发邮件并持续学习的能力是任务的“执行体”。而提示词Prompt就是地面控制中心发送给航天器的精确指令集。指令写得模糊不清“去探索火星”航天器可能原地打转指令写得精准、结构化“启动推进器调整轨道至环绕火星的极地轨道启动高分辨率相机对预定区域进行拍摄”才能引导大脑和执行体协同完成既定目标。所以这个“走进”系列目的不是复述教科书定义而是想结合我过去一年多在多个项目中趟过的坑、积累的经验和你一起拆解如何将这三个概念组合起来解决真实世界的问题。无论是想自动化处理周报、搭建一个智能客服原型还是开发一个能理解业务逻辑并自动生成SQL的数据分析助手其内核都离不开这三者的协同。接下来我们就从设计思路开始一步步拆解这个“铁三角”是如何工作的。2. 核心三角解析LLM、Agent与Prompt的协同逻辑2.1 大模型LLM能力基石与固有局限大模型特别是像GPT-4、Claude 3、国内的一些主流模型已经展现出了令人惊叹的通用知识、逻辑推理和内容生成能力。它是整个智能应用的“基座”。但在实战中我们必须清醒地认识到它的几个核心局限这直接决定了我们如何设计Agent和Prompt。第一知识的时效性与私有性。大模型的训练数据有截止日期它不知道今天早上发布的新闻也不知道你公司内部那套独特的客户数据库Schema。第二缺乏“行动”能力。模型可以告诉你“如何发送一封邮件”但它自己无法调用你的邮箱API。它是一位博学的顾问而非一个能动手的操作员。第三存在“幻觉”。模型可能会以极其自信的口吻编造看似合理但完全错误的信息比如生成一个不存在的函数名或引用一篇虚构的论文。注意因此在架构设计上我们绝不能期望用一个“超级提示词”让LLM解决所有问题。正确的思路是让LLM专注于它最擅长的“思考”和“规划”而将知识检索、工具调用、结果验证等“行动”部分交给Agent框架来统筹。2.2 智能体Agent从思考到行动的桥梁智能体是赋予大模型“手”和“脚”的框架。它的核心工作流通常遵循一个循环感知Perception - 规划Planning - 执行Action - 观察Observation。感知Agent接收用户的初始请求可能是自然语言也可能是结构化数据并结合上下文如之前的对话历史、加载的文档形成当前的任务理解。规划这是LLM大显身手的地方。Agent会将当前状态用户目标、可用工具、历史记录组织成一个清晰的提示Prompt提交给LLM。LLM的任务是输出一个“计划”这个计划可能是一系列步骤也可能是下一步该调用哪个工具。例如面对问题“帮我分析一下上季度销售数据TOP10的客户特征”LLM规划的输出可能是“步骤1连接数据库。步骤2执行查询SQL获取上季度销售额排名前10的客户ID及销售额。步骤3根据客户ID查询客户明细表获取客户行业、规模、区域等特征。步骤4对特征进行归纳总结形成报告。”执行Agent根据LLM的规划调用相应的工具Tool来执行。工具可以是执行一段Python代码、调用一个外部API如发送邮件、查询数据库、读取本地文件、甚至操作浏览器。观察Agent获取工具执行的结果可能是数据、成功/失败状态、错误信息并将这个结果作为新的“观察”反馈给LLM进入下一轮“规划-执行”循环直到任务被判定为完成或无法继续。目前主流的Agent框架如LangChain、LlamaIndex、AutoGen以及新兴的CrewAI等都在不同程度上实现了这个范式。它们提供了工具集成的标准接口、记忆管理、以及和不同LLM API的对接。2.3 提示词Prompt精准操控模型的“编程语言”如果把LLM比作一个功能强大但接口古怪的芯片那么Prompt Engineering就是为这个芯片编写微指令。它的目标是将人类模糊的意图转化为模型能稳定、准确理解的指令。在Agent场景下Prompt的设计尤为关键因为它直接决定了规划的质量。一个用于Agent规划的Prompt通常包含以下几个部分角色Role与目标Goal明确告诉模型“你是谁”以及“你要完成什么”。例如“你是一个资深数据分析师擅长通过编写精确的SQL查询来获取业务洞察。”约束Constraints设定边界防止模型天马行空。例如“你只能使用query_database_tool这个工具来执行查询。绝对不能假设任何数据库中不存在的表或字段。”工具描述Tools Description清晰定义Agent可以使用的工具列表、每个工具的用途、输入参数和输出格式。这是模型进行规划的依据。输出格式Output Format严格要求模型以特定格式如JSON、特定的思考链格式输出它的“思考过程”和“下一步行动”。这对于Agent框架稳定解析结果至关重要。示例Few-Shot Examples提供一两个“用户提问 - Agent思考过程 - 工具调用”的完整示例能极大提高模型输出的稳定性和准确性。实操心得很多人把Prompt简单理解为“把问题描述清楚”但在Agent中这远远不够。你需要像设计一个API接口文档一样设计你的Prompt考虑所有可能的输入、处理逻辑和输出规范。一个松散的Prompt会导致Agent行为不可预测时而成功时而失败一个严谨的Prompt则能让Agent像一段可靠的程序一样运行。3. 实战构建从零搭建一个数据分析智能体理论说得再多不如动手建一个。我们以构建一个“自然语言转SQL查询的数据库分析Agent”为例来串联整个流程。这个场景非常典型用户用中文提问Agent需要理解问题规划出查询步骤生成正确的SQL执行并返回结果。3.1 环境准备与工具选型首先我们需要选择技术栈。这里我以目前生态最成熟、文档最丰富的LangChain框架为例结合OpenAI GPT-4模型你也可以替换为国内通过API兼容的模型如通义千问、文心一言等数据库使用SQLite做演示。1. 安装核心依赖pip install langchain langchain-openai langchain-community sqlalchemylangchain: 核心框架。langchain-openai: 官方维护的OpenAI模型集成。langchain-community: 包含大量社区贡献的工具和组件如数据库连接工具。sqlalchemy: Python的SQL工具包和对象关系映射器LangChain通过它连接各种数据库。2. 准备示例数据库我们创建一个简单的sales.db文件包含两张表customers表:customer_id(主键),name,industry,region,employee_count。orders表:order_id,customer_id,order_date,amount。并插入一些模拟数据。3. 设置API密钥在你的环境变量或代码中设置OpenAI API密钥。import os os.environ[OPENAI_API_KEY] 你的-api-key3.2 构建核心Agent工具定义与提示词工程这是最核心的部分。我们将创建一个具备“数据库查询”单一工具的Agent。步骤1创建数据库连接工具from langchain_community.utilities import SQLDatabase from langchain_community.tools import QuerySQLDataBaseTool # 连接SQLite数据库 db SQLDatabase.from_uri(sqlite:///sales.db) # 创建查询工具实例 query_tool QuerySQLDataBaseTool(dbdb)这个query_tool就是一个标准的LangChain Tool它有一个run方法接收一个SQL字符串作为输入执行并返回结果。步骤2设计专属的Agent提示词模板这是成败的关键。我们不能用通用的聊天提示词必须为“数据库分析”这个任务定制。from langchain.prompts import PromptTemplate # 定义系统提示词模板 system_template 你是一个专业的SQL数据分析助手。你的职责是根据用户的问题编写准确、高效的SQL查询语句来获取答案。 ## 数据库Schema信息 {customers_schema} {orders_schema} ## 你必须遵守的规则 1. **绝对优先使用已提供的工具**你只能使用名为query_sql_db的工具来执行查询。不要尝试自己计算或猜测数据。 2. **严格验证查询可行性**在生成SQL前仔细对照Schema确保引用的表名、字段名完全正确。如果用户问题中提到的概念在Schema中没有直接对应你需要通过逻辑推理找到关联字段例如“销售额”可能对应orders.amount的求和。 3. **输出格式必须严格遵循以下JSON格式** {{ thought: 你的逐步推理过程解释你将如何解决问题为什么选择这样的SQL。, sql: 你生成的、准备交给工具执行的SQL语句。, action: query_sql_db // 固定为此值表示下一步动作是调用查询工具 }} 4. 如果用户的问题无法通过查询数据库回答或者信息不足请在thought中清晰说明原因并将sql设为nullaction设为final_answer。 ## 开始任务 用户问题{input} # 获取真实的Schema信息动态填入模板 customers_schema db.get_table_info(table_names[customers]) orders_schema db.get_table_info(table_names[orders]) # 创建PromptTemplate对象 prompt_template PromptTemplate.from_template( system_template, partial_variables{ customers_schema: customers_schema, orders_schema: orders_schema } )这个提示词模板做了几件关键事明确了角色和上下文告诉模型它是SQL专家并提供了具体的数据库表结构。设定了强硬约束强制要求使用工具避免了模型空想。规定了结构化输出要求模型以特定JSON格式输出这便于后续的Agent框架解析。thought字段对于调试和理解Agent的“思路”至关重要。处理了边界情况定义了当问题无法回答时的输出规范。步骤3组装Agent在LangChain中我们可以使用create_react_agentReAct范式来快速构建。from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain.agents.format_scratchpad import format_log_to_str from langchain.agents.output_parsers import ReActSingleInputOutputParser # 1. 初始化大模型 llm ChatOpenAI(modelgpt-4, temperature0) # temperature设为0减少随机性 # 2. 定义工具列表 tools [query_tool] tool_names [tool.name for tool in tools] # 3. 构建Agent的完整提示词将系统提示和用户输入结合 agent_prompt prompt_template.partial( tool_namesstr(tool_names), tools_description\n.join([f{tool.name}: {tool.description} for tool in tools]) ) # 4. 创建Agent agent create_react_agent(llm, tools, agent_prompt) # 5. 创建Agent执行器它负责运行循环 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 开启详细日志方便调试 handle_parsing_errorsTrue, # 优雅处理解析错误 max_iterations5 # 防止死循环限制最大迭代次数 )3.3 运行测试与结果分析现在让我们用几个问题来测试这个Agent。测试1简单聚合查询result agent_executor.invoke({ input: 上季度总销售额是多少 }) print(result[output])预期行为Agent的thought会推理“上季度”需要计算日期范围然后生成类似SELECT SUM(amount) FROM orders WHERE order_date BETWEEN 2024-01-01 AND 2024-03-31的SQL。观察日志当verboseTrue时你会在控制台看到完整的ReAct循环日志包括LLM的思考、决定调用的工具、工具返回的结果。这是学习和调试Agent的黄金资料。测试2涉及多表关联的复杂查询result agent_executor.invoke({ input: 找出消费金额最高的前3个客户所在的行业和区域。 })预期行为模型需要规划出“先关联orders和customers表按客户分组汇总金额排序取前三最后投影出行业和区域字段”的步骤。生成的SQL会包含JOIN、GROUP BY、SUM和ORDER BY ... LIMIT。测试3存在歧义或信息不足的查询result agent_executor.invoke({ input: 分析一下我们的金牌客户。 })预期行为由于Schema中没有“金牌客户”的定义一个好的Agent应该在thought中明确指出“‘金牌客户’的定义不明确。数据库中可能通过customer_type字段或total_amount阈值来区分。需要用户澄清。” 然后输出sql: null, action: final_answer并将上述思考作为最终答案返回给用户。这体现了Agent的“自知之明”和与用户交互的能力。实操心得在测试阶段一定要开启verboseTrue。通过观察LLM在每一步收到的提示词和它的输出你能精准定位问题所在是提示词描述不清是工具定义有误还是模型本身逻辑混乱绝大多数Agent的故障都源于提示词或工具定义的瑕疵而非模型能力不足。4. 进阶优化与模式扩展一个基础的Agent跑起来只是第一步。要让它在生产环境中可靠工作还需要考虑以下进阶问题。4.1 处理复杂任务规划与子任务分解对于“帮我写一份上季度销售分析报告包括趋势、客户排名和区域对比”这样的复杂请求单次查询无法完成。这时需要引入更强大的规划能力。我们可以升级Agent使其能够生成一个包含多个子任务的计划。例如使用LangChain 的 Plan-and-Execute 模式或CrewAI 的多智能体协作框架。思路如下规划智能体Planner接收用户复杂请求利用LLM将其分解为一系列顺序或并行的子任务。例如子任务1查询上季度每月销售趋势数据。子任务2查询消费额排名前10的客户名单及详情。子任务3查询各区域的销售额对比。子任务4将以上数据整合生成一份结构化的中文分析报告。执行智能体Executor接收规划好的子任务列表逐个调用相应的工具如数据库查询工具、报告生成工具来完成。协调者Coordinator管理任务之间的依赖关系如任务2和3可以并行任务4必须等前三个都完成并汇总最终结果。这种模式将“宏观规划”和“微观执行”分离让LLM在更高层次上思考问题结构大大提升了处理复杂任务的可靠性和逻辑性。4.2 增强可靠性记忆、验证与错误处理短期记忆与长期记忆短期记忆ConversationBufferMemory让Agent能记住当前对话轮次内的上下文实现多轮交互。例如用户问“销售额趋势如何”接着问“和去年同期比呢”Agent需要记住“销售额”指的是哪个指标、哪个时间范围。长期记忆VectorStore Retriever将历史对话、项目文档、知识库向量化存储。当用户提问时先从中检索相关片段作为上下文注入提示词。这有效解决了LLM私有知识缺失和遗忘的问题。结果验证与安全护栏让Agent盲目执行生成的SQL是危险的。必须加入验证层。SQL语法预检查在执行前可以用一个轻量级库如sqlparse或尝试EXPLAIN命令来检查SQL基本语法。敏感操作拦截在工具层面定义规则禁止执行DROP、DELETE、UPDATE等写操作或者对涉及大量数据扫描的查询进行资源限制。结果后验证对查询返回的数据进行合理性检查。例如如果查询“平均订单金额”返回的结果是一个天文数字Agent应该能标记此结果异常并在最终输出中附加警告。错误处理与重试机制数据库查询可能因网络、锁、语法错误而失败。一个健壮的Agent不应就此崩溃。结构化错误捕获在工具调用层捕获异常。LLM辅助诊断将错误信息如SQLite错误“no such column: xxx”反馈给LLM让它重新分析问题并修正SQL。有限次重试设定一个重试次数如3次避免陷入死循环。4.3 提示词迭代与评估体系构建Agent是一个高度迭代的过程。你需要建立一个科学的提示词评估和优化流程。构建测试集Test Suite收集一批具有代表性的用户问题Q以及对应的、期望的Agent正确行为A或SQL语句S。覆盖简单查询、复杂关联、歧义问题、边界情况等。批量运行与评估编写脚本用测试集批量运行你的Agent。评估指标可以包括SQL生成准确率生成的SQL在语法和语义上是否与期望SQL等价。任务完成率Agent是否最终给出了正确答案。工具调用效率是否以最少的工具调用次数解决了问题。分析失败案例这是提升的关键。仔细查看失败案例中LLM的思考日志thought。是提示词中对工具的描述不够清晰是约束条件没写明白导致模型“越狱”还是缺少必要的示例Few-Shot导致模型不理解复杂意图迭代优化提示词根据分析结果有针对性地修改提示词模板。例如增加针对某一类错误的纠正示例或者强化某一条约束的表述。5. 常见陷阱与避坑指南在开发和部署LLM Agent的过程中我踩过不少坑这里总结几个最具代表性的希望能帮你省点时间。陷阱一过度依赖LLM的“智能”忽视精确的工程约束。现象Agent经常生成不在Schema中的字段名或试图进行无法实现的计算。根因提示词中只是简单说“请根据数据库Schema查询”没有以强硬、结构化的方式比如用“你必须”“你只能”这样的措辞把约束写死。解决方案在提示词中将数据库Schema以CREATE TABLE语句的形式清晰列出。并使用类似“在生成SQL前你必须逐一核对以下字段是否存在于上述表中”这样的指令强制模型进行自查。陷阱二工具Tool定义模糊不清。现象Agent知道该做什么但调用工具时参数格式总是出错。根因传递给LLM的工具描述过于简略。LLM需要精确知道工具的名称、功能、输入参数的名称、类型和含义。解决方案利用LangChain等框架的Tool类认真填写name、description和args_schema参数模式。description要写得像一份简明的API文档说明输入是什么输出是什么。陷阱三忽视上下文管理与Token消耗。现象对话进行到后面Agent“忘记”了之前的内容或者API调用因Token超限而失败。根因没有合理管理对话历史。将整个冗长的历史记录都塞进每次请求的上下文导致Token数暴涨、成本升高、且可能触及模型上下文长度上限。解决方案使用ConversationSummaryMemory或ConversationBufferWindowMemory。前者会定期让LLM总结之前的对话用摘要代替原文后者只保留最近N轮对话。对于知识库使用检索Retrieval方式只注入与当前问题最相关的片段而不是全部知识库内容。陷阱四缺乏有效的“停止”和“超时”机制。现象Agent陷入“思考-调用-得到错误-再思考”的死循环或者在一个简单问题上花费过长时间。根因没有设置max_iterations最大迭代次数和max_execution_time最大执行时间。解决方案在AgentExecutor中务必设置这些安全阀。一个常见的配置是max_iterations5对于大多数任务已经足够。同时在最终输出中可以设计一个兜底逻辑比如“经过多次尝试未能获得可靠结果建议您简化问题或联系管理员”。陷阱五混淆了“聊天”与“任务执行”模式。现象用户和Agent聊得很开心但Agent总是偏离核心任务去回答一些无关的、知识性的问题。根因使用的系统提示词过于通用没有强有力地将其角色锁定在“任务执行者”上。解决方案在系统提示词的开头就用非常明确的语句定调。例如“你是【XXX任务】的专用自动化助手。你的唯一目标是使用我提供的工具完成用户提交的与【XXX任务】相关的请求。对于与任务无关的闲聊或知识问答你应礼貌地表示自己无法处理并引导用户回到任务主题。”
LLM、Agent与Prompt:构建下一代AI应用的铁三角架构实战
1. 项目概述从概念到实践的AI应用新范式最近和不少同行交流发现一个挺有意思的现象大家聊起AI大模型已经从最初的“ChatGPT真牛”的惊叹逐渐转向了更实际的问题——“这东西到底怎么用起来才能真帮我们干活” 这背后反映的正是整个行业从技术尝鲜到价值落地的关键转折。今天我想聊的就是这个“用起来”的核心三角大模型LLM、智能体Agent和提示词Prompt。这不仅仅是三个时髦的术语更是构建下一代AI应用的基础架构。简单来说你可以把这三者的关系想象成一次精密的太空任务。大模型LLM是那台功能强大的主控计算机它拥有海量的知识库和强大的推理能力是任务的“大脑”。智能体Agent则是搭载了这台计算机的航天器它具备感知环境读取文件、调用API、自主规划拆解任务步骤、执行动作写代码、发邮件并持续学习的能力是任务的“执行体”。而提示词Prompt就是地面控制中心发送给航天器的精确指令集。指令写得模糊不清“去探索火星”航天器可能原地打转指令写得精准、结构化“启动推进器调整轨道至环绕火星的极地轨道启动高分辨率相机对预定区域进行拍摄”才能引导大脑和执行体协同完成既定目标。所以这个“走进”系列目的不是复述教科书定义而是想结合我过去一年多在多个项目中趟过的坑、积累的经验和你一起拆解如何将这三个概念组合起来解决真实世界的问题。无论是想自动化处理周报、搭建一个智能客服原型还是开发一个能理解业务逻辑并自动生成SQL的数据分析助手其内核都离不开这三者的协同。接下来我们就从设计思路开始一步步拆解这个“铁三角”是如何工作的。2. 核心三角解析LLM、Agent与Prompt的协同逻辑2.1 大模型LLM能力基石与固有局限大模型特别是像GPT-4、Claude 3、国内的一些主流模型已经展现出了令人惊叹的通用知识、逻辑推理和内容生成能力。它是整个智能应用的“基座”。但在实战中我们必须清醒地认识到它的几个核心局限这直接决定了我们如何设计Agent和Prompt。第一知识的时效性与私有性。大模型的训练数据有截止日期它不知道今天早上发布的新闻也不知道你公司内部那套独特的客户数据库Schema。第二缺乏“行动”能力。模型可以告诉你“如何发送一封邮件”但它自己无法调用你的邮箱API。它是一位博学的顾问而非一个能动手的操作员。第三存在“幻觉”。模型可能会以极其自信的口吻编造看似合理但完全错误的信息比如生成一个不存在的函数名或引用一篇虚构的论文。注意因此在架构设计上我们绝不能期望用一个“超级提示词”让LLM解决所有问题。正确的思路是让LLM专注于它最擅长的“思考”和“规划”而将知识检索、工具调用、结果验证等“行动”部分交给Agent框架来统筹。2.2 智能体Agent从思考到行动的桥梁智能体是赋予大模型“手”和“脚”的框架。它的核心工作流通常遵循一个循环感知Perception - 规划Planning - 执行Action - 观察Observation。感知Agent接收用户的初始请求可能是自然语言也可能是结构化数据并结合上下文如之前的对话历史、加载的文档形成当前的任务理解。规划这是LLM大显身手的地方。Agent会将当前状态用户目标、可用工具、历史记录组织成一个清晰的提示Prompt提交给LLM。LLM的任务是输出一个“计划”这个计划可能是一系列步骤也可能是下一步该调用哪个工具。例如面对问题“帮我分析一下上季度销售数据TOP10的客户特征”LLM规划的输出可能是“步骤1连接数据库。步骤2执行查询SQL获取上季度销售额排名前10的客户ID及销售额。步骤3根据客户ID查询客户明细表获取客户行业、规模、区域等特征。步骤4对特征进行归纳总结形成报告。”执行Agent根据LLM的规划调用相应的工具Tool来执行。工具可以是执行一段Python代码、调用一个外部API如发送邮件、查询数据库、读取本地文件、甚至操作浏览器。观察Agent获取工具执行的结果可能是数据、成功/失败状态、错误信息并将这个结果作为新的“观察”反馈给LLM进入下一轮“规划-执行”循环直到任务被判定为完成或无法继续。目前主流的Agent框架如LangChain、LlamaIndex、AutoGen以及新兴的CrewAI等都在不同程度上实现了这个范式。它们提供了工具集成的标准接口、记忆管理、以及和不同LLM API的对接。2.3 提示词Prompt精准操控模型的“编程语言”如果把LLM比作一个功能强大但接口古怪的芯片那么Prompt Engineering就是为这个芯片编写微指令。它的目标是将人类模糊的意图转化为模型能稳定、准确理解的指令。在Agent场景下Prompt的设计尤为关键因为它直接决定了规划的质量。一个用于Agent规划的Prompt通常包含以下几个部分角色Role与目标Goal明确告诉模型“你是谁”以及“你要完成什么”。例如“你是一个资深数据分析师擅长通过编写精确的SQL查询来获取业务洞察。”约束Constraints设定边界防止模型天马行空。例如“你只能使用query_database_tool这个工具来执行查询。绝对不能假设任何数据库中不存在的表或字段。”工具描述Tools Description清晰定义Agent可以使用的工具列表、每个工具的用途、输入参数和输出格式。这是模型进行规划的依据。输出格式Output Format严格要求模型以特定格式如JSON、特定的思考链格式输出它的“思考过程”和“下一步行动”。这对于Agent框架稳定解析结果至关重要。示例Few-Shot Examples提供一两个“用户提问 - Agent思考过程 - 工具调用”的完整示例能极大提高模型输出的稳定性和准确性。实操心得很多人把Prompt简单理解为“把问题描述清楚”但在Agent中这远远不够。你需要像设计一个API接口文档一样设计你的Prompt考虑所有可能的输入、处理逻辑和输出规范。一个松散的Prompt会导致Agent行为不可预测时而成功时而失败一个严谨的Prompt则能让Agent像一段可靠的程序一样运行。3. 实战构建从零搭建一个数据分析智能体理论说得再多不如动手建一个。我们以构建一个“自然语言转SQL查询的数据库分析Agent”为例来串联整个流程。这个场景非常典型用户用中文提问Agent需要理解问题规划出查询步骤生成正确的SQL执行并返回结果。3.1 环境准备与工具选型首先我们需要选择技术栈。这里我以目前生态最成熟、文档最丰富的LangChain框架为例结合OpenAI GPT-4模型你也可以替换为国内通过API兼容的模型如通义千问、文心一言等数据库使用SQLite做演示。1. 安装核心依赖pip install langchain langchain-openai langchain-community sqlalchemylangchain: 核心框架。langchain-openai: 官方维护的OpenAI模型集成。langchain-community: 包含大量社区贡献的工具和组件如数据库连接工具。sqlalchemy: Python的SQL工具包和对象关系映射器LangChain通过它连接各种数据库。2. 准备示例数据库我们创建一个简单的sales.db文件包含两张表customers表:customer_id(主键),name,industry,region,employee_count。orders表:order_id,customer_id,order_date,amount。并插入一些模拟数据。3. 设置API密钥在你的环境变量或代码中设置OpenAI API密钥。import os os.environ[OPENAI_API_KEY] 你的-api-key3.2 构建核心Agent工具定义与提示词工程这是最核心的部分。我们将创建一个具备“数据库查询”单一工具的Agent。步骤1创建数据库连接工具from langchain_community.utilities import SQLDatabase from langchain_community.tools import QuerySQLDataBaseTool # 连接SQLite数据库 db SQLDatabase.from_uri(sqlite:///sales.db) # 创建查询工具实例 query_tool QuerySQLDataBaseTool(dbdb)这个query_tool就是一个标准的LangChain Tool它有一个run方法接收一个SQL字符串作为输入执行并返回结果。步骤2设计专属的Agent提示词模板这是成败的关键。我们不能用通用的聊天提示词必须为“数据库分析”这个任务定制。from langchain.prompts import PromptTemplate # 定义系统提示词模板 system_template 你是一个专业的SQL数据分析助手。你的职责是根据用户的问题编写准确、高效的SQL查询语句来获取答案。 ## 数据库Schema信息 {customers_schema} {orders_schema} ## 你必须遵守的规则 1. **绝对优先使用已提供的工具**你只能使用名为query_sql_db的工具来执行查询。不要尝试自己计算或猜测数据。 2. **严格验证查询可行性**在生成SQL前仔细对照Schema确保引用的表名、字段名完全正确。如果用户问题中提到的概念在Schema中没有直接对应你需要通过逻辑推理找到关联字段例如“销售额”可能对应orders.amount的求和。 3. **输出格式必须严格遵循以下JSON格式** {{ thought: 你的逐步推理过程解释你将如何解决问题为什么选择这样的SQL。, sql: 你生成的、准备交给工具执行的SQL语句。, action: query_sql_db // 固定为此值表示下一步动作是调用查询工具 }} 4. 如果用户的问题无法通过查询数据库回答或者信息不足请在thought中清晰说明原因并将sql设为nullaction设为final_answer。 ## 开始任务 用户问题{input} # 获取真实的Schema信息动态填入模板 customers_schema db.get_table_info(table_names[customers]) orders_schema db.get_table_info(table_names[orders]) # 创建PromptTemplate对象 prompt_template PromptTemplate.from_template( system_template, partial_variables{ customers_schema: customers_schema, orders_schema: orders_schema } )这个提示词模板做了几件关键事明确了角色和上下文告诉模型它是SQL专家并提供了具体的数据库表结构。设定了强硬约束强制要求使用工具避免了模型空想。规定了结构化输出要求模型以特定JSON格式输出这便于后续的Agent框架解析。thought字段对于调试和理解Agent的“思路”至关重要。处理了边界情况定义了当问题无法回答时的输出规范。步骤3组装Agent在LangChain中我们可以使用create_react_agentReAct范式来快速构建。from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain.agents.format_scratchpad import format_log_to_str from langchain.agents.output_parsers import ReActSingleInputOutputParser # 1. 初始化大模型 llm ChatOpenAI(modelgpt-4, temperature0) # temperature设为0减少随机性 # 2. 定义工具列表 tools [query_tool] tool_names [tool.name for tool in tools] # 3. 构建Agent的完整提示词将系统提示和用户输入结合 agent_prompt prompt_template.partial( tool_namesstr(tool_names), tools_description\n.join([f{tool.name}: {tool.description} for tool in tools]) ) # 4. 创建Agent agent create_react_agent(llm, tools, agent_prompt) # 5. 创建Agent执行器它负责运行循环 agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, # 开启详细日志方便调试 handle_parsing_errorsTrue, # 优雅处理解析错误 max_iterations5 # 防止死循环限制最大迭代次数 )3.3 运行测试与结果分析现在让我们用几个问题来测试这个Agent。测试1简单聚合查询result agent_executor.invoke({ input: 上季度总销售额是多少 }) print(result[output])预期行为Agent的thought会推理“上季度”需要计算日期范围然后生成类似SELECT SUM(amount) FROM orders WHERE order_date BETWEEN 2024-01-01 AND 2024-03-31的SQL。观察日志当verboseTrue时你会在控制台看到完整的ReAct循环日志包括LLM的思考、决定调用的工具、工具返回的结果。这是学习和调试Agent的黄金资料。测试2涉及多表关联的复杂查询result agent_executor.invoke({ input: 找出消费金额最高的前3个客户所在的行业和区域。 })预期行为模型需要规划出“先关联orders和customers表按客户分组汇总金额排序取前三最后投影出行业和区域字段”的步骤。生成的SQL会包含JOIN、GROUP BY、SUM和ORDER BY ... LIMIT。测试3存在歧义或信息不足的查询result agent_executor.invoke({ input: 分析一下我们的金牌客户。 })预期行为由于Schema中没有“金牌客户”的定义一个好的Agent应该在thought中明确指出“‘金牌客户’的定义不明确。数据库中可能通过customer_type字段或total_amount阈值来区分。需要用户澄清。” 然后输出sql: null, action: final_answer并将上述思考作为最终答案返回给用户。这体现了Agent的“自知之明”和与用户交互的能力。实操心得在测试阶段一定要开启verboseTrue。通过观察LLM在每一步收到的提示词和它的输出你能精准定位问题所在是提示词描述不清是工具定义有误还是模型本身逻辑混乱绝大多数Agent的故障都源于提示词或工具定义的瑕疵而非模型能力不足。4. 进阶优化与模式扩展一个基础的Agent跑起来只是第一步。要让它在生产环境中可靠工作还需要考虑以下进阶问题。4.1 处理复杂任务规划与子任务分解对于“帮我写一份上季度销售分析报告包括趋势、客户排名和区域对比”这样的复杂请求单次查询无法完成。这时需要引入更强大的规划能力。我们可以升级Agent使其能够生成一个包含多个子任务的计划。例如使用LangChain 的 Plan-and-Execute 模式或CrewAI 的多智能体协作框架。思路如下规划智能体Planner接收用户复杂请求利用LLM将其分解为一系列顺序或并行的子任务。例如子任务1查询上季度每月销售趋势数据。子任务2查询消费额排名前10的客户名单及详情。子任务3查询各区域的销售额对比。子任务4将以上数据整合生成一份结构化的中文分析报告。执行智能体Executor接收规划好的子任务列表逐个调用相应的工具如数据库查询工具、报告生成工具来完成。协调者Coordinator管理任务之间的依赖关系如任务2和3可以并行任务4必须等前三个都完成并汇总最终结果。这种模式将“宏观规划”和“微观执行”分离让LLM在更高层次上思考问题结构大大提升了处理复杂任务的可靠性和逻辑性。4.2 增强可靠性记忆、验证与错误处理短期记忆与长期记忆短期记忆ConversationBufferMemory让Agent能记住当前对话轮次内的上下文实现多轮交互。例如用户问“销售额趋势如何”接着问“和去年同期比呢”Agent需要记住“销售额”指的是哪个指标、哪个时间范围。长期记忆VectorStore Retriever将历史对话、项目文档、知识库向量化存储。当用户提问时先从中检索相关片段作为上下文注入提示词。这有效解决了LLM私有知识缺失和遗忘的问题。结果验证与安全护栏让Agent盲目执行生成的SQL是危险的。必须加入验证层。SQL语法预检查在执行前可以用一个轻量级库如sqlparse或尝试EXPLAIN命令来检查SQL基本语法。敏感操作拦截在工具层面定义规则禁止执行DROP、DELETE、UPDATE等写操作或者对涉及大量数据扫描的查询进行资源限制。结果后验证对查询返回的数据进行合理性检查。例如如果查询“平均订单金额”返回的结果是一个天文数字Agent应该能标记此结果异常并在最终输出中附加警告。错误处理与重试机制数据库查询可能因网络、锁、语法错误而失败。一个健壮的Agent不应就此崩溃。结构化错误捕获在工具调用层捕获异常。LLM辅助诊断将错误信息如SQLite错误“no such column: xxx”反馈给LLM让它重新分析问题并修正SQL。有限次重试设定一个重试次数如3次避免陷入死循环。4.3 提示词迭代与评估体系构建Agent是一个高度迭代的过程。你需要建立一个科学的提示词评估和优化流程。构建测试集Test Suite收集一批具有代表性的用户问题Q以及对应的、期望的Agent正确行为A或SQL语句S。覆盖简单查询、复杂关联、歧义问题、边界情况等。批量运行与评估编写脚本用测试集批量运行你的Agent。评估指标可以包括SQL生成准确率生成的SQL在语法和语义上是否与期望SQL等价。任务完成率Agent是否最终给出了正确答案。工具调用效率是否以最少的工具调用次数解决了问题。分析失败案例这是提升的关键。仔细查看失败案例中LLM的思考日志thought。是提示词中对工具的描述不够清晰是约束条件没写明白导致模型“越狱”还是缺少必要的示例Few-Shot导致模型不理解复杂意图迭代优化提示词根据分析结果有针对性地修改提示词模板。例如增加针对某一类错误的纠正示例或者强化某一条约束的表述。5. 常见陷阱与避坑指南在开发和部署LLM Agent的过程中我踩过不少坑这里总结几个最具代表性的希望能帮你省点时间。陷阱一过度依赖LLM的“智能”忽视精确的工程约束。现象Agent经常生成不在Schema中的字段名或试图进行无法实现的计算。根因提示词中只是简单说“请根据数据库Schema查询”没有以强硬、结构化的方式比如用“你必须”“你只能”这样的措辞把约束写死。解决方案在提示词中将数据库Schema以CREATE TABLE语句的形式清晰列出。并使用类似“在生成SQL前你必须逐一核对以下字段是否存在于上述表中”这样的指令强制模型进行自查。陷阱二工具Tool定义模糊不清。现象Agent知道该做什么但调用工具时参数格式总是出错。根因传递给LLM的工具描述过于简略。LLM需要精确知道工具的名称、功能、输入参数的名称、类型和含义。解决方案利用LangChain等框架的Tool类认真填写name、description和args_schema参数模式。description要写得像一份简明的API文档说明输入是什么输出是什么。陷阱三忽视上下文管理与Token消耗。现象对话进行到后面Agent“忘记”了之前的内容或者API调用因Token超限而失败。根因没有合理管理对话历史。将整个冗长的历史记录都塞进每次请求的上下文导致Token数暴涨、成本升高、且可能触及模型上下文长度上限。解决方案使用ConversationSummaryMemory或ConversationBufferWindowMemory。前者会定期让LLM总结之前的对话用摘要代替原文后者只保留最近N轮对话。对于知识库使用检索Retrieval方式只注入与当前问题最相关的片段而不是全部知识库内容。陷阱四缺乏有效的“停止”和“超时”机制。现象Agent陷入“思考-调用-得到错误-再思考”的死循环或者在一个简单问题上花费过长时间。根因没有设置max_iterations最大迭代次数和max_execution_time最大执行时间。解决方案在AgentExecutor中务必设置这些安全阀。一个常见的配置是max_iterations5对于大多数任务已经足够。同时在最终输出中可以设计一个兜底逻辑比如“经过多次尝试未能获得可靠结果建议您简化问题或联系管理员”。陷阱五混淆了“聊天”与“任务执行”模式。现象用户和Agent聊得很开心但Agent总是偏离核心任务去回答一些无关的、知识性的问题。根因使用的系统提示词过于通用没有强有力地将其角色锁定在“任务执行者”上。解决方案在系统提示词的开头就用非常明确的语句定调。例如“你是【XXX任务】的专用自动化助手。你的唯一目标是使用我提供的工具完成用户提交的与【XXX任务】相关的请求。对于与任务无关的闲聊或知识问答你应礼貌地表示自己无法处理并引导用户回到任务主题。”