teamai-cli:用命令行打造团队协作AI助手,自动化代码评审与周报

teamai-cli:用命令行打造团队协作AI助手,自动化代码评审与周报 先聊聊 teamai-cli 这个项目如果你在一个四五人的小研发团队里待过大概率遇到过这种场景代码评审靠人工一遍遍过pr 描述写得像流水账每周要花一两个小时整理周报团队规范散落在 wiki 里但没人真的执行。我最初折腾 teamai-cli就是因为这些事实在太烦了。它本质上是一个跑在终端里的团队协作 AI 助手通过命令行把代码仓库、git 历史、团队规范和主流大模型接口串起来让原本需要人肉盯的事情自动完成。这套工具适合谁适合研发团队里愿意折腾的 TL、对效率敏感的后端工程师、或者独立开发者想维护多个项目时用。它能解决的核心问题是把团队协作里重复、低效、但又必须做的事用 AI 加脚本的方式半自动化减少人在琐事上的时间消耗而不是搞一个大而全的平台。我不建议一上来就做一个 Web 服务配置贵、运维麻烦命令行工具反而轻量直接能和现有开发流程无缝嵌在一起。下面我从需求设计到实际落地完整拆一遍 teamai-cli 是怎么做出来的以及踩过的那些坑。1. 先想明白 teamai-cli 到底要解决什么问题1.1 团队里那些重复又耗时的“隐形工作”大多数研发团队真正消耗时间的不是写代码而是围绕代码的沟通和整理。比如代码评审光看 diff 就要在几十个文件之间来回跳还得结合上下文判断改了哪里影响哪里比如周报每个人要把一周的 commit 翻出来再组织成领导能看懂的描述再比如团队规范namespace 命名、错误处理方式、commit message 格式新人来了总得反复提醒。这些工作有一个共同点它们都基于历史数据有明确规则又非常耗时。teamai-cli 的起点就是把这类工作识别出来。我统计了一下团队一周的时间分配评审占掉工程师差不多 10%~15% 的精力周报整理平均每人每周要花 40 分钟以上还不算规范检查这种靠人盯着的事。这些其实非常适合丢给模型做“预整理”再由人来确认而不是完全依赖人的注意力。所以 teamai-cli 的第一版定位很朴素一个能读懂仓库和 git 上下文、按本地规则调用大模型生成内容、并输出为可复用文本的命令行工具。这里有个关键取舍不是所有事情都值得加 AI。像实时聊天、会议纪要这类已经有成熟产品没必要重复造轮子。命令行工具聚焦在“输入是数据、输出是文档或建议”的场景反而更好用。我见过不少团队一上来就想做“AI 研发助手”最后做成了笨重的聊天机器人连登录都没人用。明确边界才能把核心场景做到好用。1.2 为什么选命令行而不是 Web 面板设计之初就有人问我做成 Web 服务不是更方便每个人打开浏览器就能用还能有 UI。但实际推演下来Web 方案至少有三个问题第一团队内部要部署服务端涉及鉴权、数据存储、模型 key 的管理不说技术难度光是运维成本对小型团队就是负担第二研发人员日常大部分时间其实在 IDE 和终端里频繁切到浏览器会打断工作流第三命令行天然适合和 git、CI、shell 脚本集成这是 Web 服务很难做到的。命令行工具还有一个隐藏优势可以被脚本化。比如把 teamai-cli 挂到 pre-push 钩子上push 之前自动跑一轮代码评审和规范检查这个能力 Web 服务很难丝滑落地。再比如在 CI 的 pipeline 里加一步用 teamai-cli 生成 pr 描述草稿整个流程不需要任何人工打开浏览器操作。终端工具能和现有工具链嵌在一起这是它最大的价值。另外从工程角度看CLI 的边界非常清晰。输入是参数加 stdin输出是 stdout 和文件接口简单意味着好测好维护。后来我甚至把它做成了团队的“内部瑞士军刀”任何需要调用大模型但不想写代码的人都可以用命令行直接完成不需要学习 API 文档也不需要关心 token 怎么算。2. 核心功能拆解团队 AI 助手到底该做什么2.1 PR/MR 评审最快落地的场景第一个实现的功能是代码评审。具体用法很简单切到分支后执行评审命令工具会自动对比当前分支和主干分支的差异把变更文件、diff 摘要、关键代码片段发送给大模型生成按文件组织的评审意见。这里需要注意一个细节不能把完整 diff 一股脑塞给模型token 消耗太大而且有效信息会被噪声淹没。我采用的做法是分层处理。先由脚本统计变更文件列表、每个文件的增删行数、涉及的关键函数名生成一个“变更概览”然后对每个文件做一次独立的“文件级评审”最后把所有文件级意见汇总让模型生成一份全面的评审总结。这样第一次调用可以控制上下文在合理范围第二次调用又能保证意见有全局视角。实测下来对于常规功能分支一次评审消耗的 token 大概在几千到两万之间成本完全可接受。这里有个实操心得评审 prompt 里一定要嵌入团队自己的规范。比如项目里要求错误信息必须带错误码、所有对外接口都要有注释这些规则写进 prompt 之后模型给出的意见质量会明显提升。否则模型只会基于通用最佳实践给建议很多不符合团队上下文的问题会被漏掉。所以我在设计里留了 rules 文件每个团队可以维护自己的规范集合AI 只是帮你查漏补缺而不是凭自己的通用知识指手划脚。2.2 基于 git 记录的周报与交付汇总第二个很实用的功能是自动周报。原理很简单读取一段时间内的 git 提交记录按作者、日期、模块三个维度做聚合然后交给模型生成结构化周报。这个功能一开始我以为是“过度设计”结果反而成了团队里使用频率最高的能力。每周五下午大家跑一下命令几秒钟就能生成初稿自己改改措辞就能提交比从前翻 commit 记录快太多了。这里有一处容易踩坑git 提交信息往往很简略甚至有些人习惯写“update xxx”“fix bug”模型无从判断改动到底是什么。所以我在生成周报之前先做了一轮“commit 信息增强”。把每个 commit 对应的 diff stat 提取出来结合相关文件的变更内容让模型补全一条描述性的“改动摘要”再基于这些摘要聚合周报。这相当于给模型喂了上下文而不是让它直接猜。此外周报功能还支持自定义维度。比如可以选择只看某个目录下的变更、只看指定作者的提交、或者合并多个仓库的数据。这对于带多个项目的技术负责人特别有用一条命令就能汇总所有项目的交付情况。我后来还加了一个“风险识别”的能力当发现大量删改、深夜提交、或者异常的文件冲突时会在周报里单独提示虽然不一定每次都准但确实能帮管理者发现问题。2.3 团队规范检查与 style guide 的统一第三块能力是规范检查。它和传统的 linter 不同不是靠正则规则去匹配代码而是让模型结合仓库上下文做“语义层面的审查”。比如命名是否清晰、错误处理是否完整、是否有明显安全隐患这些偏主观的问题传统工具很难覆盖但模型能给出比较合理的判断。实际实现中我不会拿模型去替代 ESLint、golangci-lint 这类工具它们做精确检查更快更稳。teamai-cli 的规范检查定位于“代码评审的补充层”专门查那些规则工具查不出来的问题比如“新加的公共函数命名是否和其他模块风格一致”“错误吞掉后有没有日志”“层与层之间是否存在不该有的依赖”。这种方式刚开始用时会有误报模型偶尔会过度解读代码。后来我学乖了把检查结果分为“建议”“需确认”“必须改”三档并且只把后两档输出到阻塞级避免噪音影响开发。规范检查还有一层用法是面向新人培训的。新同学提交第一版代码时评审意见往往集中在目录结构、命名规范这类问题上。与其让导师一遍遍打字说明不如让 teamai-cli 先跑一轮把基础问题全部暴露出来导师只需要关注业务逻辑和设计问题指导效率会高很多。这个功能也是新同学上手项目时的“自检工具”。3. 从零搭建 teamai-cli 的关键设计3.1 项目结构、技术选型与依赖管理技术选型上我选了 Node.js。原因比较现实团队里 JS/TS 技能栈的人多生态里 commander、execa、simple-git 这些包直接能用而且 npm 分发对开发者友好装个全局包就能跑。如果你们团队偏 Python用 typer 搭一套也完全可以cli 工具的技术栈选择主要看团队熟悉度。下面是一个精简版的项目结构teamai-cli/ ├── bin/ │ └── teamai.js # CLI 入口 ├── src/ │ ├── commands/ │ │ ├── review.js # 代码评审 │ │ ├── report.js # 周报生成 │ │ ├── lint-check.js # 规范检查 │ │ └── init.js # 初始化配置 │ ├── core/ │ │ ├── git.js # git 数据读取 │ │ ├── diff.js # diff 解析与裁剪 │ │ ├── llm.js # 模型调用封装 │ │ ├── prompt.js # prompt 模板管理 │ │ └── token.js # token 估算 │ ├── rules/ │ │ ├── default.js # 默认团队规范 │ │ └── custom.js # 自定义规范 │ └── utils/ │ └── output.js # 输出格式化 ├── config/ │ └── config.example.yaml # 配置文件模板 ├── package.json └── README.md核心依赖只有三个commander 负责解析命令行参数simple-git 负责读取仓库信息execa 负责跑子进程。模型调用我直接用的是 fetchNode 18 内置不需要额外装 axios。整个项目依赖非常轻装起来不会有版本冲突的麻烦这一点在团队内部推广时很重要。依赖树越复杂越容易把用户挡在第一步。入口文件做了一层很薄的封装所有逻辑都进 commands 目录。每种命令只做一件事比如 review 命令只负责解析参数、获取 diff、调用 review 流程、输出结果。业务逻辑和 CLI 参数解耦后面想加参数或者改行为只需要动 command 层不用翻核心代码。这个结构也许不算惊艳但胜在简单直观新成员看一遍就能上手改功能。3.2 配置管理与多模型接入设计配置文件我用的是 YAML 格式因为可读性好、支持注释适合放团队共享的配置。默认配置模板长这样provider: openai-compatible model: gpt-4o-mini base_url: https://api.openai.com/v1 api_key_env: TEAMAI_API_KEY temperature: 0.2 max_output_tokens: 2048 repo: main_branch: main review_scope: staged diff_max_lines: 4000 rules: - 代码中所有错误信息必须包含错误码格式如 [ERR-1234] - 对外暴露的函数和接口必须有注释 - 禁止在循环体内发起网络请求 output: format: text create_artifact: true artifact_dir: .teamai这里有三个设计细节值得展开。第一个是api_key_env字段我不会把 key 直接写在配置文件里而是约定从环境变量读取这样配置文件可以放心提交到仓库共享key 只在各个开发者的本地环境变量里存在。第二是temperature设成 0.2因为代码评审和报告生成这类任务更看重确定性温度太高会导致输出千奇百怪。第三是diff_max_lines超过这个规模的 diff 会被截断防止一次请求打爆上下文。多模型接入我是通过 base_url 和 provider 字段支持的。只要你的模型服务兼容 OpenAI 的接口协议就可以配置不同的 base_url 接进来比如本地部署的模型服务、各种国内大模型厂商的 OpenAI 兼容端口。这样团队可以按需切换不锁定在某一家厂商。如果以后要支持非 OpenAI 协议的接口再单独加 provider 适配层也不迟。3.3 prompt 模板管理与 token 估算prompt 模板管理是这套工具里最“花心思”的部分。我把它拆成了三类模板系统提示、任务指令、数据载荷。系统提示固定说明角色和行为边界任务指令定义当前任务的具体要求数据载荷则是动态拼入的 repo 信息、diff 文本、团队规则。三者分开管理好处是调提示词的时候不需要改代码改一个模板文件就行。举一个评审 prompt 的例子你是一名资深代码评审工程师请基于给定的团队规范评审以下代码变更。 任务要求 1. 按文件维度输出评审意见。 2. 每个问题标注严重级别critical / warning / suggestion。 3. 如果变更没有明显问题回复“暂无问题”。 团队规范 {rules} 变更概览 {diff_summary} 变更明细 {diff_content} 请输出评审结果这个模板里没有炫技但每一项都有明确目的。角色设定是为了让模型输出更专业、更聚焦任务要求是为了控制输出格式方便后续程序处理团队规则在前是为了影响模型对变更的判断优先级。你不需要写多复杂的 prompt关键是稳定和可控。token 估算是另一个容易被忽略的点。我一开始直接按字符数截断结果经常把代码从中间切断导致模型看到一堆残缺的语法。后来实现了简单的 token 估算纯英文和代码按 4 字符约等于 1 token中文字符按 1.5 到 2 字符约等于 1 token再根据文件结构对代码块做切片。这个估算不是百分百准确但用来控制输入规模和决定取舍已经够了。实际请求时如果估算超限优先裁剪的是大文件的中间部分而不是直接丢掉文件头尾这样可以最大程度保留变更的核心信息。4. 把 teamai-cli 接入团队日常的实操记录4.1 初始化、配置与第一次跑通全流程拿到工具的第一步是初始化。执行teamai init后会在当前目录写入一份配置文件并且自动检测你用的包管理器、git 仓库的默认分支。然后需要设置环境变量把大模型服务的 API key 填进去。这一步是最容易劝退新人的地方所以我做了比较详细的引导式输出。初始化完成后第一次建议跑的就是 review 命令。步骤如下# 1. 安装全局命令 npm install -g teamai-cli # 2. 在项目根目录初始化配置 teamai init # 3. 设置 API key export TEAMAI_API_KEYyour_api_key_here # 4. 在当前分支执行代码评审 teamai review --base main第一次跑的时候别急着要求输出多完美先把链路打通git 数据读取是否正常、配置文件能不能被正确解析、模型接口是否返回期望的格式。我用了一个“dry-run”参数可以打印即将发送给模型的完整载荷而不实际调用接口方便调试。如果你的模型接口返回异常优先检查 base_url 和 api_key_env 这两项配置。绝大多数连不上模型的问题都是这两项写错了。跑通之后review 结果默认打印到终端同时会生成一份 Markdown 文件存到.teamai目录下方便后续查看和分享。这个文件也可以直接粘到 pr 的评论里当评审草稿。输出的格式我建议在团队内统一比如 critical 级别的问题必须修、warning 级别建议处理、suggestion 级别随缘这样模型输出的结果才能产生实际约束力而不是看完就忘。4.2 对接 git hook 与 CI 的集成方式CLI 工具如果只是手动跑价值会打折扣。真正的日常使用场景是把 teamai-cli 嵌进现有工作流。我在团队里做了两处集成效果都还不错。第一处是 pre-push 钩子。在 push 之前先对 staged 的文件做一次轻量规范检查如果有 critical 级别的问题直接阻断 push并打印具体文件和问题描述。这里只跑规范检查不跑完整代码评审因为完整评审会拉整个 diffpush 时等太久会让人烦躁。钩子脚本实际上就是在.git/hooks/pre-push里调用一行命令#!/bin/sh teamai lint-check --staged --block-level critical第二处是 CI 集成。在 GitHub Actions 或 GitLab CI 里增加一个 job在 mr/push 时运行完整代码评审并把结果以评论形式发布到 MR 页面。这个功能需要 CI 环境能拿到模型 API key注意不要把 key 直接写在仓库的明文变量里使用 CI 平台提供的 secret 能力。CI 集成的好处是评审结果自动沉淀在 MR 里代码提交历史里可以回溯不依赖某个人在本地跑过没有。这里有一个实战心得CI 集成的时间点要选得准。太早在 push 时跑结果出来的时候开发者已经去看别的任务了评审意见容易被忽略太晚在 merge 前跑发现问题回去改又费劲。我建议放到 MR 创建后和每次 update 时跑既不给 push 阶段增加负担又能在讨论期间提供有价值的信息。4.3 权限、key 管理与团队推广的落地姿势key 管理是团队使用这类 AI 工具的敏感话题。直接在每个人本地配置各自的 key管理混乱、成本不透明统一用一个共享 key又有滥用风险。我的建议是小型团队可以先统一用一个 key按环境变量注入后续如果需要精细化控制再做按用户转发。关键点在于key 不能写进任何会提交到远程的配置文件里不能让团队成员随手复制贴到聊天群里。成本控制上可以在配置里设一个硬性上限比如单次评审的最大 token 数超过就不调用模型改走简化流程。还可以给周报这类非关键任务用便宜的小模型代码评审用更强的模型通过配置里的 model 字段区分。这样整体成本能压下来同时保证关键任务的质量。我实测过10 人团队一个月重度使用成本大概在几十元左右完全可控。推广的时候我建议不要一上来推全量功能。先找一两个比较熟的同事只跑 review 命令让他们把体验反馈给你。等功能稳定、团队里有人主动问你“这个怎么装的”之后再写一份简明 README 在团队里扩散。工具的接受度很大程度取决于第一批使用者的体验所以前期的反馈迭代一定要快。5. 运行一段时间后踩过的坑与优化思路5.1 API 限流、超时与并发控制团队用起来之后第一个遇到的问题就是限流。大家集中在周五下午跑周报结果请求被限流报 429 错误。后来我在 sdk 调用层加了两套机制。第一是重试策略遇到限流时先等待一段时间再重试按指数退避方式递增等待时间直到最大重试次数。第二是并发限制同一时刻只允许固定数量的模型请求同时发出去其他请求排队等待。这个并发数我一开始设为 3实测在小团队场景足够了。实现上是用一个简单的 promise 队列信号量控制并发。核心代码大概这样class TaskQueue { constructor(concurrency 3) { this.concurrency concurrency; this.running 0; this.queue []; } add(task) { return new Promise((resolve, reject) { this.queue.push({ task, resolve, reject }); this._next(); }); } _next() { if (this.running this.concurrency || this.queue.length 0) return; const { task, resolve, reject } this.queue.shift(); this.running; task() .then(resolve, reject) .finally(() { this.running--; this._next(); }); } }另一个坑是超时。大模型接口的响应时间不稳定有时候一个请求要几十秒如果客户端没有设超时很容易出现请求挂死。我把超时时间设成了 60 秒超时后直接中断请求让用户手动选择重跑还是跳过。不要设成无限等待否则真出问题的时候你连日志都看不到。5.2 token 成本控制与上下文裁剪策略token 成本是最容易被低估的部分。一开始我做代码评审时把整个分支的完整 diff 都塞进去一个大型功能分支跑一次要烧掉几万 token费用高不说响应也慢。后来我调整了上下文裁剪策略整体成本降了一半以上质量几乎没有损失。具体的裁剪策略是分层的。第一层按文件过滤只保留源码文件去掉 lockfile、生成文件的 diff。第二层按变更内容裁剪如果某个文件只是重命名、格式化或者只改了几个字符就不需要发送完整文件只发变更摘要。第三层对超大文件分段处理按函数或方法块拆分分批发送给模型再把结果合成一份完整评审。这三层组合下来常规分支的一次评审可以控制在 1 万 token 左右。周报功能我用了不同的策略把 commit 的 diff stat 信息提取出来发送给模型而不是发送提交的完整 diff。因为周报不需要知道具体代码只需要理解这次改动做了什么diff stat 加文件路径信息已经足够了。同样的数据量成本可以降到原来的十分之一。这说明不是所有功能都需要完整上下文按需裁剪是降本的核心思路。5.3 输出稳定性、格式解析与误报问题模型输出的稳定性是这类工具能否真正落地的关键。同一个 diff每次跑出来的评审意见可能风格完全不同有时候格式还会乱掉。我在 prompt 里规定输出必须是严格的 Markdown 结构但模型仍然偶尔会加一些多余的话。后来加了一步“后处理校验”用一个小脚本检查输出是否符合预期的标题结构不符合就自动重试一次仍然不行就用一个简化模板包装。误报问题也很头疼。模型对代码的理解是概率性的有时候会把完全正常的代码当成问题提出来。这里我的做法是用“严重级别”来区分问题的确定性。critical 级别的问题必须是非常明确的逻辑缺陷、安全问题、错误处理缺失这些模型判断准确率较高。warning 级别对应可能是问题的内容需要人工二次确认。suggestion 级别则是风格改进建议。同时模型产出的意见里如果是对代码事实的错误描述我会在输出里直接用风险提示标注出来提醒用户这条意见的信息准确度存疑。还遇到过一个有意思的问题模型会“察言观色”。当你给的 prompt 里说“这份代码写得不好”模型就更倾向于挑刺如果说“请复核代码质量”输出会更平衡。所以我在系统提示里尽量用中性表述不加倾向性词汇避免模型为了迎合指令而过度批评或过度夸奖。这个细节对输出质量的影响比很多人想象的更大。5.4 常见问题速查表我把部署和使用过程中最常遇到的问题整理成一个速查表方便排查。问题现象可能原因解决方法命令找不到 teamai全局 bin 路径未加入 PATH执行npm ls -g teamai-cli确认安装再检查全局 bin 目录是否在 PATH 中读取不到 git 仓库当前目录不是 git 仓库确认目录下有.git目录或者根目录配置指向了错误路径模型接口一直报错base_url 或 api_key_env 配置错误用 dry-run 模式打印请求详情核对 base_url 和 key 是否有效提示上下文过长变更 diff 超过阈值调整diff_max_lines或默认启用裁剪策略评审意见太泛泛prompt 里缺少团队规范在 rules 中补充具体、可检查的规范条目返回格式不符合预期模型输出被截断调大max_output_tokens同时对长输出做截断保护周报生成偏离事实commit 信息太简略先做 commit 信息增强再聚合生成周报请求经常超时或限流并发过高或触发了速率限制降低并发数开启指数退避重试这些坑大部分都是工具接入期的阵痛跑一个月之后基本就稳定了。之后更多的工作是调 prompt、加新规则、优化输出质量属于持续打磨的过程。做这类工具最有意思的地方就是它没有一个“完工”的状态会随着团队需求不断演化。比如我们后来加了 Slack 通知、周报邮件推送都是从一个小命令开始长出来的。我个人用下来的体会是teamai-cli 这类工具的真正价值不在于“AI 写得比我好”而在于它把大量低认知密度的重复劳动从人身上卸掉了。代码评审、周报整理、规范检查这些事不是做不了是不需要花那么多时间做。省下来的时间拿来做设计、写复杂逻辑、陪同事过方案这些都是机器替代不了的。命令行只是承载这个理念的最轻便的形态核心还是想清楚哪些工作该交给模型哪些必须由人来判断。