news 2026/10/17 8:30:19

用Git管理Agent技能库:目录契约、版本策略与评审闸门

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Git管理Agent技能库:目录契约、版本策略与评审闸门

半年多前,我所在团队的 Agent 技能库还处于一种极度随意的状态:技能包散落在共享文档和各人本地文件夹里,谁想加技能就加一份,谁想改就改一份,“最新版本”“最终修订版”这类文件名累积了几十个。表面上大家一直在扩充能力,实际上没有一个人能回答“当前线上到底跑的是哪个版本”。

转折点是一次线上事故。某个报表生成技能的提示词被改了几天,新旧两套参数格式不兼容,技能入口却没有任何版本标识,直到生产环境的流程真正调用时才暴露问题。回看改动记录只能靠聊天记录推测。从那一刻起我确定,技能的演进必须做到可追溯、可回滚、可评审,否则技能越多,事故概率只会越高。

我们最后落地的方案,是把全部技能看作一个独立的 Git 仓库来管理,并围绕它建立了目录契约、版本策略、复用方式和评审闸门。这篇文章是这套方案的完整复盘,包括它仍然存在的边界和我踩过的坑,希望对你正在搭的团队技能库有参考价值。

1. 技能库从“一人一个文件夹”变成“团队公共资产”,Git 这件事绕不过去

1.1 先说清楚:Skill 在团队语境里到底是什么

团队语境下的 Skill 和很多人理解的“一个提示词文件”不是一回事。它更像一个完整的能力单元:为 Agent 准备好某个任务所需的所有素材,包括提示词模板、执行脚本、数据清洗逻辑、输出格式定义、少样本示例和回归测试用例。

举个例子,我们团队有个“把内部表格转成周报”的技能。它不是一个 prompt 就完事的,而是由几个互相咬合的部分组成的:周报的生成指令模板、表格文件的解析脚本、输出 Markdown 的格式约束、三组历史样例如"好的周报长什么样",以及一组用来验证格式的测试用例。任何一个部分改动,都可能改变 Agent 最终输出。

很多人问,Skills 和普通代码库有什么区别?我的回答是,底层协作痛点高度一致,但 Skills 还多了两层特殊性:一是语义不确定性,一个提示词的微小改写,在模型手里的结果可能天差地别;二是单一事实来源缺失,同样的技能散落在不同人手里,总会悄悄长出不同分支。这两个特殊性会放大版本管理缺失的后果。

1.2 无版本控制的技能库会经历哪几个阶段

我观察到的失控过程基本是三个阶段。

第一阶段:个人草稿文件。技能刚起步时,一个人写一个人用,最多在文件名后面加个日期。这个阶段效率很高,问题是没办法被其他人继承。等到写的人一忙,别的人想复用只能从头再读代码,或者干脆复制一份自己改。

第二阶段:共享文件夹 + 聊天传输。团队开始协作后,共享文件夹成了重灾区。你上传一个“v2”,我覆盖成“v2_new_最终”,他用另存为改成“v2_final_really”。表面上是版本管理,实际上是靠纪律约束。真实情况是:很快就会回到手忙脚乱找文件的现场。更麻烦的是,某个技能一旦同时被多个流程引用,你根本不知道对方是在哪份副本上做的修改。

第三阶段:线上事故之后被迫重建。当 Agent 开始被业务方使用时,问题就不再是“找不到文件”,而是“生产环境跑错了版本”。我们的那次报表事故就把整个问题彻底暴露了:技能入口没问题、脚本没问题,但提示词约定发生了变化,下游解析器还是按旧约定工作,最后输出全乱。这种事故用“回滚”能处理,前提是你得有可回滚的东西——那会儿我们根本没有版本概念。

Git 在这里提供的价值不是“存个历史”,而是给技能库建立了一个可讨论、可仲裁、可回退的底层平台:每次改动有 diff 可以评审,每个历史状态有 commit 可以定位,每个稳定状态有 tag 可以回溯。技能库一旦成为团队公共资产,这些能力就不是可选项,而是必须项。

2. Skill 的“最小可交付单元”:目录与元数据契约怎么定

2.1 一个标准 Skill 仓库的最小目录结构

如果技能库是一整间仓库,那么里面每一个技能都应该是自包含的文件夹。我们最终把最小目录结构定成了这样:

