使用RexUniNLU构建Skills智能体开发框架你是不是也遇到过这样的场景想给公司内部开发一个智能助手让它能处理各种杂事比如查个数据、做个报表、回答员工问题甚至还能根据邮件内容自动安排会议。听起来挺美好但真动手做起来头就大了。每个功能或者说每个“技能”都得单独开发一套自然语言理解模块。查天气是一个模型查数据库是另一个模型做日程安排又得换一个。模型之间数据格式不统一代码重复率高维护起来简直是噩梦。更别提让这些技能之间还能互相配合、串联执行了。今天要聊的就是用RexUniNLU这个模型来搭建一个统一的Skills智能体开发框架。它的核心思路很简单用一个模型理解所有任务。你不用再为每个技能单独训练和维护模型只需要定义好这个技能需要做什么剩下的理解工作交给RexUniNLU就行。1. 为什么需要Skills智能体框架在深入技术细节之前我们先看看传统做法有多麻烦。想象一下你要开发一个内部办公助手它需要具备以下技能技能A查询员工信息输入“张三的电话是多少”输出电话号码技能B预订会议室输入“帮我预订明天下午两点的大会议室”输出预订成功与否技能C生成周报摘要输入“把上周销售部的周报总结一下”输出摘要文本如果用传统方法你大概需要这么做为技能A训练一个命名实体识别模型来识别“张三”再训练一个文本分类模型来判断这是“查询电话”的意图。为技能B训练一个模型来识别“明天下午两点”、“大会议室”这些时间和地点实体再训练一个意图模型判断是“预订”动作。为技能C训练一个文本摘要模型。写三套不同的代码来处理这三个模型的输入输出还得写一个复杂的“路由”逻辑来判断用户输入到底该交给哪个技能处理。结果就是一堆模型、一堆代码、维护成本极高而且很难增加新技能。而基于RexUniNLU的Skills框架思路完全不同。RexUniNLU本身是一个“零样本通用自然语言理解”模型简单说它可以通过你定义的“任务模板”Schema直接理解文本并输出结构化的结果不需要针对每个任务进行专门训练。在这个框架下开发一个新技能就变成了定义技能用JSON格式描述这个技能需要从用户输入中提取什么信息。注册技能把这个描述注册到框架的技能库里。编写执行函数写一个简单的函数接收框架提取好的结构化信息去执行具体操作比如查数据库、调用API。框架会自动用RexUniNLU模型根据你定义的描述去理解用户输入然后把提取的结果交给对应的执行函数。路由、理解、提取这些最复杂的部分框架和模型帮你搞定了。2. RexUniNLU一个模型理解万物RexUniNLU的核心能力在于它的“零样本”和“通用性”。它基于一种叫SiamesePrompt的框架把各种不同的自然语言理解任务比如实体识别、关系抽取、分类、问答等都统一成了“根据提示Prompt从文本Text中抽取信息”的模式。对我们开发者来说最直观的体验就是它的调用方式。你不需要懂复杂的模型原理只需要通过一个叫schema的东西告诉它你想干什么。举个例子如果我想让模型从一句话里找出人名、地点和组织机构传统的做法是准备大量标注数据去训练一个NER模型。用RexUniNLU代码是这样的from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks # 初始化模型管道 nlp_pipeline pipeline(Tasks.siamese_uie, iic/nlp_deberta_rex-uninlu_chinese-base) # 定义我要抽取的 schema告诉模型请找出“人物”、“地理位置”、“组织机构” input_text 苹果公司CEO蒂姆·库克近日访问了位于硅谷的谷歌总部。 my_schema { 人物: None, 地理位置: None, 组织机构: None } # 调用模型 result nlp_pipeline(input_text, schemamy_schema) print(result)运行后你可能会得到类似这样的结构化结果{ 人物: [蒂姆·库克], 地理位置: [硅谷], 组织机构: [苹果公司, 谷歌] }看到了吗我没有提供任何关于“蒂姆·库克”是人名、“硅谷”是地点的训练数据。我只是通过schema告诉了模型“我想要这些类型的信息”模型就自己理解并抽取出来了。这就是“零样本”的魅力。这种能力正是构建Skills智能体框架的基石。每个技能本质上就是一套特定的schema和一个对应的执行动作。3. 动手搭建Skills智能体框架理论说再多不如动手。我们来一步步搭建一个最简单的框架原型。这个框架主要包含三个部分技能注册中心、统一理解引擎和技能执行器。3.1 环境准备首先确保你的Python环境已经安装了ModelScope库。pip install modelscope如果你的网络环境需要配置请参考官方文档进行设置。这里我们使用CPU环境进行演示实际生产环境建议使用GPU以获得更好的速度。3.2 核心框架代码我们来创建一个名为skills_agent.py的文件。# skills_agent.py from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks from typing import Dict, Any, Callable import json class SkillsAgent: def __init__(self): 初始化Skills智能体。 加载RexUniNLU模型作为统一理解引擎。 print(正在加载RexUniNLU模型...) # 创建自然语言理解管道 self.nlp_engine pipeline(Tasks.siamese_uie, iic/nlp_deberta_rex-uninlu_chinese-base) print(模型加载完成) # 技能注册表key为技能名value为字典包含schema和执行函数 self.skills_registry {} def register_skill(self, skill_name: str, schema: Dict, action_func: Callable): 注册一个新技能。 参数: skill_name: 技能名称如 query_weather schema: 该技能对应的RexUniNLU schema定义 action_func: 技能执行函数接收模型提取的结果返回执行结果 self.skills_registry[skill_name] { schema: schema, action: action_func } print(f技能 {skill_name} 注册成功。) def parse_user_input(self, user_input: str): 核心方法理解用户输入并分发给对应技能。 步骤 1. 遍历所有已注册的技能。 2. 用每个技能的schema去尝试理解用户输入。 3. 选择抽取结果最“丰满”非空项最多的技能作为匹配技能。 4. 调用该技能的执行函数。 if not self.skills_registry: return 抱歉目前没有可用的技能。 best_match None best_result None best_skill_name None # 第一步尝试用每个技能的schema去理解输入 for skill_name, skill_info in self.skills_registry.items(): schema skill_info[schema] try: # 调用RexUniNLU模型进行理解 nlu_result self.nlp_engine(user_input, schemaschema) # 简单评估匹配度计算非空抽取项的数量 score self._evaluate_result(nlu_result) # 选择匹配度最高的技能 if score 0 and (best_match is None or score best_match): best_match score best_result nlu_result best_skill_name skill_name except Exception as e: print(f技能 {skill_name} 理解过程出错: {e}) continue # 第二步执行匹配的技能 if best_skill_name: print(f匹配到技能: {best_skill_name}) print(f理解结果: {json.dumps(best_result, ensure_asciiFalse, indent2)}) action_func self.skills_registry[best_skill_name][action] try: # 将模型理解的结果传给技能执行函数 final_result action_func(best_result) return final_result except Exception as e: return f执行技能 {best_skill_name} 时出错: {e} else: return 抱歉我没有理解您的意思或者没有匹配到合适的技能。 def _evaluate_result(self, result: Dict) - int: 简单评估模型抽取结果的质量。 这里采用一个简单的启发式方法计算非空列表的数量。 你可以根据实际情况设计更复杂的匹配度算法。 if not result: return 0 score 0 for key, value in result.items(): if isinstance(value, list) and len(value) 0: score 1 return score # 示例技能执行函数 def query_employee_action(extracted_info): 查询员工信息的技能执行函数 # extracted_info 是模型抽取的结果例如 {人物: [张三], 信息类型: [电话]} person extracted_info.get(人物, [未知])[0] info_type extracted_info.get(信息类型, [未知])[0] # 这里应该是真实的数据库查询这里用模拟数据代替 employee_db { 张三: {电话: 13800138000, 部门: 技术部}, 李四: {电话: 13900139000, 部门: 市场部} } if person in employee_db: info employee_db[person].get(info_type, 未知信息) return f{person}的{info_type}是{info} else: return f未找到员工 {person} 的信息。 def book_meeting_room_action(extracted_info): 预订会议室的技能执行函数 # extracted_info 可能是 {时间: [明天下午两点], 会议室: [大会议室]} time extracted_info.get(时间, [未知时间])[0] room extracted_info.get(会议室, [未知会议室])[0] # 模拟预订逻辑 return f已为您成功预订{room}时间{time}。预订编号MTG20231027001 # 主程序 if __name__ __main__: # 1. 创建智能体实例 agent SkillsAgent() # 2. 注册技能 # 技能1查询员工信息 agent.register_skill( skill_namequery_employee, schema{ 人物: None, 信息类型: None }, action_funcquery_employee_action ) # 技能2预订会议室 agent.register_skill( skill_namebook_meeting_room, schema{ 时间: None, 会议室: None }, action_funcbook_meeting_room_action ) print(\n Skills智能体已就绪 ) print(已加载技能查询员工信息、预订会议室) print(输入 退出 结束对话\n) # 3. 交互循环 while True: user_input input(\n您说) if user_input.lower() in [退出, exit, quit]: print(再见) break response agent.parse_user_input(user_input) print(f助手{response})3.3 运行与测试保存文件后直接运行python skills_agent.py你会看到模型加载的提示然后进入交互界面。可以尝试输入“张三的电话是多少”“帮我订一下明天下午两点的大会议室”“李四是哪个部门的”看看智能体是如何理解并调用不同技能来回答的。虽然示例很简单但你已经拥有了一个可扩展的智能体框架核心。4. 从原型到实用框架的增强与优化上面的原型展示了核心思想但要投入实际使用还需要在以下几个方面进行增强4.1 更精准的技能路由原型里用“非空项最多”来匹配技能太粗糙了。在实际场景中我们需要更智能的路由。意图分类辅助可以训练或使用一个简单的意图分类模型作为第一道过滤器快速判断用户意图属于哪个大类再调用对应的技能schema进行精细抽取。Schema动态组合对于复杂查询可以设计一个“主技能”schema它能识别出是否需要调用其他“子技能”。比如用户说“查一下张三的电话然后帮他预订明天下午的会议室”框架可以识别出这是一个复合任务并分解执行。4.2 技能执行的流水线与上下文真正的智能体需要处理多轮对话和上下文。状态管理为每个对话会话维护一个上下文状态。例如上一句问了“张三的电话”下一句只说“那他邮箱呢”框架需要能记住“他”指代“张三”并补充“信息类型”为“邮箱”。技能流水线允许技能的输出作为另一个技能的输入。比如先执行“查询项目信息”技能得到项目ID再自动触发“查询项目成员”技能。4.3 易用性提升技能声明式注册为了让业务开发者更容易添加技能可以设计一种声明式的技能注册方式比如使用YAML文件skills: - name: query_weather description: 查询城市天气 schema: 城市: None 时间: None action: weather_module.get_weather sample_phrases: - 北京今天天气怎么样 - 明天上海会下雨吗框架启动时自动加载这些YAML文件完成技能注册。开发者只需要关注schema的定义和action函数的实现。4.4 处理模型的不确定性RexUniNLU虽然是零样本但也不是万能的。对于模糊或复杂的输入它的抽取结果可能不准或为空。置信度反馈可以修改框架让模型返回抽取的置信度。对于低置信度的结果智能体可以反问用户确认比如“您是想查询‘张三’的电话吗”多技能备选不只看最佳匹配保留2-3个候选技能如果最佳技能执行失败可以尝试备选方案。5. 实际应用场景与价值这样一个基于RexUniNLU的Skills框架特别适合哪些场景呢企业内部助手这是最直接的场景。快速集成OA、CRM、ERP系统的查询能力。新员工想了解公司制度注册一个“查询制度”技能schema定义{制度主题: None}后端连接到知识库即可。智能客服机器人客服问题虽然多样但大多可归类。用框架管理“退货”、“查物流”、“投诉”等技能比训练一个庞大的端到端模型更可控、更易更新。低代码自动化平台你可以提供一个可视化界面让业务人员自己“画”出一个技能选择要抽取的字段对应schema配置一个后续动作对应action函数。平台底层自动调用RexUniNLU和你的框架实现“描述即生成”的智能流程。个人效率工具给自己做一个桌面助手集成“记笔记”、“设提醒”、“搜文件”等个人技能。由于框架的轻量化和易扩展性添加新功能非常快捷。它的核心价值在于统一和解耦。统一了自然语言理解层用一个模型应对千变万化的需求解耦了语言理解和业务逻辑让AI算法工程师和业务软件开发者的工作可以清晰分工并行推进。6. 总结用RexUniNLU来构建Skills智能体框架本质上是一种“模型即服务技能即插件”的思想。它把复杂的自然语言理解问题通过一个强大的通用模型和清晰的框架设计变得模块化、可管理。这种方法的优势很明显开发速度快定义schema即可、维护成本低只需维护一个核心模型、扩展性强新技能即插即用。当然它也有其边界比如极度依赖预训练模型对schema的理解能力对于逻辑推理特别复杂或需要深度领域知识的任务可能还需要结合其他技术。但无论如何对于大量常见的、以信息抽取和任务执行为导向的智能体场景这套方案提供了一个非常务实且高效的起点。你不必再从零开始造轮子而是站在一个不错的基座上去快速构建和迭代属于你自己的智能应用。下次当你再为“如何让机器理解人话”而发愁时不妨试试这个思路。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。