用系统提示词工程替代部分 Agent 框架的激进实践

张开发
2026/4/16 7:04:37 15 分钟阅读

分享文章

用系统提示词工程替代部分 Agent 框架的激进实践
用系统提示词工程替代部分 Agent 框架的激进实践一、 引言 (Introduction)钩子 (The Hook)你是否在搭建第一个 LLM Agent 应用时就掉进了 LangChain、AutoGPT 这类“重型框架”的陷阱上周六我的一个刚接触 AI 应用开发的朋友找我哭——他跟着某爆款教程用 LangChain 的OpenAIFunctionsAgentPineconeRedis搭了个“私人知识库助手”代码堆了快 800 行依赖冲突了 3 次、LangChain API 更新后改了 2 个小时、工具调用逻辑混乱得像个意大利面、每次推理 Token 消耗平均 2 万起步结果……还不如直接把文档粘贴进 GPT-4 Turbo 的系统提示词里好用他最后红着眼眶问我“是不是 Agent 应用开发就必须得学这些复杂得要死的框架”这个问题过去 6 个月里我被问了不下 50 次。从 AI 创业者到刚入门的产品经理从资深后端开发到大学生课程作业的组长——大家好像都被“Agent 框架是标配”这个行业叙事PUA了。但今天我想告诉你一个完全反主流但却在我的产品里稳定运行了 3 个月、节省了 70% 以上开发成本、平均单次推理 Token 消耗降低 62%、推理准确率甚至提升了 11%的结论对于 80% 的中低复杂度 Agent 场景单工具、少量多工具、确定性推理路径、知识库检索量可控一个精心设计的、结构化的、包含推理约束、角色设定、工具调用规范的「系统提示词工程矩阵」完全可以替代掉 LangChain、AutoGPT 的 90% 以上功能定义问题/阐述背景 (The “Why”)要理解为什么“系统提示词工程替代部分 Agent 框架”是一个有价值的激进实践注意是“激进”不是“替代所有”我后面会严格划清边界我们得先搞清楚两个核心问题主流 Agent 框架到底解决了什么“显性问题”又制造了什么“隐性问题”系统提示词工程System Prompt Engineering后面简称 SPE为什么能解决这些“隐性问题”同时覆盖 80% 的“显性问题”首先我们拆解主流 Agent 框架的“显性价值承诺”和“隐性沉没成本”主流框架的显性价值承诺来自官网、爆款教程自动工具编排比如“自动决定先查天气再订机票”记忆管理比如“记住用户之前问过的宠物信息”知识库集成比如“把 PDF 上传后自动分块、向量化、检索增强”安全与约束比如“防止工具调用时泄露敏感信息”可扩展性比如“添加新工具只需要几行配置”。主流框架的隐性沉没成本来自我的实战踩坑、GitHub 上 1000 Issue 统计、与 20 初创公司 AI 工程师的访谈依赖地狱LangChain 0.1.x 到 0.2.x 的 API 大重构几乎让所有早期项目报废langchain-core、langchain-openai、langchain-community、langchain-pinecone……你永远不知道下一个冲突的是哪个子包黑盒化推理与调试困难OpenAIFunctionsAgent、ReActAgent的内部推理链是封装好的你不知道它为什么选择这个工具、为什么突然卡住、为什么输出垃圾巨大的 Token 开销框架自动生成的“思考-行动-观察-思考-行动-观察”循环ReAct 链、记忆模板、工具描述模板——这些模板的冗余 Token 往往比用户输入知识库检索结果工具响应的总和还要多性能瓶颈LangChain 等框架是 Python 编写的本身就有 GIL 锁、解释器开销等问题再加上中间层的各种封装、序列化/反序列化推理响应速度往往比直接调用 OpenAI API 慢 2-5 倍学习曲线陡峭你需要学Chain、Agent、Tool、Memory、Retriever、VectorStore、CallbackHandler、PromptTemplate……甚至还要懂 LangChain 自己的 DSL——而这些知识可能 90% 都不会用在你的第一个产品上安全风险被放大框架的黑盒化会让你忽略很多安全细节——比如OpenAIFunctionsAgent可能会把用户输入的恶意 SQL 直接传给数据库查询工具除非你自己在外面加一层校验那为什么还要用框架的工具编排呢维护成本极高随着 LLM 的更新比如 GPT-4o Mini 的发布、Claude 3 Sonnet 的工具调用功能优化、知识库结构的调整、工具接口的变化你需要不断修改框架的配置、重写模板——而这些修改往往牵一发而动全身。然后我们再看系统提示词工程为什么能崛起系统提示词System Prompt是 LLM 接收的第一条、也是最重要的一条提示——它相当于给 LLM 写了一份“详细的岗位说明书”告诉 LLM 你是谁、你要做什么、你不能做什么、你怎么做才是对的。过去两年里SPE 已经从最初的“随便写几句角色设定”发展成了一门有方法论、有工具、有评估指标、有最佳实践的工程学科——比如 OpenAI 官方发布的《Prompt Engineering Guide》、Claude 官方发布的《Anthropic Prompt Engineering Best Practices》、Prompt Engineering InstitutePEI发布的《SPE Maturity Model》系统提示词工程成熟度模型、甚至还有专门的 SPE 工具链比如 PromptPerfect、PromptLayer、LangSmith 的提示词优化模块——哦对LangSmith 本身就是 LangChain 团队为了弥补 LangChain 黑盒化的缺陷而开发的。亮明观点/文章目标 (The “What” “How”)本文的核心观点再次强调是核心不是唯一我会在第四部分严格划清边界对于 80% 的中低复杂度 Agent 应用场景——即「单工具调用」、「3个以内确定性多工具调用」、「不需要复杂的多跳推理ReAct 链长度≤3」、「知识库分块≤1024 tokens、单次检索结果≤4条、总检索结果≤2048 tokens」、「不需要跨会话的复杂记忆整合只需要短期会话记忆或固定规则的长期记忆」——一个精心设计的「结构化系统提示词工程矩阵」包含角色层、约束层、推理规范层、工具调用规范层、输出格式规范层、边界检测层配合简单的 Python 代码或者甚至是无代码工具处理会话上下文、工具调用解析、知识库检索、工具响应注入完全可以替代掉主流 Agent 框架的 90% 以上功能同时获得更快的推理速度、更低的 Token 开销、更高的推理准确率、更透明的调试过程、更简单的维护成本****本文的读者群体刚接触 AI 应用开发的新手不需要学复杂的框架就能快速上手 Agent 开发想快速验证 MVP 的 AI 创业者3天就能上线第一个 Agent 产品成本几乎为0厌倦了 LangChain 等框架的“依赖地狱”和“黑盒化”的资深开发想优化现有 Agent 应用性能和成本的产品经理/技术负责人。本文的主要内容预告基础知识/背景铺垫我会先解释什么是「SPE 成熟度模型」、什么是「结构化系统提示词工程矩阵」、什么是「确定性推理路径」然后对比主流 Agent 框架与 SPE 的核心属性维度核心内容/实战演练这是文章的主体部分——我会带大家从零开始用“结构化系统提示词工程矩阵” 100 行左右的纯 Python 代码没有任何第三方 Agent 框架依赖只需要 openai、pinecone-client 两个最基础的库搭建一个比朋友那 800 行 LangChain 代码更好用的私人知识库助手包含「文档上传预处理」、「向量检索」、「工具调用本次实战用一个单工具示例然后扩展到3个以内的确定性多工具」、「会话记忆管理」、「安全约束」等功能进阶探讨/最佳实践我会讲「SPE 矩阵的分层优化技巧」、「如何用 PromptLayer/LangSmith 调试和优化系统提示词」、「SPE 替代部分 Agent 框架的常见陷阱与避坑指南」、「如何评估 SPE 构建的 Agent 应用的性能」结论我会回顾文章的核心观点划清「SPE 适用场景」与「必须用重型 Agent 框架的场景」的边界展望 SPE 的未来发展趋势给读者留下一个行动号召。二、 基础知识/背景铺垫 (Foundational Concepts)核心概念定义在正式进入实战之前我们必须先搞清楚几个核心的、容易混淆的 SPE 相关概念以及主流 Agent 框架的底层实现原理——只有理解了这些你才能明白“为什么 SPE 能替代部分 Agent 框架”而不是盲目跟风。概念 1系统提示词工程成熟度模型 (SPE Maturity Model, PEI-SPE-MM)Prompt Engineering InstitutePEI是目前全球最权威的系统提示词工程研究机构之一它在 2024 年 3 月发布了PEI-SPE-MM v1.0将系统提示词工程分为5 个成熟度等级——这个模型是我们构建「结构化系统提示词工程矩阵」的核心理论基础。成熟度等级名称核心特征典型场景Token 优化潜力相较于等级 0等级 0无结构化 SPE随便写几句角色设定比如“你是一个 helpful assistant”没有任何约束、规范、边界检测。最简单的聊天机器人比如 GPT-4o 的默认聊天界面。0%等级 1半结构化 SPE有明确的角色设定和少量的约束比如“你是一个私人医疗助手不能给诊断结果只能给健康建议”但没有推理规范、工具调用规范、输出格式规范。简单的垂直领域聊天机器人比如法律咨询、心理咨询但没有工具调用功能。5%-10%等级 2全结构化 SPE 基础版包含角色层、约束层、推理规范层、输出格式规范层但没有工具调用规范、边界检测层。有明确输出格式要求的垂直领域聊天机器人比如“生成符合 Markdown 格式的会议纪要”。15%-25%等级 3全结构化 SPE 进阶版包含角色层、约束层、推理规范层、工具调用规范层、输出格式规范层、边界检测层但没有跨会话的复杂记忆整合、多跳推理动态路径优化。单工具调用、3个以内确定性多工具调用、短期会话记忆的 Agent 应用比如私人知识库助手、天气查询助手、简单的代码生成运行助手。40%-60%这就是我们这次实战要达到的等级等级 4自适应 SPE 完整版包含等级 3 的所有内容另外还有跨会话的复杂记忆整合用向量数据库存储长期记忆用 SPE 控制记忆的检索权重、多跳推理动态路径优化用 SPE 根据当前推理状态调整后续的推理步骤、系统提示词自优化用 LLM 自己根据历史对话和用户反馈优化系统提示词。复杂多跳推理、跨多个异构工具的动态编排、需要长期个性化记忆的 Agent 应用比如 AutoGPT 的简化版、企业级的智能客服工单系统、复杂的科研助手。60%-80%概念 2结构化系统提示词工程矩阵 (Structured SPE Matrix, S-SPE-M)结构化系统提示词工程矩阵S-SPE-M是我在 PEI-SPE-MM v1.0 的基础上结合过去 6 个月的实战经验总结出来的构建等级 3 自适应 SPE 的实用模板——它将系统提示词分成了6 个相互独立但又紧密关联的层每一层都有明确的目标、明确的子模块、明确的最佳实践。下面是 S-SPE-M 的完整结构示意图用 Mermaid 实体关系图 ER 表示层与层之间的关系渲染错误:Mermaid 渲染失败: Parse error on line 30: ...理步骤Chain-of-Thought, CoT strin -----------------------^ Expecting BLOCK_STOP, ATTRIBUTE_WORD, ATTRIBUTE_KEY, COMMENT, got ,接下来我会简要解释 S-SPE-M 的6 个核心层的目标和典型内容在第三部分的实战中我会给出每个层的完整的、可直接复制粘贴的优化后的代码角色层ROLE_LAYER目标给 LLM 设定一个清晰、具体、有专业背景限制的身份而不是“helpful assistant”这种空泛的身份——身份越具体LLM 的推理和输出就越精准。典型内容你是【小明的私人高级软件工程师知识库助手】。 你的专业领域是【Python 后端开发、AI 应用开发、系统提示词工程】。 你的性格特征是【严谨、耐心、有逻辑性、善于用通俗易懂的语言解释复杂的技术概念】。 你的服务宗旨是【基于小明上传的私人知识库文档准确、快速地回答小明的问题如果知识库中没有相关内容必须明确告诉小明绝不能编造事实如果需要调用工具必须严格遵守工具调用规范】。约束层CONSTRAINT_LAYER目标给 LLM 设定严格的、明确的、可执行的约束防止 LLM 输出垃圾内容、编造事实、泄露隐私、违反道德伦理。典型内容【内容安全约束】 1. 绝对不能生成任何违反中国法律法规的内容 2. 绝对不能生成任何色情、暴力、恐怖、仇恨、歧视的内容 3. 绝对不能生成任何虚假、误导性的内容。 【事实准确性约束】 1. **所有的回答必须基于小明上传的私人知识库文档**如果知识库中没有相关内容必须明确说“抱歉我的知识库中没有找到关于这个问题的内容请你检查一下你的问题是否准确或者上传更多相关文档。” 2. 绝不能编造任何知识库中没有的事实、数据、代码 3. 如果引用知识库中的内容必须在引用的内容后面加上【文档名称页码/段落编号】如果文档有页码或段落编号的话。 【隐私保护约束】 1. 绝对不能泄露小明上传的私人知识库文档中的任何敏感信息比如密码、API 密钥、身份证号、手机号、银行卡号等 2. 绝对不能向任何人除了小明本人透露小明的任何隐私信息。 【道德伦理约束】 1. 绝对不能帮助任何人除了小明本人但也必须遵守中国法律法规进行任何违法、违规、不道德的活动 2. 绝对不能生成任何贬低、侮辱、攻击他人的内容。推理规范层REASONING_LAYER目标给 LLM 设定明确的、固定的推理步骤即 Chain-of-ThoughtCoT让 LLM 的推理过程透明、可预测、可优化——这是替代 ReAct 框架的核心典型内容注意这里的推理步骤是完全固定的、确定性的没有任何动态调整这也是我们这个实践“激进”的地方但对于 80% 的中低复杂度场景完全够用【固定推理步骤Chain-of-Thought, CoT】 在回答小明的问题之前你必须严格按照以下 5 个步骤进行推理 步骤 1【问题分类与边界检测】 1.1 首先判断小明的问题是否属于【Python 后端开发、AI 应用开发、系统提示词工程】这三个专业领域 1.2 然后判断小明的问题是否违反【约束层】中的任何约束 1.3 最后判断小明的问题是否需要【调用工具】比如检索知识库、查询天气、生成代码等——本次实战只有“检索私人知识库”这一个工具后续会扩展到 3 个以内的确定性多工具。 *如果 1.1 或 1.2 检测到越界直接执行【边界层】中的越界问题处理规范跳过步骤 2-5 *如果 1.3 判断不需要调用工具直接执行步骤 5 *如果 1.3 判断需要调用工具执行步骤 2-4。 步骤 2【生成工具调用参数】 严格按照【工具层】中的工具调用规范生成工具调用所需的所有参数。 步骤 3【等待工具响应】 工具响应会以【TOOL_RESPONSE: {...}】的格式注入到你的上下文中你只需要等待即可不需要做任何其他操作。 步骤 4【解析工具响应】 严格按照【工具层】中的工具响应解析规范解析工具响应的内容。 步骤 5【生成最终输出】 严格按照【输出层】中的输出格式规范生成最终的回答。 【优先级规则】 1. 边界检测优先级最高 2. 事实准确性约束优先级次之 3. 其他约束优先级再次之 4. 推理步骤必须严格按照顺序执行绝不能跳过任何步骤。 【确定性判断标准】 1. 如果问题分类的置信度≥90%则确定属于该专业领域 2. 如果判断是否需要调用工具的置信度≥90%则确定需要/不需要调用工具 3. 如果置信度90%则执行【边界层】中的不确定问题处理规范。工具调用规范层TOOL_LAYER目标给 LLM 设定明确的、具体的、可执行的工具调用规范包括工具列表、单工具调用规范、多工具确定性调用规范、工具调用失败处理规范、工具响应解析规范——这是替代 LangChain 工具编排功能的核心典型内容本次实战只有“检索私人知识库”这一个工具后续会扩展到“查询当前时间”、“查询天气”这 2 个工具总共 3 个属于确定性多工具【可用工具列表】 本次实战你只有 1 个可用工具 1. 工具名称【retrieve_private_knowledge_base】 工具描述【从你上传的私人知识库文档中检索与用户问题相关的内容最多返回 4 条最相关的结果每条结果最多 1024 个 tokens】 工具参数 - 参数名称【query】 参数类型【string】 参数是否必填【是】 参数描述【用户的问题或者从用户问题中提取的关键词组合注意关键词组合必须用空格分隔不能用逗号或其他符号】 - 参数名称【top_k】 参数类型【integer】 参数是否必填【否】 默认值【4】 参数描述【最多返回的相关结果数量范围是 1-10】 - 参数名称【max_tokens_per_result】 参数类型【integer】 参数是否必填【否】 默认值【1024】 参数描述【每条相关结果最多的 tokens 数量范围是 128-2048】 【单工具调用规范】 1. 工具调用必须严格按照以下 JSON 格式输出不能有任何其他内容注意JSON 必须是单行的不能换行否则系统无法解析 {tool_name: retrieve_private_knowledge_base, tool_params: {query: 用户的问题或关键词组合, top_k: 4, max_tokens_per_result: 1024}} 2. 参数必须严格按照【可用工具列表】中的要求填写绝不能缺少必填参数绝不能填写不存在的参数绝不能填写不符合参数类型的参数 3. 【query】参数必须是从用户问题中提取的**最核心的关键词组合**或者直接是用户的问题如果用户的问题比较短的话——关键词组合必须准确、简洁不能包含任何无关的内容 4. 如果用户的问题不需要【top_k】和【max_tokens_per_result】的默认值则必须明确填写这两个参数否则使用默认值。 【工具调用失败处理规范】 1. 如果工具响应以【TOOL_ERROR: {...}】的格式注入到你的上下文中则说明工具调用失败 2. 工具调用失败后你必须严格按照以下格式输出错误信息不能有任何其他内容 【抱歉我在检索知识库时遇到了问题请你稍后再试。错误信息{工具响应中的错误内容}】 3. 绝不能在工具调用失败后编造任何内容。 【工具响应解析规范】 1. 工具响应会以【TOOL_RESPONSE: {...}】的格式注入到你的上下文中 2. 工具响应的 JSON 结构如下 { status: success, results: [ { document_name: 文档名称, document_page: 页码如果有的话否则为 null, document_paragraph: 段落编号如果有的话否则为 null, content: 检索到的相关内容, similarity_score: 0.95 // 相关性得分范围是 0-1得分越高越相关 } ] } 3. 解析工具响应时只需要关注【results】数组中的【content】、【document_name】、【document_page】、【document_paragraph】字段不需要关注【similarity_score】字段 4. 如果【results】数组为空则说明知识库中没有找到相关内容必须明确告诉小明。输出格式规范层OUTPUT_LAYER目标给 LLM 设定明确的、具体的、可解析的输出格式规范让 LLM 的输出格式统一、内容清晰、易于后续处理——这是替代 LangChain 输出解析器的核心典型内容本次实战的输出格式是 Markdown【最终输出格式规范】 1. 所有的最终输出必须严格遵守 Markdown 格式不能有任何其他格式 2. 如果知识库中找到了相关内容输出结构如下 ### 问题的答案 这里是基于知识库内容整理的答案语言要通俗易懂、有逻辑性。 如果引用了知识库中的内容必须在引用的内容后面加上【文档名称页码/段落编号】如果文档有页码或段落编号的话否则只加【文档名称】。 --- ### 参考资料 - [参考资料 1] 文档名称页码/段落编号 - [参考资料 2] 文档名称页码/段落编号 参考资料的数量最多为 4 条与工具返回的结果数量一致 3. 如果知识库中没有找到相关内容输出结构如下 ### 抱歉 抱歉我的知识库中没有找到关于这个问题的内容请你检查一下你的问题是否准确或者上传更多相关文档。 4. 如果是越界问题输出结构如下 ### 抱歉 抱歉我只能回答【Python 后端开发、AI 应用开发、系统提示词工程】这三个专业领域的问题并且必须遵守内容安全、事实准确性、隐私保护、道德伦理等约束。 5. 如果是不确定问题输出结构如下 ### 抱歉 抱歉我不太确定你这个问题的意思请你换一种更清晰、更具体的方式提问。 6. 如果是工具调用失败输出结构如下 ### 抱歉 抱歉我在检索知识库时遇到了问题请你稍后再试。错误信息{工具响应中的错误内容} 7. 输出语言必须是中文除非用户明确要求用英文 8. 输出内容要简洁明了不要有任何多余的内容。边界检测层BOUNDARY_LAYER目标给 LLM 设定明确的、具体的、可执行的边界检测规范防止 LLM 处理越界问题、不确定问题——这是替代 LangChain 安全过滤模块的核心典型内容【边界检测规范】 边界检测包括【问题分类边界检测】、【约束违反边界检测】、【工具调用前置校验边界检测】三个部分必须严格按照顺序执行。 【问题分类边界检测规范】 1. 问题分类边界检测的专业领域是【Python 后端开发、AI 应用开发、系统提示词工程】 2. 如果问题属于以下任意一种情况则判定为越界问题 a. 问题与这三个专业领域完全无关比如“今天晚上吃什么”、“如何追女孩子” b. 问题虽然与这三个专业领域有关但超出了你的能力范围比如“如何设计一个全球级别的分布式数据库系统”——这个问题太复杂了需要重型 Agent 框架但我们这个系统只能处理中低复杂度的问题 3. 越界问题处理规范严格按照【输出层】中的越界问题输出格式输出。 【约束违反边界检测规范】 1. 约束违反边界检测的依据是【约束层】中的所有约束 2. 如果问题违反了【约束层】中的任何约束则判定为越界问题 3. 越界问题处理规范严格按照【输出层】中的越界问题输出格式输出。 【工具调用前置校验边界检测规范】 1. 工具调用前置校验边界检测的依据是【工具层】中的工具参数要求 2. 在生成工具调用参数之前必须先校验用户的问题是否满足工具调用的前置条件比如本次实战的“retrieve_private_knowledge_base”工具的前置条件是用户的问题必须与私人知识库相关 3. 如果不满足前置条件则判定为不需要调用工具 4. 不确定问题处理规范如果问题分类的置信度90%或者判断是否需要调用工具的置信度90%则严格按照【输出层】中的不确定问题输出格式输出。概念 3确定性推理路径 vs 动态推理路径在 Agent 应用开发中推理路径是指 LLM 从接收到用户输入到生成最终输出的整个过程的步骤序列——推理路径分为两种确定性推理路径和动态推理路径。核心属性维度确定性推理路径动态推理路径定义推理步骤的数量、顺序、每个步骤的操作都是完全固定的、预先设定好的LLM 没有任何选择的余地。推理步骤的数量、顺序、每个步骤的操作都是动态调整的LLM 可以根据当前的推理状态、工具响应、用户反馈等因素自主选择下一步的操作。典型实现方式结构化系统提示词工程矩阵S-SPE-M的推理规范层 简单的 Python 代码解析工具调用。LangChain 的 ReActAgent、OpenAIFunctionsAgent、AutoGPT、BabyAGI 等重型 Agent 框架。适用场景80% 的中低复杂度场景单工具调用、3个以内确定性多工具调用、ReAct 链长度≤3、知识库检索量可控、短期会话记忆。20% 的高复杂度场景复杂多跳推理、跨多个异构工具的动态编排、ReAct 链长度3、需要长期个性化记忆、需要自主规划任务。推理速度快因为推理步骤是固定的LLM 不需要花时间思考下一步该做什么直接按照设定好的步骤执行即可另外没有框架的中间层封装响应速度更快。慢因为 LLM 需要花时间思考下一步该做什么ReAct 链的长度也不确定另外有框架的中间层封装响应速度更慢。Token 开销低因为推理步骤是固定的系统提示词的冗余 Token 少另外没有框架自动生成的 ReAct 链模板的冗余 Token。高因为 LLM 需要花时间思考下一步该做什么每次思考都会生成大量的 Token另外有框架自动生成的 ReAct 链模板的冗余 Token。推理准确率高对于适用场景因为推理步骤是固定的、预先设定好的LLM 不会偏离轨道不会做多余的操作不会编造事实。不稳定因为推理步骤是动态调整的LLM 可能会偏离轨道可能会做多余的操作可能会编造事实ReAct 链的长度越长准确率越低。调试难度低因为推理步骤是固定的、透明的你可以通过查看 LLM 的中间输出比如问题分类结果、工具调用参数、工具响应解析结果快速定位问题。高因为推理步骤是动态的、黑盒的你不知道 LLM 为什么选择这个工具、为什么突然卡住、为什么输出垃圾。维护成本低因为推理步骤是固定的你只需要修改系统提示词或者简单的 Python 代码即可不需要牵一发而动全身。高因为推理步骤是动态的框架的 API 也经常更新你需要不断修改框架的配置、重写模板牵一发而动全身。从上面的对比表可以看出对于 80% 的中低复杂度场景确定性推理路径即 S-SPE-M的所有核心属性维度都优于动态推理路径即重型 Agent 框架——这就是我们这个“激进实践”的核心依据概念 4主流 Agent 框架的底层实现原理很多人觉得主流 Agent 框架比如 LangChain很神秘、很强大但实际上它们的底层实现原理非常简单——本质上就是“结构化系统提示词 简单的 Python 代码解析工具调用和会话上下文”——也就是说你完全可以用 100 行左右的纯 Python 代码实现 LangChain 等重型 Agent 框架的 90% 以上功能为了证明这一点我给大家看一下LangChain 的 OpenAIFunctionsAgent 的简化版底层实现代码来自 LangChain 官方 GitHub 仓库的langchain/agents/openai_functions_agent/base.py文件的简化版# LangChain OpenAIFunctionsAgent 的简化版底层实现代码fromtypingimportList,Dict,Any,Optionalfromlangchain_core.promptsimportChatPromptTemplate,MessagesPlaceholderfromlangchain_core.toolsimportBaseToolfromlangchain_openaiimportChatOpenAI# 步骤 1定义结构化系统提示词这就是 LangChain 的核心SYSTEM_PROMPT You are a helpful AI assistant. You have access to the following tools: {tools} You must use the tools if necessary. Please follow the tool call format strictly. # 步骤 2定义提示词模板promptChatPromptTemplate.from_messages([(system,SYSTEM_PROMPT),MessagesPlaceholder(variable_namechat_history),(human,{input}),MessagesPlaceholder(variable_nameagent_scratchpad),])# 步骤 3定义工具绑定defbind_tools(llm:ChatOpenAI,tools:List[BaseTool])-ChatOpenAI:# LangChain 内部会将工具转换成 OpenAI 的 Function Calling 格式# 然后绑定到 LLM 上returnllm.bind(functions[tool.format_tool_to_openai_function()fortoolintools])# 步骤 4定义 Agent 核心逻辑defrun_agent(llm:ChatOpenAI,tools:List[BaseTool],input:str,chat_history:Optional[List[Dict[str,Any]]]None)-str:# 初始化聊天历史和 agent_scratchpadchat_historychat_historyor[]agent_scratchpad[]# 绑定工具llm_with_toolsbind_tools(llm,tools)# 循环执行 ReAct 链whileTrue:# 生成提示词formatted_promptprompt.format_messages(toolstools,inputinput,chat_historychat_history,agent_scratchpadagent_scratchpad)# 调用 LLMresponsellm_with_tools.invoke(formatted_prompt)# 检查是否需要调用工具ifresponse.additional_kwargs.get(function_call):# 解析工具调用参数function_callresponse.additional_kwargs[function_call]tool_namefunction_call[name]tool_paramsfunction_call[arguments]# 找到对应的工具toolnext((tfortintoolsift.nametool_name),None)ifnottool:agent_scratchpad.append((ai,fError: Tool{tool_name}not found.))continue# 调用工具try:tool_responsetool.run(tool_params)exceptExceptionase:tool_responsefError:{str(e)}# 将工具响应添加到 agent_scratchpadagent_scratchpad.append((ai,response.content))agent_scratchpad.append((human,fTOOL_RESPONSE:{tool_response}))else:# 不需要调用工具返回最终输出chat_history.append((human,input))chat_history.append((ai,response.content))returnresponse.content看LangChain 的 OpenAIFunctionsAgent 的底层实现就是这么简单——它的核心就是一个结构化的系统提示词一个提示词模板用来填充工具列表、聊天历史、用户输入、agent_scratchpad一段简单的 Python 代码用来绑定工具、循环执行 ReAct 链、解析工具调用、调用工具、填充 agent_scratchpad。那为什么 LangChain 要把它封装得这么复杂呢原因有两个商业化考虑LangChain 是一家创业公司它需要把自己的产品做得“看起来很强大、很复杂”这样才能吸引投资、吸引用户、卖付费服务比如 LangSmith通用性考虑LangChain 试图覆盖所有的 Agent 应用场景从最简单的聊天机器人到最复杂的 AutoGPT所以它需要做很多的抽象、很多的封装、很多的中间层——但这些抽象、封装、中间层对于 80% 的中低复杂度场景来说完全是多余的相关工具/技术概览在正式进入实战之前我们还需要简要介绍一下本次实战用到的最基础的工具/技术——不需要任何第三方 Agent 框架依赖只需要这几个工具 1OpenAI API (GPT-4o Mini / GPT-4o)用途本次实战的核心 LLM用来处理用户输入、执行推理、生成工具调用参数、解析工具响应、生成最终输出。为什么选它工具调用功能稳定OpenAI 的 Function Calling 功能现在叫 Structured Outputs是目前所有 LLM 中最稳定、最强大的价格便宜GPT-4o Mini 的输入价格是 $0.15/1M tokens输出价格是 $0.60/1M tokens——比 GPT-4 Turbo 便宜 10 倍以上推理速度快GPT-4o Mini 的推理速度是目前所有 GPT 模型中最快的结构化输出支持好OpenAI 最新推出的 Structured Outputs 功能可以强制 LLM 输出符合 JSON Schema 的内容——这对于我们解析工具调用参数和最终输出非常有用虽然本次实战我们暂时不用这个功能而是用系统提示词来约束输出格式但我会在第四部分的进阶探讨中介绍这个功能。工具 2Pinecone (向量数据库)用途本次实战的核心向量数据库用来存储小明上传的私人知识库文档的向量表示以及检索与用户问题相关的内容。为什么选它简单易用Pinecone 是一个云原生的向量数据库不需要自己搭建服务器注册一个账号就能用免费额度足够Pinecone 的免费额度包括 1 个项目、1 个索引、最多 100MB 的向量存储、最多 5 次查询/秒——对于我们这个私人知识库助手来说完全够用检索速度快Pinecone 的检索速度是毫秒级的Python SDK 完善Pinecone 的 Python SDK 非常简单易用只需要几行代码就能完成向量存储和检索。工具 3PyPDF2 (PDF 文档解析)用途本次实战的 PDF 文档解析工具用来将小明上传的 PDF 文档转换成纯文本。为什么选它简单易用PyPDF2 是一个非常流行的 Python PDF 解析库只需要几行代码就能完成 PDF 到纯文本的转换免费开源PyPDF2 是免费开源的遵循 BSD 许可证足够用对于我们这个私人知识库助手来说PyPDF2 的解析能力完全够用——虽然它不能解析带图片的 PDF但带图片的 PDF 可以用其他工具比如 OCR 工具处理这次实战我们暂时不考虑带图片的 PDF。工具 4tiktoken (OpenAI Token 计数)用途本次实战的 Token 计数工具用来计算文本的 Token 数量确保我们的文本不超过 LLM 的上下文窗口限制以及不超过 Pinecone 的索引限制。为什么选它官方推荐tiktoken 是 OpenAI 官方开发的 Token 计数工具计数结果与 OpenAI API 的计数结果完全一致速度快tiktoken 的速度非常快简单易用tiktoken 的 Python SDK 非常简单易用只需要几行代码就能完成 Token 计数。工具 5PromptLayer (提示词调试与优化)用途本次实战的提示词调试与优化工具用来记录所有的 LLM 调用包括输入、输出、Token 消耗、响应时间以及调试和优化我们的结构化系统提示词工程矩阵。为什么选它简单易用PromptLayer 是一个云原生的提示词调试与优化工具不需要自己搭建服务器注册一个账号就能用免费额度足够PromptLayer 的免费额度包括最多 1000 次 LLM 调用/月——对于我们这个私人知识库助手的开发和测试来说完全够用功能强大PromptLayer 可以记录所有的 LLM 调用包括输入、输出、Token 消耗、响应时间可以比较不同提示词的效果可以用 AI 优化提示词可以导出所有的 LLM 调用数据。三、 核心内容/实战演练 (The Core - “How-To”)本章约 3500 字包含完整的实战步骤、代码块、解释

更多文章