写了 10 个 Agent Skill 后,我把 300 行重复代码压到了 30 行
1. 引言在最近的一个 AI Agent 项目中我陆续编写了 10 个不同的 Agent Skill。每个 Skill 都负责一个独立的业务能力比如查询天气、发送邮件、调用内部 API、解析文档等。写第一个 Skill 时很顺畅写第二个也还行但写到第五个时我发现自己陷入了 CtrlC / CtrlV 的泥潭。每个 Skill 都包含几乎相同的模板代码参数校验、错误处理、日志记录、结果格式化……10 个 Skill 下来光这些重复的“骨架”代码就堆了将近 300 行。这不仅让代码库变得臃肿更可怕的是——每次要修改公共逻辑比如统一日志格式就得手动改 10 个文件。于是我决定重构。最终通过抽象公共基类和装饰器模式我把这 300 行重复代码压缩到了 30 行。这篇文章就来分享我是怎么做到的。2. 问题重现一个典型的 Agent Skill 长什么样先看一个典型的 Skill 实现。假设我们有一个WeatherSkill用于查询天气classWeatherSkill:def__init__(self,name:strweather):self.namename self.loggerlogging.getLogger(self.name)defcan_handle(self,intent:str)-bool:returnintentquery_weatherdefexecute(self,params:dict)-dict:# 参数校验ifcitynotinparams:return{success:False,error:Missing city parameter}# 业务逻辑try:resultself._query_weather(params[city])# 结果格式化return{success:True,data:result}exceptExceptionase:self.logger.error(fFailed to query weather:{e})return{success:False,error:str(e)}def_query_weather(self,city:str)-dict:# 实际的 API 调用return{temperature:25,condition:sunny}看起来还不错但当你写出第 2 个、第 3 个 Skill 时你会发现__init__、can_handle、execute里的参数校验、异常捕获、日志记录、返回格式——这些代码几乎一模一样。3. 重复代码的统计与分析我整理了 10 个 Skill 的代码统计了重复部分重复模块每个 Skill 行数10 个 Skill 总行数__init__初始化3 行30 行can_handle意图匹配3 行30 行execute参数校验5 行50 行executetry-except 包裹6 行60 行日志记录4 行40 行结果格式化3 行30 行其他类型注解、文档字符串等6 行60 行合计30 行300 行核心业务逻辑真正的 API 调用、数据处理只占每个 Skill 的 20% 左右。80% 的代码都是“基础设施”。4. 重构方案抽象基类 装饰器我的目标是让每个 Skill 只写业务逻辑其余全部由框架自动完成。4.1 定义抽象基类首先创建一个BaseSkill把公共逻辑全部收进来importloggingfromabcimportABC,abstractmethodfromfunctoolsimportwrapsclassBaseSkill(ABC):def__init__(self,name:strNone):self.namenameorself.__class__.__name__.lower()self.loggerlogging.getLogger(self.name)defcan_handle(self,intent:str)-bool:# 默认通过类名匹配子类可覆盖returnintentself.namedefexecute(self,params:dict)-dict:# 统一的执行入口自动包裹校验和异常处理try:self._validate(params)resultself._execute(params)returnself._format_result(result)exceptExceptionase:self.logger.error(fExecution failed:{e},exc_infoTrue)return{success:False,error:str(e)}def_validate(self,params:dict):子类可重写默认不做校验passabstractmethoddef_execute(self,params:dict)-dict:子类必须实现真正的业务逻辑passdef_format_result(self,result:dict)-dict:子类可重写默认包装为成功响应return{success:True,data:result}4.2 用装饰器处理参数校验对于需要参数校验的 Skill我写了一个装饰器避免在每个_execute里写 if-elsedefrequire_params(*required_keys):defdecorator(func):wraps(func)defwrapper(self,params:dict,*args,**kwargs):missing[kforkinrequired_keysifknotinparams]ifmissing:raiseValueError(fMissing required parameters:{missing})returnfunc(self,params,*args,**kwargs)returnwrapperreturndecorator4.3 重构后的 Skill 长什么样现在一个 Skill 只需要 3 行核心代码classWeatherSkill(BaseSkill):require_params(city)def_execute(self,params:dict)-dict:return{temperature:25,condition:sunny}另一个 Skill 也类似classEmailSkill(BaseSkill):def__init__(self):super().__init__(namesend_email)require_params(to,subject,body)def_execute(self,params:dict)-dict:# 真正的发邮件逻辑return{message_id:12345,status:sent}5. 效果对比重构前后对比指标重构前重构后每个 Skill 平均代码行数30 行3 行10 个 Skill 总行数300 行30 行公共逻辑修改改 10 个文件改 1 个基类新增一个 Skill 成本30 行模板 业务3 行业务单元测试覆盖难模板代码干扰易只测业务更重要的是可维护性得到了质的提升。后来我又加了 5 个 Skill每个只花了 5 分钟写业务逻辑再也不用复制粘贴了。6. 总结与思考这次重构让我深刻体会到重复代码是万恶之源。当你在写第 3 个相似的类/函数时就该停下来思考抽象方案了。抽象基类 装饰器是消除 Agent Skill 模板代码的绝佳组合。基类负责骨架装饰器负责横切关注点参数校验、权限检查等。不要过度抽象。我的原则是只有出现 3 次以上重复时才考虑抽象。过早抽象反而会增加理解成本。代码行数不是唯一目标。虽然从 300 行压到了 30 行但更重要的是代码的可读性和可维护性。30 行清晰的代码远胜 300 行重复的代码。如果你也在写 Agent 或类似的插件化系统不妨试试这个模式。你会发现写代码可以是一件很清爽的事。

