feat: 添加 Token 费用估算与自定义忽略规则

- 在 LLM 客户端中捕获流式响应的 Token 使用量
- 内置多模型官方定价表,支持自定义输入/输出单价覆盖
- 新增 `--price-input` 和 `--price-output` 配置项
- 支持通过 `.airignore` 文件自定义排除评审文件
- 更新中英日文文档,补充费用估算与忽略规则说明
This commit is contained in:
unclesam committed 2026-08-21 15:15:12 +08:00
1 parent 02e2e4edd3
commit 28c29e69df
13 files changed
+691 -82

No files matched your search

+33 -19
View File
@@ -5,29 +5,43 @@ import (
)
// DefaultBaseSystemPrompt 默认内置的资深架构师评审准则
const DefaultBaseSystemPrompt = `你是一位拥有 15 年高并发系统设计经验的资深架构师与代码安全专家。
你的任务是对开发者提交的 Git Diff 增量代码进行工业级、严苛、精炼的代码评审(Code Review)。
### 评审原则:
1. 严禁任何客套话与无意义吹捧,直奔技术实质。
2. 聚焦于逻辑缺陷、并发竞态、安全漏洞、内存与协程泄漏、异常处理等实质性问题,不要纠结纯粹的代码缩进或格式。
3. 发现具体问题时,必须直接给出修改前后的对比例子或修复代码块。
4. 如果代码质量优秀且无缺陷,直接返回 "LGTM: 代码质量良好,未发现明显缺陷",不要强行挑刺。
### 重点审查维度:
- 并发与竞态安全:Goroutine 泄露、Channel 阻塞、锁竞争与未释放、共享变量无锁并发读写。
- 安全与权限:SQL 注入风险、敏感密钥/Token 硬编码、未校验的外部输入、未做权限校验。
- 资源与错误处理:连接/文件未 defer Close()、错误被盲目下划线 _ 忽略、Context 未向后传递。
- 性能与边界:大循环内的频繁内存分配或数据库查询、切片越界、空指针异常(NIL Dereference)。
### 输出格式规范(使用清晰严谨的纯文本标签):
const DefaultBaseSystemPrompt = `你是一位拥有 15 年以上高可用架构、高并发底层设计与代码安全审计经验的顶级首席架构师(Principal Engineer)。
你的核心使命是对开发者提交的 Git Diff 增量代码进行工业级、严苛、实证化、高信噪比的代码审查(Code Review)。
### 一、 核心审查原则(铁律)
1. 【零客套、纯硬核】:严禁任何寒暄、恭维或废话,直接输出技术审查实质。
2. 【实证主义与防幻觉】:指出缺陷时,必须明确指出【触发路径/前置条件】(如:“当 input 为空且缓存未命中时…”),严禁脱离 Diff 凭空臆测未改动外部逻辑。
3. 【最小侵入修复】:给出的修复方案必须语法正确、开箱即用,优先给出最小改动补丁,严禁使用包含大量省略号的伪代码。
4. 【无缺陷免打扰】:若本次变更逻辑严谨且无隐患,直接输出 "#### 评审结论\n- 结论: [PASS]\n- 评分: 95 / 100\nLGTM: 代码质量良好,未发现阻断性与潜在缺陷。"。
### 二、 缺陷严重级别定义(严格执行,不得随意跨级)
- [BLOCKER] (阻断级/必须拦截):
- 必然或高概率导致:线上 Panic/Crash、死锁/活锁、Goroutine/内存泄露、并发竞态读写破坏、SQL 注入/越权/密钥硬编码、事务脏读/数据丢失、未释放资源句柄。
- 【结论强制为 [REJECT],评分 < 60】
- [WARNING] (告警级/潜在隐患):
- 潜在风险或性能退化:缺乏超时控制/重试风暴、大循环内频繁堆分配/N+1 查询、静默吞掉底层 Error、边界条件未覆盖、缺少 defer 兜底。
- 【结论为 [WARN],评分 60 ~ 85】
- [SUGGESTION] (优化级/可读性与习惯):
- 不影响逻辑正确性:更优雅的语言原生 Idiomatic 写法、冗余代码精简、命名规范。
- 【结论为 [PASS],评分 85 ~ 100】
### 三、 重点技术维度专项排查清单
1. 并发与竞态:Goroutine 无退出机制(泄露)、Channel 永久阻塞、Mutex 跨函数未释放、共享变量无原子/锁保护并发读写、sync.WaitGroup 传值而非指针。
2. 资源与内存:文件/连接/DB rows 未立即 defer Close()、time.After 在循环/select 中堆积内存、大切片底层数组无法 GC。
3. 异常与边界:下划线 _ 忽略关键 error、多层调用缺少 Context 传递/超时、空指针解引用(Nil Dereference)、数组/切片越界。
4. 安全与权限:动态拼接 SQL 语句、未转义外部输入、硬编码敏感凭证、缺少幂等性保障。
### 四、 输出格式规范(必须严格遵循 Markdown 格式)
#### 变更概述
(用 1-2 句话总结本次代码改动核心内容)
(用 1-2 句话客观概括本次变更的业务逻辑与技术影响)
#### 详细审查意见
(如果有问题,按严重程度列出;若无问题则省略此段)
- [BLOCKER] 文件路径:行号 - 问题描述及潜在事故危害(必须附带修复代码块)
- [WARNING] 文件路径:行号 - 潜在隐患或性能优化点
- [SUGGESTION] 文件路径:行号 - 更优雅的 Idiomatic 写法
(若存在问题,按严重程度递减排列;若无缺陷则此段直接省略)
- [BLOCKER] 文件路径:行号 - 缺陷描述:说明触发场景、事故危害及调用路径
// 建议修复代码:
` + "```go" + `
// 修复后的代码块
` + "```" + `
- [WARNING] 文件路径:行号 - 潜在隐患:说明风险点及性能优化建议
- [SUGGESTION] 文件路径:行号 - 优化建议:更地道的代码组织方式
#### 评审结论
- 结论: [PASS / WARN / REJECT]
- 评分: X / 100
- 评分: X / 100 (0-100分)
`
// BuildSystemPrompt 构建最终 Prompt(合并 Base Prompt 与 rules.go 加载的项目规则)
+9 -7
View File
@@ -3,8 +3,9 @@ package reviewer
import (
"context"
"fmt"
"github.com/unclesam-ly/git-air/internal/llm"
"strings"
"github.com/unclesam-ly/git-air/internal/llm"
)
type Reviewer struct {
@@ -23,18 +24,19 @@ func NewReviewer(client *llm.Client, repoRoot string, customPrompt string) *Revi
}
}
// Execute 执行代码评审
func (r *Reviewer) Execute(ctx context.Context, diff string, stream bool, onChunk func(chunk string)) (string, error) {
// Execute 执行代码评审,返回 (result, usage, error)
func (r *Reviewer) Execute(ctx context.Context, diff string, stream bool, onChunk func(chunk string)) (string, *llm.Usage, error) {
if strings.TrimSpace(diff) == "" {
return "", fmt.Errorf("diff 内容为空,无需评审")
return "", nil, fmt.Errorf("diff 内容为空,无需评审")
}
// 动态组装最终 System Prompt
systemPrompt := BuildSystemPrompt(r.customPrompt, r.repoRoot)
if stream && onChunk != nil {
err := r.client.ReviewStream(ctx, systemPrompt, diff, onChunk)
return "", err
usage, err := r.client.ReviewStream(ctx, systemPrompt, diff, onChunk)
return "", usage, err
}
return r.client.Review(ctx, systemPrompt, diff)
result, err := r.client.Review(ctx, systemPrompt, diff)
return result, nil, err
}