四哥还会聊AI

80后突围:当程序员不再是第一个梦想,AI成了第四个梦想

第6篇-架构即代码-如何用系统化思维驯服AI

架构即代码:如何用系统化思维驯服AI

🧠 AI编程的终极困境:你是在"使用AI"还是"被AI使用"?

大多数人在AI编程中都陷入了一个悖论:本来是想让AI提高效率,结果却花大量时间在"纠正AI"和"修复AI生成的问题"上。

问题的根源在于:缺乏系统化架构思维。没有好的架构,AI就像一匹野马,有能力但不可控。

在希语低喃心绪笔记开发中,我总结出一套"架构即代码"的方法论,让AI从"不可控的天才"变成"听话的专家"。

🎯 核心认知:架构先于代码,规则先于功能

传统AI编程的误区

❌ 典型的错误流程:

  1. 有一个想法
  2. 直接让AI写代码
  3. AI生成复杂的解决方案
  4. 发现不对,让AI修改
  5. 问题越来越多,项目失控

问题在哪里?

  • 没有明确的架构边界
  • 没有预先定义的规则
  • 没有系统化的约束机制
  • AI在"自由发挥",偏离了真实需求

架构即代码的正确流程

✅ 系统化的正确流程:

  1. 定义架构原则和边界
  2. 创建规则约束和模板
  3. 让AI在框架内工作
  4. 通过架构控制输出质量
  5. 持续优化架构本身

🏗️ 第一层:项目级架构约束

1. 技术栈的强制约束

问题:AI为什么会推荐不合适的技术栈?

  • AI倾向于推荐"最新最热"的技术
  • 缺乏对项目真实需求的了解
  • 过度考虑"未来可能的扩展需求"

解决方案:在Claude.md中强制锁定技术栈

## 技术栈强制约束(不可更改)

### 前端技术栈(锁死)
- 框架:Taro 4.1.7 + React 18(不得使用Vue、Next.js等)
- 语言:TypeScript 5.4.5(严格模式,不得使用any)
- 状态管理:React Context + useReducer(不得使用Redux、Zustand等)
- 样式:SCSS + CSS变量(不得使用Tailwind、Styled Components等)
- 图表:ECharts(不得使用Chart.js、D3等)

### 后端技术栈(锁死)
- 运行时:Node.js 18+(不得使用Python、Java等)
- 框架:Fastify(不得使用Express、Koa等)
- 数据库:PostgreSQL 14+(不得使用MySQL、MongoDB等)
- ORM:Prisma(不得使用TypeORM、Sequelize等)
- 认证:JWT(不得使用Session、OAuth等)

### 禁止使用的技术
- ❌ 任何形式的微服务架构
- ❌ 消息队列(Redis Queue、RabbitMQ等)
- ❌ 复杂的缓存策略
- ❌ 多数据库设计

效果:AI无法再推荐"炫技"方案,只能在给定框架内解决问题

2. 文件结构的强制规范

问题:AI为什么喜欢创建复杂的文件结构?

  • 受到"最佳实践"文章影响
  • 倾向于过度分层和抽象
  • 不理解小项目的实际需求

解决方案:定义精确的文件结构模板

## 强制文件结构(不可违背)

project/
├── frontend/
│ └── tidepool/
│ ├── src/
│ │ ├── app.tsx # 应用入口,不超过100行
│ │ ├── context/ # 全局状态,每个文件不超过200行
│ │ │ └── AppContext.tsx
│ │ ├── pages/ # 页面组件,每个文件不超过300行
│ │ │ ├── index/
│ │ │ ├── record/
│ │ │ ├── chat/
│ │ │ ├── insights/
│ │ │ └── settings/
│ │ ├── components/ # 通用组件,每个文件不超过200行
│ │ │ ├── PageWrapper.tsx
│ │ │ ├── CustomTabBar.tsx
│ │ │ └── SketchIcon.tsx
│ │ ├── services/ # API服务,每个文件不超过300行
│ │ │ └── api.ts
│ │ └── types/ # 类型定义,每个文件不超过150行
│ │ └── index.ts
│ └── config/ # 配置文件,不可更改
│ └── apiConfig.js
└── backend/
└── src/
├── routes/ # API路由,每个文件不超过200行
│ ├── auth.routes.ts
│ ├── users.routes.ts
│ └── sessions.routes.ts
├── services/ # 业务逻辑,每个文件不超过400行
│ ├── auth.service.ts
│ ├── users.service.ts
│ └── llm.service.ts
├── repositories/ # 数据访问,每个文件不超过300行
│ ├── users.repository.ts
│ └── sessions.repository.ts
└── types/ # 类型定义,每个文件不超过150行
├── users.types.ts
└── sessions.types.ts