skills/ ├── form-xml-to-report/ │ ├── SKILL.md │ ├── README.md │ ├── prompts/ │ │ ├── main.md │ │ └── examples.md │ ├── scripts/ │ │ └── transform.py │ ├── assets/ │ │ └── template.xlsx │ └── tests/ │ ├── cases.json │ └── expected_outputs.md

每个文件夹的命名用小写字母加连字符,全局唯一。为什么这样设计?因为技能会被很多上层 Agent 引用,名字一旦不确定,依赖关系就跟着混乱。

文件夹内各部分分工明确:

  • SKILL.md:技能元数据,是给 Agent 和同事共同看的接口;
  • README.md:给人看的使用文档,告诉用户这个技能适合什么场景、不支持什么场景;
  • prompts/:提示词模板和示例,尽量把上下文模板和示例拆开,方便单独 review;
  • scripts/:真正可执行的代码,负责数据预处理、格式转换、调用外部工具;
  • assets/:静态资源,比如表格模板、图片素材;
  • tests/:回归测试数据,用来验证技能改动后输出仍然符合预期。

这套结构的核心原则是“一个技能一个独立边界”。不要让两个技能共享一个 scripts 目录,也不要让一个技能同时依赖另一个技能内部的未声明文件。边界清晰之后,Review、回滚和权限控制才能精准落在一个技能上,而不是眉毛胡子一把抓。

2.2 元数据字段是给 Agent 和同事共同看的“接口”

如果说目录结构是仓库的骨架,SKILL.md就是技能的接口契约。它的重要性经常被低估:很多人写技能只把提示词往文件夹里一丢,觉得元数据是形式主义,但等技能数量上来,你会发现元数据恰恰是整个版本化体系里最重要的部分。

我们 SKILL.md 里维护了这些核心字段:

字段说明是否必填
id技能唯一标识,与文件夹名保持一致是
name人类可读的技能名称是
description一句话说清技能用途和适用场景是
version遵循 SemVer 的技能版本号是
api_version技能依赖运行环境的接口版本是
dependencies需要引用的其他技能或内部依赖否
inputs输入参数定义,包括类型、必选、默认值是
outputs输出结构的说明或 schema是
tags分类标签,方便检索和治理否

其中 description 是最容易被写坏也最重要的字段。Agent 会根据 description 决定什么时候调用这个技能,所以描述必须语义精确。不要写“处理表格数据”,要写“将包含销售额数据的 xlsx 文件转换为指定格式的周报 Markdown,支持合并同品类条目并计算环比”。写模糊了,Agent 就会在不需要它的时候调用它,或者在需要的时候跳过它。

version 和 api_version 分开的用意是:技能本身可能升级(version),支撑它的平台接口可能升级(api_version)。两个维度混在一起,一旦运行环境接口变化,你根本判断不了是哪个技能实例受到波及。

2.3 目录规范落地,不能只靠约定

契约定了,还要用脚本确保每个人提交前都遵守。我们仓库里放了一个check_skills.py,在 pre-commit 阶段自动跑。它的逻辑很简单:

  1. 扫描所有同名目录,检查文件夹名与 SKILL.md 里的 id 是否一致;
  2. 检查必填字段是否存在,version 是否符合语义化版本规则;
  3. 检查 prompts、scripts、tests 三个目录是否都存在;
  4. 识别是否有重复技能名或同名但 id 不同的情况。
# scripts/check_skills.py import os import re import sys from pathlib import Path REQUIRED_FIELDS = ["id", "name", "description", "version", "api_version", "inputs", "outputs"] SEMVER = re.compile(r"^\d+\.\d+\.\d+$") def parse_skill_meta(path): content = Path(path).read_text(encoding="utf-8") fields = {} for line in content.splitlines(): if ":" in line: key, value = line.split(":", 1) fields[key.strip()] = value.strip() return fields errors = [] for skill_dir in Path("skills").iterdir(): if not skill_dir.is_dir(): continue meta = parse_skill_meta(skill_dir / "SKILL.md") for field in REQUIRED_FIELDS: if field not in meta: errors.append(f"{skill_dir.name}: 缺少字段 {field}") if "version" in meta and not SEMVER.match(meta["version"]): errors.append(f"{skill_dir.name}: 版本号不是 x.y.z 格式") if meta.get("id") != skill_dir.name: errors.append(f"{skill_dir.name}: 目录名与 id 不一致") if errors: print("技能目录检查失败:") for err in errors: print(" -", err) sys.exit(1)

