ARTICLE DETAIL

资讯详情

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

AI Agent技能演进:从复杂工程到简洁架构的现代化实践

AI Agent技能演进:从复杂工程到简洁架构的现代化实践 在AI Agent技术快速迭代的今天很多早期被视为“必备”的技能或组件正随着底层模型能力的增强和工程范式的成熟而逐渐被淘汰或简化。本文将结合社区讨论与工程实践系统梳理那些曾经“必须拥有”、但如今已可被“降级”或“弃用”的AI Agent技能并深入分析其背后的技术演进逻辑。无论你是正在规划Agent架构的开发者还是希望优化现有系统的工程师本文都将为你提供一份清晰的“技能过时清单”与现代化的替代方案。1. 背景与核心概念AI Agent的技能演进在深入讨论具体被淘汰的技能之前我们首先需要明确AI Agent的核心构成。一个典型的AI Agent系统通常由规划Planning、记忆Memory、工具使用Tool Use和反思Reflection等核心模块组成。其目标是理解复杂指令通过调用工具、规划步骤、利用记忆来完成特定任务。技术的发展并非线性。早期由于大语言模型LLM本身在规划、工具调用等方面的能力较弱开发者不得不构建大量精巧的、手动的“脚手架”来弥补这些不足。这些“脚手架”就是曾经的“must-have”技能。然而随着LLM能力的飞速提升特别是上下文长度、代码生成、逻辑推理和指令遵循能力的增强以及更优的工程模式如ReAct、Chain-of-Thought的普及许多复杂的中间层技能变得不再必要甚至成为系统的负担。本文的讨论正是基于这一背景哪些技能已经从“必须手动实现”变成了“可以交给模型本身”或“有更简单的替代方案”理解这一点能帮助我们在开发新Agent时避免过度设计将精力集中在真正产生价值的创新上。2. 环境与认知准备理解技能“降级”的前提在具体列举之前我们需要建立一个共识技能的“降级”或“弃用”并非绝对它高度依赖于你所使用的基础模型能力和任务复杂度。基础模型如果你使用的是GPT-4o、Claude 3.5 Sonnet或DeepSeek-V2等顶尖模型与使用一两年前的模型或某些开源小模型相比能“放心交给模型”的事情范围完全不同。本文的讨论主要基于当前2024年中后期主流高性能模型的能力。任务领域在高度专业化、容错率极低的领域如金融交易、医疗诊断某些“降级”可能仍需保留为安全冗余。本文更多针对通用任务和大多数业务场景。因此在阅读下文时请结合自身的技术栈和业务需求进行判断。我们的目标是追求架构的简洁与高效而非盲目地削减功能。3. 已被“降级”的前“必备”技能详解以下是经过社区和工程实践验证可以显著简化或移除的几类经典Agent技能。3.1 复杂的多轮对话状态管理曾经的“必须”在早期的聊天机器人或任务型Agent中开发者需要手动维护复杂的对话状态机Dialogue State Tracking, DST。这包括显式地定义对话的“槽位”Slots编写逻辑来提取用户语句中的信息填充槽位管理槽位的确认、澄清和修改流程并基于填满的槽位触发后续动作。为何曾是必备早期的LLM在长上下文一致性、指代消解和精确信息提取上能力不足无法可靠地自行维护多轮对话的完整上下文和目标。手动状态机是保证任务成功完成的唯一可靠方法。现状与替代方案 现代高性能LLM拥有强大的长上下文窗口如128K、200K甚至无限上下文和出色的指令遵循能力。对于大多数非极端复杂的任务将完整的对话历史作为上下文直接提供给模型并辅以清晰的系统提示System Prompt模型已经能够很好地理解当前对话状态、记住用户之前提供的信息并主动推进任务。示例对比旧方法手动状态机# 伪代码示例手动管理“订餐”任务的槽位 slots {“food_type”: None, “quantity”: None, “address”: None} def update_slots(user_utterance): # 使用规则或简单NLP模型解析语句填充slots if “pizza” in user_utterance: slots[“food_type”] “pizza” # ... 复杂的确认和澄清逻辑新方法交给LLM上下文# 系统提示词 system_prompt “”” 你是一个订餐助手。请根据整个对话历史来理解用户需求。 当用户提供的信息足够时包括食物类型、数量和送餐地址请主动生成订单摘要并请求确认。 如果信息不足请友好地询问缺失的部分。 “”” # 每次调用LLM时将system_prompt和完整的对话历史user/assistant消息对一起传入。 # LLM会基于全部历史来生成回复自然地进行状态管理。最佳实践对于绝大多数场景优先采用“完整上下文 清晰提示”的方案。仅在任务步骤极其固定、且对流程控制的确定性要求极高时如电话客服IVR升级版才考虑保留轻量化的状态跟踪。3.2 精细化的工具描述与选择逻辑曾经的“必须”早期Agent需要开发者为每一个工具函数编写极其详细、格式化的描述名称、功能、参数列表、参数类型、示例等并通常需要训练一个专门的“工具选择器”模型或者编写复杂的规则逻辑让Agent根据用户意图从几十个工具中选出最合适的一个。为何曾是必备LLM对函数调用的理解能力有限无法仅凭函数名和简单描述就可靠地决定何时调用、如何传参。现状与替代方案 以OpenAI的function calling后发展为tool_calls和Anthropic的tool use为代表的“结构化输出”能力已成为现代LLM的标准配置。模型现在能够理解自然语言需求并匹配工具只需提供工具的名称和简单自然语言描述模型就能较好地判断是否需要调用。生成格式化的参数模型可以严格按照JSON Schema格式生成调用参数。处理复杂参数对于嵌套对象、数组等复杂参数结构模型也能有效处理。关键转变从“教Agent如何思考选择工具”转变为“清晰地告诉Agent有哪些工具可用”。工程重点从构建选择逻辑转移到了设计一套简洁、清晰、正交的工具集。示例对比旧方法复杂描述与选择器tools [ { “name”: “get_weather”, “description”: “获取指定城市的天气信息。需要城市名称作为参数。”, “parameters”: { “type”: “object”, “properties”: {“city”: {“type”: “string”}}, “required”: [“city”] } # 可能还需要附加适用场景、示例等大量元数据 } ] # 需要额外的“路由”逻辑或模型来决定使用哪个工具新方法依赖模型的原生工具调用能力tools [ { “type”: “function”, “function”: { “name”: “get_weather”, “description”: “Get the current weather in a given city”, # 描述更自然 “parameters”: { “type”: “object”, “properties”: {“location”: {“type”: “string”, “description”: “The city name”}}, “required”: [“location”] } } } ] # 直接将tools列表和用户查询传给LLM。LLM会返回一个包含tool_calls的响应。 # 后端只需解析并执行被调用的工具。最佳实践为工具起一个见名知意的函数名并用一两句自然语言描述其功能。利用模型的原生工具调用能力简化架构。将多个相似工具合并为一个更通用的工具往往比维护多个精细工具更有效。3.3 手动的、复杂的规划与步骤分解曾经的“必须”对于“写一份行业报告”或“策划一次旅行”这样的复杂任务开发者需要预先定义好一套固定的任务分解模板或编写复杂的规划算法如基于树的搜索将高层目标拆解成一系列原子操作子任务然后让Agent按顺序执行。为何曾是必备LLM缺乏对复杂任务的整体规划能力和步骤间依赖关系的理解容易“跳步”或陷入循环。现状与替代方案Chain-of-Thought思维链和ReAct推理行动等模式的普及本质上将规划能力“内化”给了LLM。我们不再需要手动编写复杂的规划器而是通过设计提示词激励模型自己生成一步一步的推理和计划。核心改变从“外部规划器驱动Agent”到“提示词激发模型内部规划”。我们提供的是规划的方法论如“请逐步思考”而不是规划的具体内容。示例提示词你是一个任务执行专家。请用以下格式处理用户请求 Thought: 首先我需要理解任务的核心目标并拆解出关键步骤。 Action: 需要调用的工具名称如果没有则写 None。 Action Input: 调用工具的输入参数JSON格式。 Observation: 工具执行的结果。 ...这个循环可以重复多次 Thought: 我已经完成了所有必要步骤现在可以给出最终答案。 Final Answer: [对用户的最终回复]通过这样的提示LLM能够自主地进行任务分解、工具调用和结果整合。对于更复杂的规划可以结合有向无环图DAG工作流引擎如LangChain的Expression Language, LlamaIndex的Workflow来管理确定性强的部分而将其中需要灵活判断的节点交给LLM规划。最佳实践对于大多数任务采用ReAct范式即可。对于业务流程极其固定、有严格SLA要求的场景可以使用工作流引擎定义主干仅在决策点嵌入LLM调用。3.4 过度工程化的记忆系统曾经的“必须”为了克服LLM有限的上下文窗口开发者构建了复杂的记忆系统包括向量数据库存储与检索将历史对话切片嵌入每次查询时检索最相关的片段。摘要记忆定期将长对话总结成一段摘要放入上下文。分层/分类型记忆区分长期记忆、短期记忆、事实记忆、程序记忆等。为何曾是必备当上下文窗口只有4K或8K token时这是让Agent拥有“长期记忆”的唯一方法。现状与替代方案 随着128K、200K乃至“无限上下文”模型的商业化可用对于许多应用而言过度工程化的记忆系统变得“杀鸡用牛刀”。对于一次会话内的记忆直接将大量历史对话放入上下文窗口是最简单、最保真无需损失信息的摘要或检索的方法。新范式记忆系统的设计重点发生了转移核心记忆利用大上下文窗口处理会话内记忆。跨会话记忆这仍然是关键需求。但解决方案更倾向于使用传统数据库如SQLite, PostgreSQL存储结构化的用户偏好、事实和数据仅在需要时查询并注入上下文。向量检索更适用于从海量非结构化文档中查找相关知识而非替代基础的对话历史存储。最佳实践评估需求你的Agent需要记住多长的对话如果一次会话通常在几千token内优先使用长上下文。结构化存储用户的身份、偏好、设置等应存入传统数据库。精准使用向量库仅当Agent需要从大型知识库如产品手册、公司文档中查找信息时才使用向量检索。避免用它来存储简单的对话历史。3.5 独立的“反思”或“验证”模块曾经的“必须”为了让Agent能够检查自己的工作成果、发现错误并进行修正开发者会设计一个独立的“反思”步骤。这通常意味着让同一个LLM或另一个“验证器”LLM以旁观者视角重新评估Agent输出的正确性、完整性和安全性。为何曾是必备LLM在初次生成时可能犯“愚蠢的错误”缺乏自我检查能力。现状与替代方案让任务执行和反思在同一个推理循环中完成已成为更高效的范式。通过精心设计的提示词我们可以让LLM在输出最终答案前自发地进行“自我批判”和“修正”。示例在ReAct循环中融入反思Thought: 我需要计算圆的面积。用户给了半径5。 Action: calculate Action Input: {“operation”: “area_of_circle”, “radius”: 5} Observation: 结果是 78.53981633974483。 Thought: 我得到了结果。但我应该验证一下计算是否正确。圆的面积公式是 π*r²。π约等于3.14165的平方是25乘积是78.54。这与观察结果基本一致计算看来正确。 Final Answer: 半径为5的圆的面积大约是78.54平方单位。在这个例子中“验证”步骤被自然地融入了“Thought”里无需单独调用一个外部模块。对于代码生成等任务可以通过提示“请先解释你的思路然后写出代码最后检查代码是否有常见错误”来集成反思。最佳实践将反思作为提示词的一部分鼓励模型在生成最终输出前进行一步自我检查。对于极高风险的任务如代码部署、金融操作仍可保留一个轻量级的、规则化的最终检查哨卡。4. 实战案例构建一个简化版的旅行规划Agent让我们通过一个实战案例对比新旧架构思维展示如何运用上述“降级”理念构建一个更简洁的Agent。需求一个帮助用户规划一日游行程的Agent。4.1 旧架构思路过度设计对话状态管理定义槽位city,date,interests(list),budget。编写槽位填充和确认逻辑。工具系统创建多个工具search_hotels,search_attractions,check_weather,calculate_distance。为每个工具编写详细描述和选择规则。规划器编写一个固定流程先确定城市和日期 - 查天气 - 根据兴趣和预算找景点 - 计算景点间距离 - 排行程 - 推荐酒店。记忆系统使用向量数据库存储用户的历史旅行偏好。验证模块生成行程后调用另一个LLM检查行程是否合理时间是否太赶、预算是否超支。4.2 新架构思路简洁高效我们将基于GPT-4级别的模型能力进行设计。系统提示词设计你是一个专业的旅行规划助手。请根据以下原则与用户对话 1. 你需要主动询问用户的目的地、旅行日期、兴趣点如历史、美食、自然和大致预算。 2. 在获得足够信息后你需要为我规划一个合理的一日游行程。规划时请调用我提供的工具来获取实时信息。 3. 在给出最终行程前请务必自行检查景点间的交通时间是否合理总花费是否在预算内行程节奏是否张弛有度 4. 请以清晰、有条理的Markdown格式输出最终行程。 你可以使用的工具 - search_places: 根据地点和兴趣关键词搜索景点。参数location(城市名), keyword(兴趣关键词)。 - get_route: 获取两个地点间的公共交通时间和路线。参数origin, destination。 - get_weather: 获取某地某日的天气预报。参数location, date。 - estimate_cost: 估算一个活动的平均花费。参数activity(活动描述)。 请使用以下格式进行交互 Thought: [你的思考过程] Action: [工具名如无需调用则写 None] Action Input: [工具的输入参数JSON格式] Observation: [工具返回的结果] ... (重复 Thought/Action/Action Input/Observation 直到任务完成) Final Answer: [给用户的最终行程方案]后端实现核心Python伪代码import json from openai import OpenAI client OpenAI(api_key“your_key”) # 模拟的工具函数 def search_places(location, keyword): # 调用真实API如Google Places return f“在{location}找到关于{keyword}的景点XXX, YYY” def get_route(origin, destination): return f“从{origin}到{destination}乘坐地铁约30分钟” def get_weather(location, date): return f“{date} {location} 天气晴朗20-25°C” def estimate_cost(activity): return f“{activity} 的平均花费约为100元” tools [ { “type”: “function”, “function”: { “name”: “search_places”, “description”: “Search for tourist attractions or places based on location and interest.”, “parameters”: {“type”: “object”, “properties”: {…}, “required”: [“location”, “keyword”]} } }, # ... 定义其他工具 ] def run_agent(user_query, conversation_history[]): messages [ {“role”: “system”, “content”: system_prompt}, *conversation_history, {“role”: “user”, “content”: user_query} ] response client.chat.completions.create( model“gpt-4”, messagesmessages, toolstools, tool_choice“auto” ) message response.choices[0].message # 处理可能存在的 tool_calls if message.tool_calls: for tool_call in message.tool_calls: function_name tool_call.function.name function_args json.loads(tool_call.function.arguments) # 执行对应的工具函数 function_result globals()[function_name](**function_args) # 将结果作为新的“observation”消息追加到对话历史 messages.append(message) # 添加助理的消息包含tool_calls messages.append({ “role”: “tool”, “content”: function_result, “tool_call_id”: tool_call.id }) # 再次调用LLM让它基于工具结果继续思考 second_response client.chat.completions.create(...) message second_response.choices[0].message return message.content # 运行示例 history [] user_input “我想这周末去上海玩一天喜欢建筑和咖啡预算1000左右。” print(run_agent(user_input, history))架构对比总结状态管理由conversation_history上下文替代。工具选择交给LLM的原生tool_calls能力。规划与反思通过ReAct格式的提示词内化到模型的推理循环中。记忆本次会话记忆由上下文处理。用户长期偏好可存储在数据库下次对话时注入系统提示。代码量新架构的核心逻辑可能只需旧架构的1/3甚至更少。5. 常见问题与排查思路在采用这种更简洁的Agent架构时你可能会遇到一些新问题。问题现象可能原因解决思路LLM不按格式如ReAct输出提示词不够清晰或模型未对齐1. 在系统提示中更严格地规定格式。2. 在few-shot示例中展示完整流程。3. 考虑使用输出格式限制库如Guidance, LMQL。工具调用不准或参数错误工具描述不清晰参数Schema太复杂1. 简化工具描述使用更自然的口语。2. 简化参数结构避免深层嵌套。3. 提供更具体的工具使用示例。长上下文下性能下降/成本高上下文过长包含太多无关历史1. 实施上下文窗口管理并非所有历史都需要。可以总结较早的对话或只保留最近N轮。2. 将关键信息如用户偏好结构化提取并存储而非全文存入上下文。Agent陷入循环或无关动作任务目标不明确缺乏停止条件1. 在系统提示中明确任务边界和最终输出格式。2. 设置最大迭代次数ReAct循环数。3. 让模型在Thought中判断“任务是否已完成”。处理复杂任务时逻辑混乱单一ReAct循环可能不足以处理超复杂规划1. 引入分层任务分解先让LLM输出一个高级计划大纲再对每个子任务执行ReAct。2. 对于流程固定的部分使用工作流引擎。6. 最佳实践与工程建议基于以上分析我们总结出构建现代AI Agent的几点核心建议信任模型但加以引导现代LLM的能力远超以往。我们的工作重点应从“弥补模型缺陷”转向“有效激发和引导模型能力”。通过设计精良的提示词系统指令、few-shot示例、输出格式你可以让模型完成大部分繁重工作。工具设计追求“少而精”工具不是越多越好。设计功能聚合、接口清晰的工具。一个强大的search工具支持多种筛选条件可能比十个专用的search_X工具更有效。这降低了模型的选择难度。拥抱“提示词工程”作为核心架构你的系统提示词就是Agent的“宪法”和“操作系统”。花费时间迭代和优化提示词其回报远高于编写复杂的控制代码。考虑将提示词版本化、模块化管理。上下文管理是新的艺术有了长上下文如何高效利用它成为关键。明确什么信息需要放入上下文当前任务相关历史什么信息应存入外部数据库用户档案、知识库什么信息可以被安全地丢弃或总结。评估与监控至关重要简化架构不代表放弃控制。你需要建立完善的评估体系检查Agent的最终输出质量、工具调用准确率、任务完成率。设置自动化监控对异常情况如循环、调用不存在工具进行告警和降级处理。保持架构的演进能力今天被“降级”的技能可能因为新的模型能力或业务需求再次变得重要。你的架构应该模块化使得你可以轻松地重新引入一个状态管理器或一个专门的规划模块如果未来证明有必要的话。技术的本质是不断将复杂性封装到底层为上层开发者提供更简洁的抽象。AI Agent领域正在经历这一过程。淘汰过时的“必备技能”拥抱更强大的原生模型能力和更优雅的工程范式是我们构建更强大、更可靠、更易维护的智能体系统的必经之路。希望这份梳理能帮助你厘清思路在下一个Agent项目中轻装上阵直击核心价值。
返回列表