相关新闻

QgsSingleBandPseudoColorRenderer 完整详解(QGIS 3.40.13 C++)

QgsSingleBandPseudoColorRenderer 完整详解(QGIS 3.40.13 C++)

一、基础定位、头文件、继承关系 1. 引入头文件 #include <qgssinglebandpseudocolorrenderer.h>2. 继承链 QgsRasterRenderer↳ QgsSingleBandRenderer↳ QgsSingleBandPseudoColorRendererQgsRasterRenderer&#xff1a;栅格渲染器顶层抽象基类&#xff0c;所有栅格渲染…

2026/7/24 4:23:10 阅读更多 →
Qwen3-8B大模型本地化部署与vLLM优化实践

Qwen3-8B大模型本地化部署与vLLM优化实践

1. 项目背景与核心价值 在当前的AI技术浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;的本地化部署正成为开发者关注的焦点。Qwen3-8B作为通义千问团队推出的80亿参数开源模型&#xff0c;在中文理解和生成任务上展现出接近商用闭源模型的性能。而vLLM作为UC Berkel…

2026/7/24 5:35:35 阅读更多 →
Typora如何设置字体颜色

Typora如何设置字体颜色

1. 需要打开文件的偏好设置——>markdown扩展语法中——>勾选内联公式。2. 在编辑器中&#xff0c;使用 $\textcolor{颜色}{.......}$ latex语法即可修改颜色​举例&#xff1a;我想要把hello world修改成红色。$\textcolor{red}{hello world}$输入后敲击回车&#xff…

2026/7/24 7:07:20 阅读更多 →

最新新闻

为什么 DCD 分配向量表时,函数地址要加 1(LSB=1)?

为什么 DCD 分配向量表时,函数地址要加 1(LSB=1)?

难度:★★ 本文首发于我的嵌入式技术号「OneChan」,未经授权禁止转载。 打开任何一个 Cortex-M3 的启动文件,查看向量表,你会看到类似这样的代码: __Vectors DCD __initial_sp ; 0x00000000:栈顶DCD Reset_Handler ; 0x00000004:复位入口…

2026/7/25 0:54:57 阅读更多 →
Chrome滚动截图终极指南:如何一键保存完整网页内容

Chrome滚动截图终极指南:如何一键保存完整网页内容

Chrome滚动截图终极指南&#xff1a;如何一键保存完整网页内容 【免费下载链接】full-page-screen-capture-chrome-extension One-click full page screen captures in Google Chrome 项目地址: https://gitcode.com/gh_mirrors/fu/full-page-screen-capture-chrome-extensio…