这段脚本第一版只做基础检查,后来才陆续加入了字段值类型、依赖声明合法性等更严格的校验。它最重要的是提供了一个“提交即校验”的反馈闭环,让目录契约不依赖人类的自觉。别小看这种简单脚本,它把“规范”从 PPT 里搬到了实际工作流里。

3. 版本化不只打 tag:分支模型、提交规范与技能回滚

3.1 分支模型:main 始终可用,feature 分支承载实验

技能库的分支模型不需要发明新花样,我们直接采用的是最稳妥的模式:长期存在main分支,技能开发和修复都在独立 feature 分支上完成,通过评审后合回主分支。

main分支的原则是“始终可用”,含义是这里面每个技能都满足最小质量要求,随时可以被业务调用。至于更好用的新版本、试验中的提示词写法,一律先进 feature 分支。不要在main上直接改东西,哪怕只是改一个词。

为什么这么苛刻?因为 Agent 技能库会被多个上层流程引用。如果 main 分支不稳定,你今天合并了一个未经验证的改动,明天另一个团队同步仓库时就会把不稳定状态带到自己的环境里。这么搞一次,大家对仓库的信任度就会崩掉。

每个 feature 分支的命名我们也做了约定:feat/<skill-id>-<改动简述>,比如feat/form-xml-to-report-add-thousands-separator。分支名承担了“改动声明”的功能,评审人一眼就看出改动范围,不会把不同技能的改动混在同一个分支里。

3.2 提交信息约定与自动生成 CHANGELOG

提交信息是团队最容易忽略但收益最大的环节。我们引入了常规提交规范(Conventional Commits),格式统一成:

<type>(<scope>): <description>

其中 type 包括feat、fix、docs、test、refactor、perf,scope 写技能 id,描述写清楚的改动原因。

实际例子:

feat(form-xml-to-report): 增加千分位格式选项,默认开启 fix(sales-summary): 修复同比字段为空时输出异常的问题 docs(data-clean): 补充中文日期格式的输入示例

这个规范最大的价值是让每一行历史都能“被脚本消费”。通过扫描提交信息,我们可以半自动生成每个技能自己的 CHANGELOG,而不是靠人手动维护文档。手动维护的文档一定会过期,提交时顺手写清楚,再让脚本汇总,才是长期可维护的做法。

3.3 技能版本号打在哪一层

版本号的载体有好几种选择,简单说:

  • 单个技能独立仓库:直接在仓库上打 tag,比如v1.2.0,简单直接;
  • 多技能共用一个 monorepo:打带路径前缀的 tag,比如skills/form-xml-to-report/1.2.0,这样每个技能可以独立发布;
  • 不想分太细:至少按仓库整体打 tag,记录“这一批技能当前的状态”。

我建议稍有点规模的团队直接用带前缀的 tag。整体 tag 的问题是牵一发动全身:你只改了一个技能,却把整个仓库版本号升级了,下游依赖方无法判断自己需不需要更新。

另外一个值得注意的点是:版本号要写在 SKILL.md 里,同时同步打 tag。我这个版本号,就是当前这个技能的 API 版本,别人引用它时应该依赖这个数字做判断。tag 是 Git 层面的标记,字段是语义层面的声明,两者必须保持一致。我们在 CI 里加了一步校验:如果 SKILL.md 的 version 变了但 tag 没有对应更新,构建会直接失败。

3.4 一次技能回滚的完整操作

版本管理最重要的实战场景就是出问题后的回滚。我复盘一下我们真实做过的操作流程。

假设当前线上跑的是form-xml-to-report/1.2.0,但生产环境 Agent 输出的格式异常。怀疑是 1.3.0 引入的改动,我们需要在几分钟内恢复:

