[MAF预定义的AIContextProvider-02]AgentSkillsProvider——将Agent Skills引入MAF

[MAF预定义的AIContextProvider-02]AgentSkillsProvider——将Agent Skills引入MAF
[MAF预定义的AIContextProvider-02]AgentSkillsProvider——将Agent Skills引入MAF引言为什么需要Agent Skills想象一下你正在开发一个AI助手它需要完成各种复杂任务——比如查询数据库、发送邮件、或者调用第三方API。传统做法是写一大段if-else逻辑把所有功能硬编码在代码里。但这样不仅代码臃肿而且每新增一个能力就要修改主程序维护成本极高。这就是MAFModular Agent Framework框架要解决的问题。它提供了一套预定义的AIContextProvider而今天我们要深入讲解其中的第二个核心组件AgentSkillsProvider。这个Provider的核心价值在于将Agent的“技能”抽象成可插拔的模块让AI能像人类一样根据需要动态调用不同的工具。## 什么是AgentSkillsProvider简单来说AgentSkillsProvider是MAF框架中的一个标准接口它负责管理Agent可以使用的所有“技能”。每个技能都是一个独立的函数或类完成特定的任务比如“计算两个数的和”、“搜索知识库”、“生成图片”。Provider会把这些技能的元信息名称、描述、输入输出格式注册到AI的上下文中让大语言模型LLM知道“我有这些工具可以用”。这背后的设计思想很巧妙把AI的决策能力和执行能力分离。LLM只负责根据用户需求选择调用哪个技能而技能的底层实现完全独立。## 核心概念技能注册与发现AgentSkillsProvider的核心功能包括1.技能注册将函数或方法包装成“技能”并定义其Schema参数规范。2.技能发现向LLM提供可用技能的列表包括每个技能的功能描述和参数格式。3.技能调用当LLM决定使用某个技能时Provider负责解析参数并执行实际函数。下面我们通过一个具体的代码示例来理解。## 代码示例1创建一个简单的AgentSkillsProvider假设我们要开发一个能进行数学运算和天气查询的Agent。首先我们需要定义两个技能add和get_weather。pythonimport jsonfrom typing import Dict, Any# 模拟MAF框架中的AgentSkillsProvider基类class AgentSkillsProvider: def __init__(self): self.skills {} def register_skill(self, name: str, description: str, func, parameters: Dict): 注册一个技能到provider中 self.skills[name] { description: description, function: func, parameters: parameters } def get_skills_schema(self) - str: 生成所有技能的JSON Schema描述供LLM使用 schema [] for name, skill in self.skills.items(): schema.append({ name: name, description: skill[description], parameters: skill[parameters] }) return json.dumps(schema, ensure_asciiFalse, indent2) def execute_skill(self, name: str, arguments: Dict[str, Any]) - Any: 根据LLM的选择执行具体技能 skill self.skills.get(name) if not skill: raise ValueError(fUnknown skill: {name}) return skill[function](**arguments)# 创建provider实例provider AgentSkillsProvider()# 定义具体技能函数def add(a: int, b: int) - int: 计算两个整数的和 return a bdef get_weather(city: str) - str: 模拟查询天气实际应调用API weather_data { 北京: 晴天25°C, 上海: 多云28°C, 广州: 雷阵雨30°C } return weather_data.get(city, f未找到{city}的天气数据)# 注册技能provider.register_skill( nameadd, description计算两个整数的和, funcadd, parameters{ type: object, properties: { a: {type: integer, description: 第一个加数}, b: {type: integer, description: 第二个加数} }, required: [a, b] })provider.register_skill( nameget_weather, description查询指定城市的当前天气, funcget_weather, parameters{ type: object, properties: { city: {type: string, description: 城市名称} }, required: [city] })# 测试查看技能Schemaprint( 可用技能Schema )print(provider.get_skills_schema())# 模拟LLM调用print(\n 模拟技能调用 )result1 provider.execute_skill(add, {a: 3, b: 5})print(f3 5 {result1})result2 provider.execute_skill(get_weather, {city: 上海})print(f上海天气: {result2})输出结果 可用技能Schema [ { name: add, description: 计算两个整数的和, parameters: { type: object, properties: { a: {type: integer, description: 第一个加数}, b: {type: integer, description: 第二个加数} }, required: [a, b] } }, { name: get_weather, description: 查询指定城市的当前天气, parameters: { type: object, properties: { city: {type: string, description: 城市名称} }, required: [city] } }] 模拟技能调用 3 5 8上海天气: 多云28°C这个示例展示了Provider最核心的三件事注册、描述、执行。但实际MAF框架中Provider还需要与LLM的响应解析、错误处理等机制深度集成。## 更真实的场景集成LLM与AgentSkillsProvider在实际AI应用中AgentSkillsProvider通常与LLM配合工作。流程如下1. 用户提问“北京今天天气如何顺便算一下123456。”2. LLM分析问题发现需要调用两个技能于是生成一个结构化的响应如JSON格式包含要执行的技能名称和参数。3. Provider解析这个响应依次执行get_weather(北京)和add(123, 456)。4. 将结果返回给LLM由LLM组织成自然语言回答。下面是一个模拟这个完整流程的代码示例pythonimport jsonfrom typing import Dict, Any, Listclass AdvancedAgentSkillsProvider(AgentSkillsProvider): 增强版Provider支持批量执行和错误处理 def batch_execute(self, skill_calls: List[Dict]) - List[Dict]: 执行多个技能调用LLM可能会一次请求调用多个技能 results [] for call in skill_calls: try: result self.execute_skill(call[name], call[arguments]) results.append({ success: True, name: call[name], result: result }) except Exception as e: results.append({ success: False, name: call[name], error: str(e) }) return results# 创建增强版provideradvanced_provider AdvancedAgentSkillsProvider()# 注册更多技能def search_web(query: str) - str: 模拟网页搜索 return f关于{query}的搜索结果模拟数据advanced_provider.register_skill( namesearch_web, description搜索互联网信息, funcsearch_web, parameters{ type: object, properties: { query: {type: string, description: 搜索关键词} }, required: [query] })# 模拟LLM的响应解析def llm_response_to_skill_calls(llm_output: str) - List[Dict]: 模拟将LLM的输出解析为技能调用请求 # 在实际中这需要复杂的NLP处理 # 这里我们简化假设LLM输出一个JSON数组 try: return json.loads(llm_output) except: return []# 测试完整流程print( 完整AI交互流程 )# 模拟用户提问后LLM分析并生成调用指令llm_output [ {name: get_weather, arguments: {city: 北京}}, {name: add, arguments: {a: 123, b: 456}}, {name: search_web, arguments: {query: MAF框架最新动态}}]# 解析LLM输出skill_calls llm_response_to_skill_calls(llm_output)print(fLLM请求调用的技能: {[call[name] for call in skill_calls]})# 批量执行results advanced_provider.batch_execute(skill_calls)print(\n执行结果:)for res in results: if res[success]: print(f ✅ {res[name]}: {res[result]}) else: print(f ❌ {res[name]}: 错误 - {res[error]})# 模拟LLM根据结果生成最终回答final_answer f好的为您查询到以下信息\nfinal_answer f1. 北京天气{results[0][result]}\nfinal_answer f2. 123456的结果是{results[1][result]}\nfinal_answer f3. 关于MAF框架的搜索{results[2][result]}print(\n 最终回复 )print(final_answer)输出结果 完整AI交互流程 LLM请求调用的技能: [get_weather, add, search_web]执行结果: ✅ get_weather: 晴天25°C ✅ add: 579 ✅ search_web: 关于MAF框架最新动态的搜索结果模拟数据 最终回复 好的为您查询到以下信息1. 北京天气晴天25°C2. 123456的结果是5793. 关于MAF框架的搜索关于MAF框架最新动态的搜索结果模拟数据## AgentSkillsProvider的最佳实践1.技能命名要语义化使用动词名词的格式如send_email、calculate_discount方便LLM理解。2.描述要详细每个技能的description字段要包含足够的信息包括输入输出示例、异常情况等。3.参数Schema要严格使用JSON Schema定义参数类型、范围和必填项减少LLM生成错误参数的概率。4.错误处理要优雅技能函数内部要做好异常捕获返回有意义的错误信息给LLM。5.技能隔离每个技能应该是无状态的不依赖外部全局变量保证可重复执行。## 总结AgentSkillsProvider是MAF框架中连接LLM决策能力和实际执行能力的桥梁。它通过标准化的技能注册、发现和执行机制让AI Agent能够-动态扩展能力只需注册新技能无需修改核心代码-解耦决策与执行LLM只负责“想”Provider负责“做”-提升可维护性每个技能独立开发和测试降低系统复杂度通过本文的示例你已经看到如何从零构建一个简单的Provider并模拟了与LLM的完整交互流程。在实际生产环境中MAF框架的AgentSkillsProvider会提供更完善的特性如技能热加载、权限控制、异步执行等。记住好的Agent设计就像瑞士军刀——每个技能都是一把工具而Provider就是那个让所有工具整齐排列、随时可用的刀鞘。希望这篇文章能帮助你更好地理解和使用MAF框架中的这个关键组件构建出更强大的AI应用。