十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

手搓一个代码审查插件——Harness 插件开发没有你想的那么玄乎

手搓一个代码审查插件——Harness 插件开发没有你想的那么玄乎 你别说我刚开始接触 Harness 的插件系统时第一反应是——又要写一堆接口适配了吧毕竟之前搞过一些平台的插件开发光是注册、回调、生命周期钩子就能把人绕晕。结果打开 Harness 的插件开发文档一看一个插件就是一个函数。笑死白紧张了。先说我为什么非要自己写个插件事情是这样的。我们团队有个代码审查的流程——PR 提交之后自动跑一遍静态分析、检查代码风格、再扫一遍安全漏洞。之前用的是 GitLab CI 里挂了一堆脚本每次改流水线配置都得找 DevOps 的人烦得很。我就想能不能让 Agent 自己干这事把代码审查的逻辑封装成一个插件Harness 跑任务的时候只要 Agent 觉得这步需要审查就自动调我的插件去跑。这个想法说实话挺野的但 Harness 的插件架构天生就是干这个的——它的核心理念是一切皆插件Agent 的工具链、执行器、甚至模型调用都可以是插件。那我写一个代码审查插件本质上就是在它这套框架里多加一个工具箱。一个插件到底长什么样Harness 的插件分两层插件定义告诉系统我这个插件能干什么和插件实现真正干活的那段逻辑。先说定义层。插件定义就是一个 JSON 结构体描述你的插件的名称、入参、出参和调用方式。我写代码审查插件定义大概是这样的{ name: code-reviewer, version: 0.1.0, description: 对指定代码仓库进行自动审查返回审查意见列表, inputs: { repo_path: { type: string, description: 本地仓库路径 }, target_branch: { type: string, description: 目标分支默认 main }, rules: { type: array, description: 启用的审查规则列表 } }, outputs: { issues: { type: array, description: 发现的问题列表 }, summary: { type: string, description: 审查摘要 } } }这里有个我觉得很舒服的设计——入参和出参都是声明式的你不用手动处理序列化反序列化Harness 的运行时负责帮你把输入参数注入进来把输出结果接走。然后是实现层。Harness 插件支持的语言有 Python 和 TypeScript 两种我选了 Python因为团队里代码审查的逻辑之前就是 Python 写的直接复用。from harness.plugin import Plugin, param, output class CodeReviewer(Plugin): param(repo_path, str) param(target_branch, str, defaultmain) param(rules, list, defaultNone) output(issues, list) output(summary, str) def run(self, repo_path, target_branch, rules): # 这里就是实际干活的地方 issues [] # 规则1检查是否有调试代码残留 if not rules or debug_check in rules: debug_issues self._check_debug_code(repo_path) issues.extend(debug_issues) # 规则2检查 import 排序 if not rules or import_sort in rules: import_issues self._check_imports(repo_path) issues.extend(import_issues) # 规则3安全检查 if not rules or security in rules: sec_issues self._check_security(repo_path) issues.extend(sec_issues) summary f审查完成发现 {len(issues)} 个问题 return {issues: issues, summary: summary}第一次跑的时候我犯了个特别蠢的错——忘了给output装饰器传参数类型。结果插件跑完了Harness 说拿不到输出日志里全是 key error。查了半天才发现output(issues, list)里那个list不能省它是运行时做类型校验和序列化的依据。这个坑踩得我有点无语但想想也合理——没有类型信息Agent 怎么知道输出该怎么用把插件挂到 Harness 任务里插件写好了怎么让 Agent 在任务里用它Harness 有个叫plugin_registry的概念你注册了插件之后Agent 的能力列表里就多了一项可以调用 code-reviewer。然后在任务配置文件里声明一下tools: - name: code-reviewer config: rules: [debug_check, import_sort, security]然后神奇的事情发生了——Agent 在跑代码审查任务的时候会自动判断什么时候该调用这个插件。比如它先git diff拿到变更文件然后觉得嗯这步应该让 code-reviewer 来审一下就会调用插件并把结果写进上下文。有意思的是我第一次跑的时候Agent 调了两次插件——一次审了全部文件一次又单独审了某个变更特别大的文件。我原本以为它会一次审完结果它觉得这个文件变更量太大值得单独审一轮。这种插件怎么用的决策权其实在 Agent 手里插件作者只负责把能力提供好就行。现在的插件生态还差点什么说实话目前 Harness 的插件生态还在早期。官方仓库里只有十几个插件而且大部分是很基础的——文件读写、Shell 执行、HTTP 请求这些。像代码审查、自动化测试、部署检查这类行业插件基本都得自己写。文档也是一个槽点。插件开发文档写得还算清楚但示例代码太少了而且缺少从零到一的完整教程。我写这个插件的时候光是搞清楚plugin和tool两种装饰器的区别就翻了好几个 issue。不过换个角度想这也说明现在入局做插件贡献的人能吃到早期的生态红利。Harness 在推社区插件市场如果你写了一个质量不错的插件官方会帮你推广。我打算把这个代码审查插件整理一下提个 PR 到官方仓库。写在最后插件开发这块其实门槛真的不高。如果你写过 Flask 的路由或者 FastAPI 的接口那 Harness 的插件开发你十分钟就能上手。核心就是定义一个 JSON 描述写一个函数注册到 registry三步走完。我好奇的是——你们团队有没有什么频繁重复的运维或开发工作是觉得要是能有个 Agent 插件自动干就好了的评论区聊聊说不定下一期我就写你那个场景
返回列表