# 先确认当前仓库状态和历史 git log --oneline -- skills/form-xml-to-report/ # 查看某个 commit 改了什么 git show b3a4c5d -- skills/form-xml-to-report/ # 找到 1.2.0 对应位置 git tag | grep form-xml-to-report # skills/form-xml-to-report/1.2.0 # 基于 1.2.0 开一个 hotfix 分支,把当前 main 回滚到该状态 git checkout -b hotfix/form-xml-to-report-1_2_0 git checkout skills/form-xml-to-report/ -- skills/form-xml-to-report/ # 提交并推送,走评审流程 git add skills/form-xml-to-report git commit -m "fix(form-xml-to-report): 回滚至 1.2.0,修复输出格式异常"

这里有个很容易踩的坑:不要直接在 main 上git revert再推,也没必要把整个仓库硬 reset。正确的姿态是只对出问题的技能目录做定点恢复,保留其他技能的当前状态。弄完以后还要把“为什么 1.3.0 会出问题”的根因补进 issue,经验不记录就等于没回滚。

4. 复用不外传:子模块、子树与内部相对路径三种玩法

4.1 先理解“技能安装边界”再谈复用

版本管理建好之后,下一个问题是复用。复用有几种姿势,选择之前必须想清楚“技能怎么被安装到目标环境”。是运行时直接从仓库读取?还是在部署时复制到某个技能目录?还是作为依赖被另一个技能调用?边界不同,方案完全不同。

我们最初犯的错误是:所有技能都放在一个仓库里,然后让上层 Agent 在启动时直接加载这个仓库的全部文件。短期看很省事,长期看 Agent 每次都要面对一份越来越大的技能清单,加载慢且容易产生幻觉式误调用。

4.2 方法一:Git Submodule——精确锁版本,适合跨仓库引用

如果你有多个独立仓库,其中一个仓库想引用技能库里的某个技能,Git Submodule 最合适。它能在父仓库里锁定子仓库的某个提交,保证任何人 checkout 时拿到的都是同一个状态。

优点很明确:依赖关系显式存在,版本精确到 commit。缺点也很明显:更新时机是所有协作方共同决定的事,子模块更新常常被忘记;跨仓库调试时的流程也比较繁琐。

我在团队里只推荐一个场景用 submodule:构建反依赖关系明确的独立技能资产,你每次上线都不想被别人的偶然改动波动,需要稳定引用。

4.3 方法二:Git Subtree——复制代码但保留上游同步能力

Subtree 相当于把某个技能的文件复制进当前仓库,同时保留一条和来源仓库的关联记录。优点是对使用者透明,父仓库里所有文件完整可见,没有额外的 submodule 更新操作。缺点是历史会比较冗余,同步冲突处理费劲。

我观察到的实际使用习惯是:如果技能库本身就是 monorepo,那么团队内部跨项目复用技能,subtree 其实没太大必要。subtree 更适合把一组技能从主技能库提取出来,复制到另一个独立项目里基线。我们的做法是给内部二开的演示项目用 subtree 拉取技能包,保证了它们能离线使用。

4.4 方法三:仓库内部相对路径——小团队最划算

如果团队只有一个技能仓库,上层 Agent 引用的技能全部通过内部相对路径读取,这是最便宜的方案。不引入任何 Git 高级特性,依赖关系就是目录路径。

优点不多说,缺点是路径依赖太脆弱。别人调整目录结构时,所有引用立即坏掉。这个方案只在仓库规模可控、结构稳定时成立,我们一开始用这个方案,后来规模上来了才逐步拆成组件版本。

三种方式优缺点一张表看全:

方案版本锁定上手成本同步灵活性适用场景
Submodule精确到 commit中等低跨仓库依赖,需要强一致
Subtree精确到复制时的版本中等中技能整体复制到其他项目基线
内部相对路径随仓库整体走低高单一 monorepo,团队规模小

4.5 跨技能依赖与版本锁定:防止 A 技能悄悄改坏 B 技能

真正让版本管理变复杂的是技能之间的相互依赖。比如我们有个“清洗销售数据”的技能,另一个“生成销售周报”的技能会调用它。后者用自己的 prompt 把前者的输出“喂”给模型。这时候问题来了:清洗技能的输出格式一改,生成周报的技能就可能跟着坏。

我们做的第一道防线是在 SKILL.md 里显式声明 dependencies:

dependencies: ># .git/hooks/pre-commit #!/bin/sh python scripts/check_skills.py || exit 1 python scripts/check_large_files.py --max-size-mb=50 || exit 1

