代码规范感知

wescode 中的 Convention(项目约定)与 Correction(用户纠正)——自动检测 vs 显式反馈。


Convention 概念

Convention 是自动检测的项目事实——代码库中已经存在但没有写成文档的编码规范:

项目约定示例:
  - 缩进使用 tab(不是 space)
  - import 按 stdlib → 第三方 → 本地排序
  - 错误处理使用 errors.Wrap 而非 fmt.Errorf
  - 测试文件命名 *_test.go
  - 每个 handler 开头校验 Authorization header

关键特性

特性说明
来源自动从代码检测
持久化❌ 不入 memory store(INV-MEM-12)
存储runtime probe-cache(per-Cell LRU)
生命周期随进程(重启后重新检测)
隔离per-workspace(per-Cell)

Correction 概念

Correction 是用户显式教给 Agent 的偏好——通过拒绝或修改 AI 的编辑来学习:

纠正示例:
  - "不要用 any 类型,用具体类型"
  - "错误信息用中文"
  - "函数命名用驼峰不用下划线"

关键特性

特性说明
来源用户反馈(拒绝/修改编辑)
持久化✅ 入 memory store(L4 Agent Memory)
存储wesgine 记忆系统
生命周期持久化(跨会话/跨重启)
隔离per-Actor(默认跨项目)

Convention vs Correction 对比

维度Convention(约定)Correction(纠正)
本质项目事实用户偏好
来源自动检测用户反馈
持久化❌ runtime probe-cache✅ memory store
存储介质per-Cell LRU cachewesgine sessions.db
生命周期进程级(重启重检测)持久(直到删除)
隔离范围per-workspaceper-Actor(跨 workspace)
注入方式系统提示词快照L4 Agent Memory
修改方式不可手动修改记忆中心管理
跨项目❌✅ 默认跨项目

ScanConventions

检测流程

ScanConventions
  → 分析当前 workspace 代码
  → 检测缩进风格、命名规范、导入顺序等
  → 结果写入 per-Cell LRU ProbeCache
  → 注入系统提示词(作为快照)

ProbeCache 机制

// Convention 结果存储在 per-Cell 的 LRU 缓存中
// 不写入 memory store(INV-MEM-12)
type ProbeCache struct {
    cache   *lru.Cache  // key = 工作目录
    cellID  string
}

为什么不存入记忆

Convention 是项目事实,不是认知记忆:
  - 项目可能随时改变编码风格
  - 不同分支可能有不同的约定
  - 重检测的成本很低
  - 存入记忆会污染认知空间

Learn 系统

Learn 系统处理用户反馈,生成 Correction 和 Convention:

API 端点

方法路径说明
POST/cells/{id}/learn/scan-conventions扫描项目约定
POST/cells/{id}/learn/edit-rejected报告被拒绝的编辑
POST/cells/{id}/learn/edit-modified报告被修改的编辑
GET/cells/{id}/learn/corrections获取纠正列表
GET/cells/{id}/learn/conventions获取约定列表

edit-rejected

当用户拒绝 AI 的编辑时:

// POST /cells/{id}/learn/edit-rejected
{
  "file": "internal/service/user.go",
  "original": "func GetUser(id string) (*User, error) {",
  "proposed": "func getUser(id string) (*User, error) {",
  "agent_id": "default-coder"
}

AI 学到:「用户不想让公开函数变成私有」→ 生成 Correction。

edit-modified

当用户修改 AI 的编辑时:

// POST /cells/{id}/learn/edit-modified
{
  "file": "internal/service/user.go",
  "original": "return fmt.Errorf(\"user not found: %s\", id)",
  "ai_edit": "return errors.New(\"user not found\")",
  "user_edit": "return errors.Wrapf(err, \"user not found: %s\", id)",
  "agent_id": "default-coder"
}

AI 学到:「用户偏好 errors.Wrapf 并保留上下文」→ 生成 Correction。


Correction 的跨项目行为

在 wescode 中,1 workspace = 1 Cell,但 Correction 属于 L4 记忆(per-Actor):

workspace A (Cell ws-a1b2):
  → 用户拒绝了某个编辑
  → Correction 写入 Cell ws-a1b2 的记忆

workspace B (Cell ws-c3d4):
  → 这条 Correction 不在 Cell ws-c3d4 中
  → 不会跨 workspace 生效

为什么"默认跨项目"在 wescode 不完全成立

由于 1 workspace = 1 Cell 的隔离模型,Correction 实际上不跨 workspace——虽然 Correction 属于 L4 per-Actor 记忆,但 actor 绑定在 Cell 中:

wescode 的隔离:
  Correction 生命周期 = Cell 生命周期 = workspace 生命周期

接入 SSO 后(多 workspace 共享 actor),Correction 才会真正跨项目生效。


Convention 注入时机

Convention 以快照形式注入系统提示词:

新对话开始
  → 读取 ProbeCache 中的 Convention
  → 作为快照注入系统提示词
  → 对话期间不变(byte-stable,保护 prompt 缓存)

Convention 变化
  → 下次 ScanConventions 时更新 ProbeCache
  → 下一个新对话生效

最佳实践

  1. 通过拒绝/修改教 AI:这是最自然的反馈方式
  2. 理解隔离:Convention 和 Correction 都随 workspace 切换
  3. 不需要手动配置 Convention:自动检测
  4. 在记忆中心管理 Correction:查看和删除不正确的纠正