ARTICLE DETAIL

资讯详情

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

AI应用开发中Skill与Agent的本质区别及实战设计指南

AI应用开发中Skill与Agent的本质区别及实战设计指南 1. 从开奶茶店的故事理解 Skill 与 Agent 的本质区别如果你正在接触 AI 应用开发或者想搞清楚大模型能做什么一定会频繁遇到Skill和Agent这两个词。它们听起来都像是“能力”或“代理”但背后的设计理念和适用场景天差地别。用一堆技术定义去解释不如讲个故事来得直接。假设你想开一家奶茶店。Skill就像你店里一个个独立的、功能明确的“工具”或“标准操作流程”。比如封口机它的技能Skill就是“封口”。你给它一杯装好奶茶的杯子它执行封口动作完成。糖度计量勺它的技能是“定量加糖”。你告诉它“七分糖”它舀出对应分量的糖完成。收银系统它的技能是“结算收款”。顾客下单它计算金额、打印小票完成。每个 Skill 都是确定性的、边界清晰的、可被单独调用的。它不关心为什么封口也不管这杯奶茶最终卖给谁只负责把交给它的那一步做到位。Agent则像是你雇的一个全能店长。你告诉他“今天目标是营业额达到5000元。” 然后这位店长 Agent 会开始自己动脑子感知观察天气热可能冰饮需求大、查看库存珍珠快没了、留意客流学生放学时段。规划决定主推几款冰爽水果茶并安排员工提前煮珍珠。行动调用各种 Skill 来执行计划。他指挥店员甲调用封口机 Skill去制作饮品指挥店员乙调用收银系统 Skill加快结账速度自己还可能去写个促销小黑板调用某种文案或绘画 Skill。反思中午过后他发现水果茶卖得不如预期于是调整策略下午改推“买一送一”的奶茶套餐。这个店长 Agent 的核心特点是他有目标、能自主规划、会调用工具Skill、并能根据结果反思和调整策略。他是一个具备一定自主性的“智能体”。所以最核心的区别在于Skill是“做什么”—— 一个被定义好的、被动的、单一的功能或动作。Agent是“为什么做”和“怎么做”—— 一个主动的、有目标的、能编排多个动作Skill来完成复杂任务的智能体。搞懂这个区别你就能明白为什么有些AI应用感觉“很傻”只会机械问答而有些则显得“有脑子”能帮你一步步处理复杂工作。接下来我们就从技术实现和落地实操的角度把这套“开店理论”拆解清楚。2. Skill 详解如何定义与实现一个可靠的“工具”在技术实现中Skill 的本质是一个封装好的、可复用的功能单元。它对外提供明确的接口内部处理特定逻辑。开发一个 Skill关键在于让它“可靠”和“好用”。2.1 Skill 的核心特征与设计原则一个设计良好的 Skill 应该具备以下特征这就像确保你的封口机不出故障、计量勺刻度精准单一职责一个 Skill 只做好一件事。比如“查询天气”、“发送邮件”、“计算折扣”。避免设计成“既查询天气又发送邮件还计算折扣”的巨无霸Skill否则难以维护和复用。接口明确有清晰的输入和输出定义。输入是什么格式、哪些是必填参数输出是什么结构、成功和失败分别返回什么。这就像封口机需要明确杯口尺寸收银系统需要商品清单。确定性相同的输入应该产生相同的输出或可预期的输出。它不应该有“随机发挥”的空间。这是 Skill 和 Agent 内“思考”环节的根本区别。可独立测试不依赖复杂的 Agent 环境就能单独验证其功能是否正确。这是保证系统稳定性的基础。2.2 一个 Skill 的典型实现结构以“查询城市天气”这个 Skill 为例我们来看它的内部构成# 伪代码示例WeatherQuerySkill class WeatherQuerySkill: def __init__(self, api_key): self.api_key api_key # 依赖的外部服务密钥 self.client WeatherClient(api_key) # 初始化客户端 def execute(self, input_params: Dict) - Dict: 执行技能的核心方法 输入: {city: 北京, date: 2023-10-27} 输出: {status: success, data: {temp: 18, condition: 晴}, unit: 摄氏度} 或 {status: error, message: 城市名称无效} # 1. 参数校验与标准化 city input_params.get(city) if not city: return {status: error, message: 缺少必要参数: city} standardized_city self._standardize_city_name(city) # 2. 调用外部API或内部逻辑 try: raw_data self.client.query(standardized_city, input_params.get(date)) except APINetworkError: # 3. 错误处理与重试机制 return {status: error, message: 网络请求失败请稍后重试} # 4. 结果解析与格式化 formatted_data self._parse_weather_data(raw_data) # 5. 返回结构化结果 return { status: success, data: formatted_data, unit: 摄氏度, source: 某天气平台, timestamp: time.time() } def _standardize_city_name(self, city: str) - str: # 内部方法将“北京市”、“北京”、“beijing”统一为标准编码 pass def _parse_weather_data(self, raw_data: Dict) - Dict: # 内部方法从原始API响应中提取所需字段 pass关键点解析依赖管理Skill 可能需要 API Key、数据库连接等外部资源这些应在初始化时注入。健壮性包含输入校验、异常捕获、错误信息友好返回。一个 Skill 不应该因为无效输入而崩溃。可观测性返回结果中包含status,source,timestamp等信息便于上游Agent追踪和调试。2.3 在项目中管理和使用 Skill当 Skill 多起来后你需要一个“工具箱”来管理它们。通常有两种模式集中注册表模式创建一个全局的 Skill 注册中心。每个 Skill 开发完成后向中心注册自己的名称、描述、输入输出格式。skill_registry.register( nameweather_query, description根据城市名称查询天气, skill_classWeatherQuerySkill, required_params[city], optional_params[date] )Agent 或其他组件需要时只需向注册中心请求skill_registry.get(“weather_query”)。配置文件模式将 Skill 的定义写在 YAML 或 JSON 配置文件中系统启动时动态加载。skills: - name: weather_query class_path: “my_project.skills.weather.WeatherQuerySkill” init_args: api_key: ${WEATHER_API_KEY} description: “查询指定城市天气”给开发者的建议不要一上来就追求 Skill 的“智能”。先把它的功能做稳定、接口做清晰、错误处理做完善。一个总是返回“Internal Server Error”的 Skill再“智能”的 Agent 也用不了。3. Agent 详解构建那个“有脑子”的店长如果说 Skill 是肌肉和骨骼那么 Agent 就是大脑和神经系统。它的目标是在不确定的环境中通过感知、规划、行动、反思的循环自主完成复杂任务。3.1 Agent 的核心循环感知-规划-行动-反思我们回到奶茶店店长的例子把这个循环技术化感知Agent 从环境中获取信息。这可以是用户的自然语言指令“帮我策划一个周末促销方案”、来自传感器的数据、数据库查询结果、乃至其他 Agent 的消息。技术实现通常通过“感知器”模块将原始输入文本、图像、数据转化为 Agent 内部可以理解的“状态”表示。规划基于当前状态和目标Agent 生成一个行动计划序列。这是 Agent “思考”的核心。简单任务可能是直接调用一个 Skill。如用户问“北京天气”规划结果就是[调用 weather_query Skill]。复杂任务需要多步分解。如“策划促销方案”规划结果可能是[调用 market_analysis Skill] - [调用 copy_writing Skill] - [调用 design_draft Skill] - [调用 cost_estimate Skill]。关键技术大语言模型在此环节发挥巨大作用。我们可以通过 Prompt Engineering 让 LLM 扮演“规划师”角色。例如你是一个营销策划专家。请将以下目标分解为具体的可执行步骤。 目标为一家位于大学城的奶茶店策划一个周末促销方案预算有限。 请列出步骤每个步骤应是一个明确的动作如“分析目标客户特征”、“制定促销产品组合”等。行动执行规划好的步骤本质上是调用相应的 Skill。Agent 需要有一个“技能调用器”它能根据规划步骤的描述找到注册表中对应的 Skill并按照 Skill 要求的格式传入参数。关键挑战参数映射。规划步骤可能是“分析最近一周的销售数据”而对应的sales_analysisSkill 需要的输入可能是{“start_date”: “2023-10-20”, “end_date”: “2023-10-26”, “metrics”: [“volume”, “revenue”]}。Agent 需要自动完成这种从自然语言到结构化参数的转换。反思观察行动结果评估是否离目标更近并决定下一步。成功继续执行下一个规划步骤。失败或部分成功分析原因。是 Skill 执行出错还是规划不合理然后调整策略。例如调用cost_estimateSkill 后发现预算超支Agent 应能重新规划或许减少广告投放渠道。技术实现可以设计一个“验证器”模块检查 Skill 返回结果的status字段或通过另一个 LLM 调用评估结果与目标的匹配度。3.2 实现一个基础 Agent 的框架代码下面是一个高度简化的 Agent 核心循环的伪代码框架它展示了上述概念如何组合class BasicAgent: def __init__(self, skill_registry, planner_llm, verifier_llm): self.skills skill_registry # 技能库 self.planner planner_llm # 用于规划的LLM self.verifier verifier_llm # 用于反思/验证的LLM self.memory [] # 记忆存储历史交互 def run(self, user_goal: str, max_steps10): 执行一个目标 current_state {goal: user_goal, history: self.memory} plan [] for step in range(max_steps): # 1. 规划 (或重新规划) if not plan: plan self._make_plan(current_state) if not plan: return {status: failed, reason: 无法生成有效计划} # 2. 执行当前计划的第一步 current_action plan.pop(0) # 例如: {skill: market_analysis, args: {scope: university}} skill_name current_action[skill] skill self.skills.get(skill_name) if not skill: # 技能不存在加入记忆并重新规划 current_state[history].append(f尝试调用不存在的技能: {skill_name}) plan [] # 触发重新规划 continue # 执行技能 result skill.execute(current_action.get(args, {})) # 3. 观察结果并存储记忆 current_state[history].append({ action: current_action, result: result }) # 4. 反思与验证 if result.get(status) ! success: # 技能执行失败需要调整 adjustment self._reflect_on_failure(current_state, result) if adjustment replan: plan [] elif adjustment retry: plan.insert(0, current_action) # 重试当前动作 continue # 检查目标是否达成 if self._is_goal_achieved(current_state, user_goal): return {status: success, final_state: current_state} return {status: timeout, final_state: current_state} def _make_plan(self, state: Dict) - List[Dict]: 利用LLM生成计划步骤列表 prompt f 目标{state[goal]} 已有历史{state[history][-3:]} # 只参考最近几条历史 可用的技能列表{self.skills.list_skills()} # 列出所有技能名称和描述 请将目标分解为一系列可执行的步骤。每个步骤必须对应一个上述技能。 输出格式为JSON列表每个元素如{{skill: 技能名, args: {{参数名: 值}}}} # 调用 self.planner 生成计划 (此处简化) generated_plan call_llm(prompt) return parse_json(generated_plan) def _reflect_on_failure(self, state: Dict, failed_result: Dict) - str: 反思失败原因决定重试或重新规划 prompt f 任务历史{state[history]} 最新失败动作的结果{failed_result} 请分析失败原因并决定下一步 1. 如果是参数错误或临时错误建议 retry重试。 2. 如果是计划根本不可行或技能不匹配建议 replan重新规划。 只输出 retry 或 replan。 decision call_llm(prompt, modelself.verifier) return decision.strip() def _is_goal_achieved(self, state: Dict, original_goal: str) - bool: 验证目标是否达成 # 简单实现检查最近几个成功结果是否包含目标关键词 # 复杂实现可以调用另一个LLM进行判断 pass这个框架揭示了 Agent 开发的关键点规划器的质量决定上限_make_plan方法依赖 LLM 的能力。Prompt 的设计、上下文history的提供方式直接影响规划是否合理。技能调用的可靠性是基础如果 Skill 频繁失败Agent 会陷入不断重试或重新规划的循环。反思机制决定稳健性_reflect_on_failure是 Agent 从错误中学习的关键。一个简单的规则引擎可能比 LLM 更稳定。记忆是连续的保证self.memory存储了交互历史让 Agent 有“上下文”概念避免重复错误或循环。4. 实战从零设计一个“智能奶茶店运营助手” Agent现在我们把理论和故事结合设计一个具体的项目。目标是创建一个能协助运营奶茶店的 AI Agent。4.1 第一步定义核心目标与边界首先明确你的 Agent 要解决什么问题避免一开始就陷入功能蔓延。核心目标根据每日销售数据、库存情况和天气自动生成次日或本周的补货建议和产品推荐策略。边界限定只处理数据分析和策略建议不直接操作采购系统或修改菜单价格。输入是结构化的销售报表、库存表和天气 API。输出是清晰的文本报告和结构化建议。这是一个辅助决策的 Agent不是全自动运营 Agent。4.2 第二步拆解并开发所需的 Skills根据目标我们需要以下 Skillssales_data_fetcher(销售数据获取)输入{“date”: “2023-10-26”, “data_source”: “database”}输出{“status”: “success”, “data”: [{“product”: “珍珠奶茶”, “qty”: 120, “revenue”: 3600}, …]}实现连接数据库查询指定日期的销售明细。inventory_checker(库存检查)输入{“materials”: [“珍珠”, “绿茶茶叶”, “牛奶”]}可选不传则查全部输出{“status”: “success”, “data”: {“珍珠”: {“stock”: 15.5, “unit”: “kg”, “alert_threshold”: 10.0}, …}}实现查询库存管理系统 API 或数据库。weather_forecast(天气预测)输入{“city”: “上海”, “days”: 1}输出{“status”: “success”, “data”: {“tomorrow”: {“max_temp”: 28, “condition”: “晴转多云”, “precipitation_prob”: 10%}}}实现调用第三方天气 API。demand_analyzer(需求分析)输入{“historical_sales”: […], “weather_forecast”: {…}, “day_of_week”: “Monday”}输出{“status”: “success”, “insights”: [“预计明天珍珠奶茶需求增长20%”, “气温高建议增加水果茶备料”], “product_forecast”: {“珍珠奶茶”: 144, “芒果冰沙”: 80}}实现这是核心“大脑”之一。可以内置一个简单的回归/时间序列模型或者使用规则引擎如温度 30度冰饮系数 * 1.5。replenishment_advisor(补货建议)输入{“demand_forecast”: {…}, “current_inventory”: {…}, “lead_time”: {“珍珠”: 2}}lead_time 是采购提前期输出{“status”: “success”, “purchase_list”: [{“material”: “珍珠”, “suggested_qty”: “20kg”, “reason”: “库存15.5kg明日需求预计消耗18kg需提前2天订货”}]}实现基于需求预测和当前库存结合安全库存和采购提前期计算建议采购量。report_generator(报告生成)输入{“insights”: […], “purchase_list”: […], “date”: “2023-10-27”}输出{“status”: “success”, “report_text”: “## 2023-10-27 运营建议报告\n\n### 市场洞察\n1. 明日天气晴朗气温较高…\n\n### 补货建议\n1. 珍珠建议采购20kg…\n”, “structured_data”: {…}}实现使用模板或调用 LLM如 GPT将结构化数据润色成易读的报告文本。开发要点每个 Skill 开发完后务必编写单元测试模拟各种输入正常、边界、异常确保其行为符合预期。这是 Agent 稳定运行的基石。4.3 第三步设计 Agent 的工作流与规划逻辑我们的ShopOpsAgent的工作流规划是相对固定的可以描述为一个流程图开始 │ ▼ [感知] 获取当前日期、店铺位置等初始信息 │ ▼ [规划] 生成固定步骤序列 │ 1. 获取昨日销售数据 │ 2. 获取当前库存 │ 3. 获取明日天气 │ 4. 分析需求 │ 5. 生成补货建议 │ 6. 生成最终报告 │ ▼ [行动] 按顺序调用对应 Skill │ ▼ [反思] 检查每个 Skill 执行结果 │ ┌─── 失败 ─── 记录日志尝试继续或终止 │ ▼ └─ 成功 │ ▼ 结束输出报告对于这种流程固定的 Agent其“规划”模块可以不用复杂的 LLM而是一个预定义的工作流引擎。这比依赖 LLM 动态生成计划更稳定、更高效。# 用 YAML 定义工作流 workflow: name: daily_ops_report steps: - name: fetch_sales skill: sales_data_fetcher args: date: “{{ yesterday }}” # 支持变量 on_success: next on_failure: abort - name: check_inventory skill: inventory_checker args: {} # 查全部库存 on_success: next on_failure: abort - name: get_weather skill: weather_forecast args: city: “{{ shop_location }}” days: 1 on_success: next on_failure: continue # 天气获取失败仍可继续分析 - name: analyze_demand skill: demand_analyzer args: historical_sales: “{{ steps.fetch_sales.output.data }}” weather_forecast: “{{ steps.get_weather.output.data }}” day_of_week: “{{ tomorrow_weekday }}” on_success: next on_failure: abort - name: advise_replenishment skill: replenishment_advisor args: demand_forecast: “{{ steps.analyze_demand.output.product_forecast }}” current_inventory: “{{ steps.check_inventory.output.data }}” on_success: next on_failure: abort - name: generate_report skill: report_generator args: insights: “{{ steps.analyze_demand.output.insights }}” purchase_list: “{{ steps.advise_replenishment.output.purchase_list }}” date: “{{ tomorrow }}” on_success: end on_failure: end_with_error这种基于工作流的 Agent是生产环境中更常见、更可控的形式。它结合了 Skill 的确定性和固定流程的效率。4.4 第四步实现、测试与迭代1. 环境搭建与集成测试为每个 Skill 创建 Mock 或测试桩模拟数据库和 API 调用。先让工作流引擎跑通整个流程使用测试数据。重点观察数据在 Skill 之间传递是否正确错误处理是否生效2. 引入 LLM 增强固定工作流稳定后可以考虑用 LLM 增强某些环节。例如report_generatorSkill 可以改为调用 GPT API让它写出更生动、更有说服力的报告。甚至可以增加一个anomaly_detectorSkill用 LLM 分析销售数据发现机器规则未能发现的异常模式如“某款产品在雨天突然销量上升”。3. 加入记忆与学习让 Agent 将每日的报告和执行结果存储到数据库。每周或每月增加一个weekly_reviewSkill调用 LLM 总结过去一段时间的运营情况提出长期优化建议如“每周三珍珠消耗量都很大建议固定周三上午补货”。这样Agent 就从“每日助手”进化成了“有经验的运营顾问”。4. 监控与告警为 Agent 的执行过程添加详细日志。对关键指标设置监控如demand_analyzer的预测准确率、replenishment_advisor的建议采纳率。当某个 Skill 连续失败或预测偏差过大时触发告警通知人工介入。5. 关键决策点何时用 Skill何时用 Agent如何选择框架理解了 Skill 和 Agent 是什么之后在实际项目中如何选择5.1 判断标准你的任务需要“自主性”吗特征适合用 Skill或工作流适合用 Agent任务确定性高。输入输出明确步骤固定。低。环境多变需要灵活应对。流程复杂性低到中。线性流程分支较少。高。有大量条件分支、循环或试错。所需“智能”低。主要是数据处理、规则计算、API调用。高。需要理解自然语言、进行复杂规划、创造性生成。示例数据ETL流水线、每日报表生成、订单状态更新。智能客服对话、游戏NPC、自动研究助手、个性化旅行规划。技术实现函数库、微服务、Apache Airflow/Dagster 工作流。基于LLM的规划-行动框架、强化学习智能体。简单规则如果你能用一张清晰的流程图包括所有判断分支把任务画出来那么用工作流一组 Skill 的固定编排更可靠。如果流程图都画不出来或者分支多到像一棵树那么可能需要 Agent 的自主决策能力。5.2 主流 Agent 框架/库选型参考如果你决定构建 Agent市面上有很多框架可以加速开发。选择时关注以下几点社区活跃度、与现有 Skill 的集成难度、对复杂规划的支持、调试工具是否完善。框架/库核心特点适用场景上手难度LangChain生态最丰富概念最全Agent, Chain, Tool文档和社区资源极多。快速原型验证构建基于LLM的复杂应用。Agent是其一部分功能。中。概念较多需要时间理解其抽象。AutoGen微软推出主打多智能体对话。擅长让多个角色化Agent协作完成任务。需要模拟讨论、辩论、评审等多人协作场景的应用。中高。需要设计多Agent的交互协议。Semantic Kernel微软推出与.NET生态结合深强调“规划”与“插件”即Skill。.NET技术栈团队或希望深度集成微软系服务如Azure OpenAI。中。LlamaIndex最初专注于RAG现在也提供了强大的Agent和工具调用能力。任务严重依赖私有知识库检索和推理的场景。中。自定义框架基于上述框架二次开发或完全从零实现如本文第3章的简化示例。对性能、控制力有极致要求或业务逻辑极其特殊。高。给新手的建议不要一上来就追求最强大、最灵活的框架。先从 LangChain 的AgentExecutor和Tool概念入手快速搭建一个能调用 2-3 个简单 ToolsSkill的 Agent理解其运行机制。这比一开始就研究多Agent协作要实际得多。5.3 避坑指南Agent 项目常见的失败原因Skill 不可靠Agent 的强大建立在 Skill 的稳定之上。一个总出错的 Skill 会让整个 Agent 崩溃。先花 80% 的时间打磨好你的 Skills。规划过于开放让 LLM 完全自由规划容易产生幻觉或调用不存在的 Skill。务必用system prompt严格限制其可用的 Skill 列表和输出格式。无限循环Agent 可能陷入“规划-失败-重新规划”的死循环。必须设置最大迭代次数max_steps并设计有效的反思逻辑来跳出循环。成本失控每次规划和反思都可能调用 LLM产生费用。对于固定流程用工作流引擎对于可变流程缓存规划结果避免相同任务重复规划。忽视验证不要完全相信 Agent 的最终输出尤其是涉及事实、数据或重要决策时。建立人工审核或关键结果自动验证的机制。回到开奶茶店的故事一个成功的店长Agent不仅因为他聪明更因为他手下有一批靠谱的员工Skill并且店里有一套行之有效的操作流程工作流。构建 AI 应用也是如此平衡好“智能”与“确定”才能做出真正有用的系统。
返回列表