有些团队会觉得这麻烦,但实际体验下来,这种“提交时多花几秒”的成本,远比后续 review 时被问“为什么目录结构错了”要低。所有检查失败都是立即、明确、可修复的。

5.3 版本号和变更文件的自动校验

第二道闸门放在 CI 里。它检查的核心逻辑是:当前合并请求到底动了哪个技能,版本号有没有相应升级。这是最容易漏掉的一步:很多人改完技能但不记得改版本,结果线上运行环境还是旧版本号,排查问题时被误导。

我们 CI 脚本的思路是:

  1. 用git diff --name-only列出变更文件名;
  2. 根据文件路径识别被改动的技能 id;
  3. 检查该技能 SKILL.md 的 version 字段相比 main 是否有变化;
  4. 有变化且没有对应 tag,构建失败。

这个逻辑不复杂,但能让“版本号必须和改动同步”从口头要求变成硬性约束。

5.4 敏感信息守卫:技能里最容易出现密钥泄露

技能库和代码库一样容易保存机密。很多人为了调试一个外部 API,直接把 token 写在提示词模板里,再一个不留神提交到仓库,之后每一条提交记录里都会有这个密钥的影子。

我们的防线有两层。第一层靠 Git hooks,在 pre-commit 阶段用一段简单的自定义扫描,拦截常见密钥格式,比如sk-开头的字符串或者password =这种赋值模式。第二层靠全量历史扫描,在 CI 里定期扫描所有 commit,防止旧历史里藏着已泄露的密钥。

再说下最容易被忽略的一点:就算你现在把 token 从代码里删掉,旧的 Git 历史里仍然存在它。所以一旦发现密钥进了技能库,正确操作不是删除提交,而是立刻吊销密钥并轮换新密钥。处理完密钥之后,再做历史清理或者直接重建仓库。

6. 跑通这套方案之后的实绩、边界与仍然存在的坑

6.1 团队实际感受到的三个变化

这套以 Git 为底座的管理方案跑了大半年,最明显的三个变化,不是工具层面的,而是团队行为层面的。

第一个变化是改动有据可查。现在任何人问“这个技能为啥变成这样”,我们不再翻聊天记录,而是直接看提交历史,几秒钟定位到改动人和改动理由。这个变化看似简单,但大大降低了协作中的猜测成本。

第二个变化是回归可控。引入“依赖技能自动跑回归”测试后,技能间的隐性问题从原来靠人肉发现,变成“合并不了你别想上线”。有几次明显是改动方自己都没想到会影响的技能,测试直接抓了出来。

第三个变化是新人上手路径变短。以前新人入职要看一堆文档才能搞清楚技能库长什么样,现在仓库结构就是文档,规范就是钩子脚本。新同学提交一次失败,看一下报错信息就能自己修正,不用反复问老同事。

6.2 边界必须说清楚:版本库不等于运行时技能注册中心

Git 只解决了技能库的“来源管理”,但没有解决“运行时发现”和“运行时更新”的问题。这个边界如果不认清楚,很容易产生一种幻觉——只要仓库里加一个技能,Agent 就能立刻用上。

实际上,Agent 运行时通常需要从某个技能注册中心或能力清单里加载技能,而不是直接 clone 你的 Git 仓库。我们从仓库到运行时还有一层发布动作:CI 构建产物生成技能包,推送到内部对象存储,再更新注册表。Git 的唯一事实来源,是给这层发布动作提供稳定、可追溯的输入。

所以我的建议是:把仓库管理做好,但别指望它替代运行时系统。版本化管理是地基,不是整栋楼。

6.3 仍然存在的坑:大文件、递归依赖与提示词的“语义回归”

按这套方案跑到现在,我们还持续在跟几个问题作斗争。

第一个问题是大文件。技能里的模型文件、模板文件、图片素材很容易超过几百兆,直接塞进 Git 会让仓库变臃肿,每次 clone 都痛。解决办法是给仓库启用 Git LFS,或者把静态资源放到独立对象存储,仓库里只放引用信息。前者简单,后者更彻底。

第二个问题是递归依赖。技能 A 依赖 B,B 又依赖 A,这种环在元数据层面可能检测不到,直到构建时才发现。我们后来加了依赖图的检测脚本,循环引用直接报错。这事看起来不起眼,但等到依赖链条变长后再排查,会非常痛苦。