2026/7/25 0:54:57 阅读更多 →
ncmdump终极指南:5分钟免费解锁网易云音乐加密NCM文件

ncmdump终极指南:5分钟免费解锁网易云音乐加密NCM文件

ncmdump终极指南&#xff1a;5分钟免费解锁网易云音乐加密NCM文件 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否在网易云音乐下载了心爱的歌曲&#xff0c;却发现只能在网易云音乐App中播放&#xff1f;NCM加密格式就像一把…

2026/7/25 0:54:57 阅读更多 →
深挖Superpowers 6.0 SDD重写,Token砍半不是优化,是Agent工程的底层范式革新

深挖Superpowers 6.0 SDD重写,Token砍半不是优化,是Agent工程的底层范式革新

在AI编程工具高速迭代的当下&#xff0c;绝大多数版本更新都逃不开常规优化的套路&#xff0c;无非是修复已知bug、小幅提升运行速度、微调资源消耗。前不久Superpowers推出的v6.0.0版本&#xff0c;后续又快速迭代v6.0.3修复版&#xff0c;官方给出的核心数据格外亮眼&#xf…

2026/7/25 0:54:57 阅读更多 →
开放式耳机性价比高有哪些?2026年十大高性价比开放式耳机推荐

开放式耳机性价比高有哪些?2026年十大高性价比开放式耳机推荐

因为开放式耳机真的好用&#xff0c;但只适合“对的人”。它没有入耳式的闷耳、胀痛&#xff0c;没有头戴式的笨重、闷热&#xff0c;更兼顾了听力友好和场景安全。开放式耳机不用塞进耳道&#xff0c;耳道通畅&#xff0c;不用担心堵耳&#xff0c;不闷不胀&#xff0c;不滋生…

2026/7/25 0:53:57 阅读更多 →
高性价比的开放式耳机有哪些?十大公认高性价比的开放式耳机推荐

高性价比的开放式耳机有哪些?十大公认高性价比的开放式耳机推荐

在当下的耳机品类里&#xff0c;开放式耳机无疑占据着极高热度。伴随声学技术不断迭代升级&#xff0c;大众对耳机的使用要求也变得更加精细化&#xff0c;开放式耳机也跳出了过去小众的定位&#xff0c;慢慢成为通勤出行、日常办公以及运动健身场景里的必备数码单品。那么&…

2026/7/25 0:53:57 阅读更多 →

日新闻

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制&#xff1a;kill-doc让你看到的都能保存 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档&#xff0c;但是相关网站浏览体验不好各种广告&#xff0c;各种登录验证&#xff0c;需要很多步骤才能下载文档&#xff0c;该脚本就是为了解决您的…

2026/7/25 0:00:35 阅读更多 →
C++ string类模拟实现:从深拷贝到内存管理的完整指南

C++ string类模拟实现:从深拷贝到内存管理的完整指南

1. 项目概述&#xff1a;为什么我们要“手撕”string类&#xff1f;在C的学习道路上&#xff0c;尤其是从C语言过渡到C的“初阶”阶段&#xff0c;string类绝对是一个绕不开的核心。标准库里的std::string用起来太方便了&#xff0c;、find、substr&#xff0c;几个操作符和函数…

2026/7/25 0:00:35 阅读更多 →
三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

1. 先搞清楚“三角洲寻宝鼠”到底是什么工具从名称来看&#xff0c;“三角洲寻宝鼠”更像是一个资源查找或文件检索类工具&#xff0c;而不是游戏或娱乐软件。这类工具的核心价值在于帮助用户快速定位特定资源&#xff0c;比如文档、图片、压缩包或特定格式的文件。如果你经常需…

2026/7/25 0:00:35 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中&#xff0c;我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源&#xff0c;还是配置文件、证书等&#xff0c;都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下&#xff0c;但这…

2026/7/24 3:59:20 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP&#xff08;轻量级目录访问协议&#xff09;作为企业级身份认证的黄金标准&#xff0c;已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时&#xff0c;发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 1:23:39 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”&#xff0c;而是以可解释、可审计、可迭代的方式&#xff0c;赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 18:52:18 阅读更多 →

月新闻