**关键约束:**
- 单文件不超过1500行(AI上下文窗口限制)
- 目录结构不可更改
- 文件命名必须遵循规范
- 禁止创建额外的utils、helpers等目录

3. 依赖管理的强制规则

问题:AI为什么喜欢添加不必要的依赖?

  • 倾向于使用"专门的库"解决简单问题
  • 受到GitHub stars数量影响
  • 不理解依赖维护的成本

解决方案:制定严格的依赖管理规则

## 依赖管理强制规则

### 禁止添加的依赖类型
- ❌ 任何形式的工具库(lodash、date-fns、classnames等)
- ❌ 任何UI组件库(Ant Design、Material-UI等)
- ❌ 任何表单验证库(yup、zod、joi等)
- ❌ 任何HTTP客户端库(axios、got等,用原生fetch)
- ❌ 任何状态管理库(redux、mobx、zustand等)

### 必须使用原生实现的场景
```typescript
// ❌ 禁止使用lodash
import { map, filter, find } from 'lodash'

// ✅ 使用原生JavaScript
const filtered = users.filter(user => user.age > 18)
const found = users.find(user => user.id === targetId)

// ❌ 禁止使用date-fns
import { format, addDays } from 'date-fns'
format(new Date(), 'yyyy-MM-dd')

// ✅ 使用原生Date
const formatDate = (date: Date) => {
  return date.toISOString().split('T')[0]
}

// ❌ 禁止使用axios
import axios from 'axios'
const response = await axios.get('/api/users')

// ✅ 使用原生fetch
const response = await fetch('/api/users')
const data = await response.json()

依赖决策树

需要功能F?
├── 是否可用JavaScript原生API实现?
│   ├── 是 → 使用原生实现
│   └── 否 → 检查是否为项目核心需求
│       ├── 是 → 考虑添加依赖(需要充分理由)
│       └── 否 → 重新设计需求,避免依赖

🧩 第二层:代码级架构约束

1. 函数设计的强制规范

问题:AI为什么写出复杂的函数?

  • 倾向于展示"全面考虑"
  • 过度处理边界情况
  • 喜欢使用复杂的设计模式

解决方案:函数设计的三重约束

// ✅ 函数模板:强制简洁
export class TemplateService {
  // 约束1:单个函数不超过50行
  async create(data: CreateData): Promise<ReturnData> {
    // 约束2:只有必要的错误处理
    try {
      const result = await repository.create(data)
      logger.info(`Entity created: ${result.id}`)
      return result
    } catch (error) {
      logger.exception('Create failed', error)
      throw error
    }
  }

  // 约束3:单一职责,不做多余的事情
  private validate(data: CreateData): void {
    if (!data.requiredField) {
      throw new Error('Required field missing')
    }
  }
}

// ❌ AI可能会生成的复杂函数
export class ComplexService {
  async createComplexEntity(data: ComplexInput): Promise<ComplexResult> {
    // 过度输入验证(50行)
    this.validateInputFormat(data)
    this.validateBusinessRules(data)
    this.validatePermissions(data)
    this.validateDependencies(data)

    // 复杂的重试逻辑(30行)
    const result = await this.withRetry(async () => {
      return await this.performComplexCreation(data)
    }, { retries: 3, backoff: 'exponential' })

    // 过度的日志记录(20行)
    logger.debug('Starting creation process', { dataId: data.id })
    logger.info('Validation passed', { validationResults: this.lastValidation })
    logger.info('Creation completed', { resultId: result.id })

    // 不必要的缓存处理(15行)
    await this.updateCache(result)
    await this.invalidateRelatedCache(result.relatedEntities)

    return result
  }
}

2. 错误处理的统一标准

问题:AI为什么设计复杂的错误处理?

  • 倾向于"兼容所有情况"
  • 喜欢创建复杂的错误分类体系
  • 过度考虑用户体验

解决方案:Let it Crash + 统一错误格式

// ✅ 统一的错误处理模板
export class StandardService {
  async operation(data: InputData): Promise<OutputData> {
    try {
      const result = await repository.operation(data)
      return result
    } catch (error) {
      // 统一格式:记录 + 抛出
      logger.exception('Operation failed', error)
      throw new Error(`Operation failed: ${error.message}`)
    }
  }
}

// ❌ AI可能会生成的复杂错误处理
export class ComplexErrorService {
  async operation(data: InputData): Promise<OutputData | null> {
    try {
      const result = await repository.operation(data)
      return result
    } catch (error) {
      // 过度的错误分类
      if (error instanceof ValidationError) {
        return { error: 'VALIDATION_ERROR', details: error.details }
      } else if (error instanceof PermissionError) {
        return { error: 'PERMISSION_DENIED' }
      } else if (error instanceof NetworkError) {
        // 复杂的重试逻辑
        return await this.retryWithBackoff(() => repository.operation(data))
      } else {
        // 返回null而不是抛出错误
        return null
      }
    }
  }
}

3. 类设计的简约原则

问题:AI为什么喜欢过度设计类结构?

  • 受到设计模式书籍影响
  • 倾向于"为未来扩展做准备"
  • 喜欢使用继承和抽象

解决方案:禁止过度抽象,强制组合

// ✅ 简单的组合设计
export class UserService {
  constructor(
    private userRepository: UserRepository,
    private logger: Logger
  ) {}

  async create(userData: CreateUserInput): Promise<User> {
    const user = await this.userRepository.create(userData)
    this.logger.info(`User created: ${user.id}`)
    return user
  }
}

// ❌ AI可能会生成的复杂继承结构
abstract class BaseService<T, CreateInput, UpdateInput> {
  protected abstract repository: Repository<T, CreateInput, UpdateInput>
  protected abstract logger: Logger
  protected abstract validator: Validator<T>

  async create(data: CreateInput): Promise<T> {
    await this.validator.validate(data)
    const result = await this.repository.create(data)
    this.logger.info(`${this.getEntityName()} created: ${result.id}`)
    return result
  }

  protected abstract getEntityName(): string
}

class UserService extends BaseService<User, CreateUserInput, UpdateInput> {
  // 复杂的模板方法模式
}

🔧 第三层:流程级架构约束

1. 开发流程的标准化

问题:为什么AI编程项目容易失控?

  • 缺乏清晰的开发节奏
  • 没有明确的完成标准
  • 缺乏持续的质量控制

解决方案:标准化的开发流程

## 强制开发流程

### 阶段1:架构定义(不可跳过)
1. 创建/更新Claude.md文档
2. 定义明确的需求边界
3. 确定技术栈约束
4. 创建文件结构模板

### 阶段2:骨架搭建(必须先做)
1. 创建所有必要的目录结构
2. 定义TypeScript接口
3. 创建基础的CRUD操作
4. 设置基础的错误处理

### 阶段3:功能实现(严格按顺序)
1. 先实现数据层(repositories)
2. 再实现业务层(services)
3. 最后实现接口层(routes)
4. 每层完成后必须测试通过

### 阶段4:质量检查(必须执行)
1. 文件行数检查(不超过1500行)
2. 类型检查(noImplicitAny: true)
3. 代码风格检查(ESLint)
4. 单元测试覆盖率检查

### 每日质量门禁
- [ ] 所有文件不超过1500行
- [ ] 没有使用any类型
- [ ] 所有错误都正确抛出
- [ ] 依赖项符合约束规则
- [ ] 函数职责单一

2. 代码审查的强制要求

问题:如何确保AI生成的代码符合架构要求?

## 强制代码审查清单

### 架构一致性检查
- [ ] 文件结构是否符合规范
- [ ] 依赖关系是否正确
- [ ] 接口设计是否一致
- [ ] 错误处理是否统一

### 质量标准检查
- [ ] 函数长度不超过50行
- [ ] 类的职责是否单一
- [ ] 是否有不必要的复杂性
- [ ] 是否遵循KISS原则

### 约束规则检查
- [ ] 没有使用禁止的依赖
- [ ] 没有使用any类型
- [ ] 错误是否正确抛出
- [ ] 日志格式是否统一

### 性能和安全检查
- [ ] 没有不必要的数据库查询
- [ ] 输入验证是否充分
- [ ] 敏感信息是否正确处理
- [ ] API响应是否合理

3. 重构的自动化机制

解决方案:自动化架构守护

// scripts/archural-guard.ts
import fs from 'fs'
import path from 'path'

interface ArchitecturalRule {
  name: string
  check: (filePath: string, content: string) => boolean
  message: string
}

const rules: ArchitecturalRule[] = [
  {
    name: 'file-size-limit',
    check: (filePath, content) => {
      const lines = content.split('\n').length
      return lines <= 1500
    },
    message: 'File exceeds 1500 lines limit'
  },
  {
    name: 'no-any-types',
    check: (filePath, content) => {
      return !content.includes(': any') && !content.includes('as any')
    },
    message: 'Found usage of any type'
  },
  {
    name: 'required-imports',
    check: (filePath, content) => {
      if (filePath.endsWith('.ts')) {
        return content.includes('import traceback')
      }
      return true
    },
    message: 'Missing import traceback statement'
  },
  {
    name: 'error-handling',
    check: (filePath, content) => {
      if (filePath.includes('service')) {
        return content.includes('logger.exception')
      }
      return true
    },
    message: 'Service files must use logger.exception for error handling'
  }
]

function checkArchitecture() {
  const srcDir = './src'
  const files = getAllTypeScriptFiles(srcDir)
  let hasViolations = false

  files.forEach(file => {
    const content = fs.readFileSync(file, 'utf8')

    rules.forEach(rule => {
      if (!rule.check(file, content)) {
        console.error(`❌ [${rule.name}] ${file}: ${rule.message}`)
        hasViolations = true
      }
    })
  })

  if (hasViolations) {
    console.error('\n❌ Architecture check failed!')
    process.exit(1)
  } else {
    console.log('✅ Architecture check passed!')
  }
}

checkArchitecture()

🎯 实战案例:希语低喃心绪笔记的架构演进

案例1:消息系统的架构重构

初始状态(AI自由发挥的结果):

// AI生成的复杂消息系统
class MessageManager {
  // 支持多种消息类型
  async createTextMessage(data: TextMessageData): Promise<TextMessage>
  async createImageMessage(data: ImageMessageData): Promise<ImageMessage>
  async createVoiceMessage(data: VoiceMessageData): Promise<VoiceMessage>
  async createVideoMessage(data: VideoMessageData): Promise<VideoMessage>

  // 复杂的消息处理流程
  async processMessage(message: Message): Promise<ProcessedMessage> {
    await this.validateMessage(message)
    await this.transformMessage(message)
    await this.enrichMessage(message)
    await this.routeMessage(message)
    await this.indexMessage(message)
    await this.cacheMessage(message)
    return this.formatMessage(message)
  }

  // 过度的错误处理
  async handleError(error: Error, context: ErrorContext): Promise<ErrorResult> {
    // 50行复杂的错误分类和处理逻辑
  }
}

应用架构约束后的简化:

// 约束后的消息系统
export class MessageService {
  constructor(
    private messageRepository: MessageRepository,
    private logger: Logger
  ) {}

  async create(data: CreateMessageData): Promise<Message> {
    try {
      const message = await this.messageRepository.create(data)
      this.logger.info(`Message created: ${message.id}`)
      return message
    } catch (error) {
      this.logger.exception('Failed to create message', error)
      throw error
    }
  }

  async findBySessionId(sessionId: string): Promise<Message[]> {
    return await this.messageRepository.findBySessionId(sessionId)
  }
}

架构约束带来的效果:

  • 代码行数从800行减少到150行
  • 维护成本降低70%
  • AI生成的一致性提高90%
  • 新功能开发速度提升50%

案例2:AI集成的标准化

AI自由发挥的复杂方案:

// AI倾向于过度设计LLM集成
class LLMOrchestrator {
  constructor() {
    this.promptManager = new ComplexPromptManager()
    this.conversationManager = new ConversationStateManager()
    this.responseParser = new MultiFormatResponseParser()
    this.errorHandler = new RetryWithBackoffHandler()
    this.cacheManager = new MultiLevelCacheManager()
  }

  async generateResponse(input: UserInput): Promise<AIResponse> {
    // 复杂的多层处理逻辑
    const context = await this.conversationManager.getContext(input)
    const prompt = await this.promptManager.buildPrompt(context, input)
    const rawResponse = await this.callLLMWithRetry(prompt)
    const parsedResponse = await this.responseParser.parse(rawResponse)
    const enrichedResponse = await this.enrichResponse(parsedResponse)
    await this.cacheManager.store(input, enrichedResponse)
    return enrichedResponse
  }
}

架构约束后的标准化:

// 标准化的LLM集成
export class LLMService {
  constructor(
    private openaiClient: OpenAIClient,
    private logger: Logger
  ) {}

  async generateSuggestion(sessionData: SessionData): Promise<string> {
    try {
      const prompt = this.buildPrompt(sessionData)
      const response = await this.openaiClient.chat.completions.create({
        model: 'gpt-4',
        messages: [{ role: 'user', content: prompt }],
        temperature: 0.7,
        max_tokens: 1000
      })
      return response.choices[0].message.content
    } catch (error) {
      this.logger.exception('Failed to generate suggestion', error)
      throw error
    }
  }

  private buildPrompt(sessionData: SessionData): string {
    return `基于用户会话数据,提供情绪建议:${JSON.stringify(sessionData)}`
  }
}

案例3:架构守护的自动化

实现的自动化检查:

// 每次提交前自动执行
{
  "scripts": {
    "pre-commit": "npm run type-check && npm run lint && npm run arch-check",
    "arch-check": "ts-node scripts/architectural-guard.ts",
    "type-check": "tsc --noEmit",
    "lint": "eslint src --ext .ts"
  }
}

// CI/CD管道中的架构检查
name: Architecture Check
on: [push, pull_request]
jobs:
  check-architecture:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v2
      - run: npm install
      - run: npm run arch-check
      - run: npm run test

🌟 总结:架构即代码的核心原则

架构思维的三个层次

1. 项目级架构(顶层设计)

  • 明确的技术栈约束
  • 标准化的文件结构
  • 严格的依赖管理规则
  • 统一的开发流程

2. 代码级架构(中层控制)

  • 函数设计的三重约束
  • 错误处理的统一标准
  • 类设计的简约原则
  • 接口设计的一致性

3. 流程级架构(底层保障)

  • 标准化的开发流程
  • 强制的代码审查
  • 自动化的架构守护
  • 持续的质量控制

实施架构即代码的步骤

第一步:建立架构文档

  • 创建详细的Claude.md
  • 定义明确的约束规则
  • 提供具体的代码模板
  • 制定质量检查清单

第二步:实现自动化守护

  • 创建架构检查脚本
  • 集成到CI/CD流程
  • 设置代码质量门禁
  • 建立持续监控机制

第三步:持续优化架构

  • 定期回顾架构效果
  • 根据实际问题调整规则
  • 优化自动化检查机制
  • 分享架构实践经验

关键成功要素

1. 约束的明确性

  • 每个规则都要具体可执行
  • 提供正面和负面示例
  • 定期检查规则的有效性
  • 及时更新过时的约束

2. 工具的自动化

  • 减少人工检查的依赖
  • 集成到开发工作流
  • 提供清晰的错误反馈
  • 确保检查的快速执行

3. 文化的持续性

  • 团队对架构约束的认同
  • 持续的架构思维培训
  • 定期的架构评审会议
  • 开放的问题反馈机制

记住:AI编程的核心不是"让AI做什么",而是"让AI不做什么"。好的架构就是为AI划定清晰的边界,让它在可控的范围内发挥价值。


下一篇预告: 《提示工程即架构:如何让AI理解你的真实需求》


微信搜索"四哥还会聊AI",看这些架构原则如何在实际项目中创造价值

微信搜索"汐屿笔记",看这些架构原则如何在实际项目中应用

← 返回首页