第三个问题最难处理,我叫它提示词的语义回归。代码回归可以靠单测判断“输出对不对”,但提示词改了之后,模型输出往往不是对错问题,而是风格变了、结构变了,很难自动化判断。我们目前的做法是维护一组固定测试用例,要求每个技能至少覆盖三类场景的预期输出样例,改动后人工抽查;也在逐渐试验用另一个模型对输出做自动比对。距离完全自动化还有距离,但至少没有裸奔。

6.4 给想落地的团队一句实在话

如果你现在正打算给团队技能库搭建版本化体系,我最朴实的建议是:不要一开始就设计二十个目录、三十个字段、十种自动化检查。把两三个核心技能的目录结构和 SKILL.md 契约定好,把 pre-commit 的脚本跑起来,把回滚流程自己走一遍。这些做扎实了,再慢慢往里面加复杂度。

版本管理工具从来不是难点,真正难的是让团队把“每次改动都留下可检查的痕迹”变成写作习惯。Git 恰好是那个能把习惯变成机制、把机制变成纪律的底座。技能库规模越大,这个习惯的价值就越明显。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/17 8:29:52

SPSS非参数检验全指南:从原理到论文报告与AMOS衔接

刚接触问卷数据分析那会儿&#xff0c;我犯过一个特别典型的错误&#xff1a;拿到一份满意度量表&#xff0c;想看性别差异&#xff0c;直接“分析→比较均值→独立样本t检验”&#xff0c;结果显著&#xff0c;心里还挺美。直到有一次数据明明偏态得厉害&#xff0c;被一位前辈…

作者头像 李华
网站建设 2026/10/17 8:29:29

金融领域元学习实战:破解小样本学习难题

这两年做金融AI落地&#xff0c;最常被问的一个问题是&#xff1a;“我们不是有上亿条交易数据吗&#xff0c;为什么一个新模型从立项到上线要折腾好几个月&#xff1f;”问题就出在“干净、可标注、事件就绪”的数据上——数据总量看着多&#xff0c;特定场景下的有效样本可能…

作者头像 李华
网站建设 2026/10/17 8:29:26

Unity原生Text文字渐显:用状态机替代协程的完整方案

最近在做一套对话框展示逻辑时&#xff0c;遇到一个很典型的 UI 需求&#xff1a;一行提示文字要在指定时机淡入&#xff0c;淡入完成后停留一段时间&#xff0c;再根据剧情或玩家操作淡出。听起来很简单&#xff0c;第一反应自然是开个协程&#xff0c;从 0 把 alpha 跑到 1。…

作者头像 李华
网站建设 2026/10/17 8:28:46

2024商用AI视频生成选型指南:稳定性、可控性与成本全解析

做商用AI视频生成选型&#xff0c;2024年是个特别拧巴的年份。一方面模型能力肉眼可见地往上蹿&#xff0c;几乎每个月都有“新效果炸裂”的方案放出来&#xff1b;另一方面&#xff0c;真正敢把AI视频接进生产线的团队&#xff0c;反而比去年更谨慎了。我最近大半年一直在做AI…

作者头像 李华
网站建设 2026/10/17 8:27:38

STM32F1平台MPU9250九轴传感器移植:从F4例程到稳定出数

简介&#xff1a;MPU9250从STM32F4移植到F1源码例程&#xff0c;是一份面向嵌入式开发者的完整移植工程&#xff0c;重点解决在资源更有限的STM32F1平台上驱动九轴传感器MPU9250的问题。资料涵盖GPIO映射、中断向量调整、时钟配置、内存优化等关键环节&#xff0c;适合需要将现…

作者头像 李华
网站建设 2026/10/17 8:26:58

OpenClaw 安装排坑,解决网关离线、路径报错各类问题

&#x1f539; 工具简述 OpenClaw 是一款广受开发者与办公人群认可的开源本地智能工具&#xff0c;凭借离线本地运行、可视化图形面板、全流程自主任务处理三大核心特点&#xff0c;积累了众多忠实用户。与普通对话类 AI 产品不同&#xff0c;它能够直接调用电脑软硬件操作权限…

作者头像 李华