AI编程新范式:UNIT-00:Berserk Interface结对编程实践与效果评估

最近几个月,我一直在尝试一种新的编程方式:和AI结对编程。听起来有点科幻,但实际体验下来,感觉就像身边多了一个不知疲倦、知识渊博的编程伙伴。这次我深度体验了UNIT-00:Berserk Interface(以下简称Berserk),想和大家分享一下,一个真实的项目从零到一,和AI一起完成是什么感觉。

很多人可能觉得AI编程就是让AI写代码,自己当甩手掌柜。其实完全不是这样。好的结对编程,是人和AI的深度协作。AI负责处理那些繁琐、重复、需要快速检索知识的工作,而人则负责把控方向、设计架构、审查逻辑和做出最终决策。这有点像从“自己开车”变成了“坐在副驾的领航员”,车还是你在开,但路线规划、路况提醒、甚至帮你递杯水的工作,都有人分担了。

这次我选择了一个不算复杂但很典型的后端服务项目:一个简单的待办事项(Todo)API服务。麻雀虽小,五脏俱全,它涵盖了用户认证、数据增删改查、错误处理、单元测试和API文档等现代Web开发的常见环节。下面,我就带你完整走一遍这个过程,看看Berserk在各个阶段的表现到底怎么样。

1. 项目启动与需求澄清

任何项目的第一步都是搞清楚要做什么。以前,这一步要么是自己闷头想,要么是和产品经理反复沟通。现在,我有了一个新的对话对象。

我打开Berserk的聊天界面,没有直接说“帮我写个Todo应用”,而是像和同事沟通一样,描述了背景和初步想法:

“我想构建一个个人使用的待办事项API服务,后端用Python的FastAPI框架。它需要支持用户注册登录(JWT token),每个用户只能管理自己的待办事项。每个待办事项有标题、描述、完成状态和创建时间。需要完整的CRUD接口。另外,我希望代码结构清晰,有基本的错误处理,并且最后能生成API文档。”

Berserk的回复没有立刻跳转到代码,而是先帮我梳理和确认需求:

“好的,我们先明确一下这个Todo API的核心需求:

  1. 用户系统:注册、登录(返回JWT)、获取当前用户信息。
  2. Todo管理:针对登录用户,实现创建、读取(列表和详情)、更新(标记完成/修改内容)、删除待办事项。
  3. 技术栈:Python, FastAPI, SQLite(或你偏好的数据库),JWT认证。
  4. 工程要求:清晰的模块化结构、输入验证(Pydantic)、统一错误响应、自动化API文档(FastAPI自动提供)。

这是一个很好的起点。为了确保我们理解一致,你能确认一下数据库的选择吗?比如先用轻量级的SQLite本地开发?”

这个回复让我有点惊喜。它没有急于表现,而是先做“需求确认”,这恰恰是结对编程中非常重要的第一步——对齐认知。我回复确认使用SQLite,并补充说希望使用SQLAlchemy作为ORM来保持灵活性。

基于确认后的需求,Berserk给出了一个初步的项目结构建议:

todo_api/
├── app/
│   ├── __init__.py
│   ├── main.py          # FastAPI应用入口
│   ├── core/            # 核心配置(安全、数据库等)
│   ├── models/          # SQLAlchemy数据模型
│   ├── schemas/         # Pydantic模型(请求/响应格式)
│   ├── crud/            # 数据库增删改查操作
│   ├── api/             # 路由端点
│   └── tests/           # 单元测试
├── requirements.txt
└── README.md

这个结构非常标准,符合FastAPI社区的常见实践。它不是一个死板的模板,而是一个可讨论的蓝图。我告诉它,我觉得crud层可以暂时和api层合并,让初期结构更简单,它立刻表示赞同并调整了建议。这种“可讨论”的感觉,是传统代码生成工具无法提供的。

2. 核心模块的协同构建

有了清晰的结构图,我们就可以开始“施工”了。我采取的方式是:由我驱动,告诉Berserk接下来要构建哪个模块,然后由它生成代码草案,我来审查、修改和集成。

2.1 数据模型与数据库配置

我首先提出:“我们先从数据模型开始吧。请创建用户(User)和待办事项(Todo)的SQLAlchemy模型,并设置数据库连接。”

Berserk很快给出了两个模型的代码。以Todo模型为例:

# app/models/todo.py
from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String, Text
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
from app.db.base import Base  # 假设我们有一个Base类

class Todo(Base):
    __tablename__ = "todos"

    id = Column(Integer, primary_key=True, index=True)
    title = Column(String(100), nullable=False)
    description = Column(Text, nullable=True)
    is_completed = Column(Boolean, default=False)
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    owner_id = Column(Integer, ForeignKey("users.id"), nullable=False)

    # 关系
    owner = relationship("User", back_populates="todos")

同时,它也提供了数据库连接和会话管理的核心代码草案。我审查后发现,它自动使用了created_at字段并设置了默认时间,这个细节考虑得很周到。但我指出,我希望updated_at字段来跟踪最后修改时间。它立刻道歉并提供了修改后的版本。

这个交互过程很高效。我不需要去记忆SQLAlchemy每个字段的精确参数,也不需要去查文档看时间字段如何设置默认值。我只需要提出概念(“我们需要一个创建时间字段”),AI就能给出符合最佳实践的实现草案,而我则专注于业务逻辑是否正确(“每个Todo必须属于一个User”)。

2.2 认证系统的实现

接下来是棘手的JWT认证。我提出需求:“现在实现用户认证。需要用户注册、登录(校验密码并返回JWT Token)的端点。密码需要哈希存储,登录后其他端点需要Token保护。”

Berserk的表现像是一个熟悉FastAPI生态的助手。它给出了以下关键代码片段:

  1. 密码工具:使用passlibbcrypt上下文。
  2. JWT工具:生成和验证Token的函数,包含了密钥、算法和过期时间的配置建议。
  3. 依赖项:一个get_current_user依赖注入函数,用于在需要认证的路由中自动获取当前用户。
# app/core/security.py
from passlib.context import CryptContext
from jose import JWTError, jwt
from datetime import datetime, timedelta

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

def verify_password(plain_password, hashed_password):
    return pwd_context.verify(plain_password, hashed_password)

def get_password_hash(password):
    return pwd_context.hash(password)

# JWT相关函数...
# app/api/deps.py
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from app.core import security

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="login")

async def get_current_user(token: str = Depends(oauth2_scheme)):
    credentials_exception = HTTPException(...)
    try:
        payload = security.decode_access_token(token)
        user_id: int = payload.get("sub")
        if user_id is None:
            raise credentials_exception
    except JWTError:
        raise credentials_exception
    user = crud.user.get(db, user_id) # 需要注入db session
    if user is None:
        raise credentials_exception
    return user

它甚至提醒我:“get_current_user依赖项需要数据库会话,你可能需要在路由层面通过依赖注入引入db,或者使用中间件。常见的做法是创建一个get_db依赖项。” 这体现了它对FastAPI设计模式的理解。

2.3 API端点的快速迭代

构建完基础设施,编写业务端点就快多了。我给出指令:“现在实现Todo的CRUD端点。所有端点都需要认证。列出Todo时,只返回当前用户的。”

Berserk几乎是在我发送指令的瞬间,就生成了一个完整的todos.py路由文件草案。包括GET /todos/, POST /todos/, GET /todos/{id}, PUT /todos/{id}, DELETE /todos/{id}。代码结构清晰,使用了Pydantic模型进行请求验证和响应序列化,错误处理也考虑到了“未找到”和“无权访问”的情况。

我扮演了代码审查者的角色。我指出:“在更新Todo的端点里,你用了todo.update(update_data.dict(exclude_unset=True)),这个exclude_unset=True用得挺好,可以局部更新。但请确保传入的update_dataTodoUpdate schema,而不是TodoCreate。”

它接受了反馈,并修正了schema的定义和用法。这种即时反馈和修正的循环,极大地加快了开发速度,并且保证了代码质量。

3. 测试与文档的自动化辅助

功能开发告一段落,但一个完整的项目还需要测试和文档。这是AI非常擅长的领域。

3.1 单元测试的生成

我对Berserk说:“为GET /todos/POST /todos/这两个端点编写Pytest单元测试。需要测试认证失败的情况和成功的情况。”

它生成的测试代码超出了我的预期。它不仅写了测试函数,还搭建了完整的测试夹具(fixture),包括测试客户端、覆盖认证的测试用户创建和Token生成、以及每个测试后的数据库清理。

# app/tests/test_todos.py
import pytest
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session

def test_create_todo_authenticated(client: TestClient, test_user_token_headers: dict):
    """测试认证用户创建Todo"""
    data = {"title": "Test Todo", "description": "Test Description"}
    response = client.post("/todos/", json=data, headers=test_user_token_headers)
    assert response.status_code == 200
    content = response.json()
    assert content["title"] == data["title"]
    assert content["owner_id"] == 1  # 假设测试用户ID为1

def test_read_todos_unauthenticated(client: TestClient):
    """测试未认证用户访问列表应失败"""
    response = client.get("/todos/")
    assert response.status_code == 401

它甚至为不同的测试场景(成功、失败、边界条件)生成了多个用例。我只需要运行这些测试,并根据实际情况微调数据库连接和断言即可。这节省了我大量编写样板测试代码的时间。

3.2 文档的补充与整理

FastAPI虽然能自动生成交互式API文档,但项目的README.md和代码中的文档字符串(docstring)仍然很重要。我让Berserk:“为项目主模块和主要的Pydantic模型添加Google风格的docstring,并生成一个简单的README.md,包含项目简介、安装步骤和运行方法。”

它出色地完成了任务。生成的README.md结构清晰,包含了pip install -r requirements.txtuvicorn app.main:app --reload等标准命令。为代码添加的docstring也格式规范,描述了参数、返回值和可能抛出的异常。

这虽然不是核心业务逻辑,但却是项目可维护性和协作性的关键。AI自动化这部分工作,让我能更专注于逻辑本身。

4. 效果评估与真实感受

经过这样一个完整项目的协作,我对AI结对编程有了更具体的认识。下面从几个维度总结一下Berserk的表现:

优势与高光时刻:

  1. 知识检索与代码生成速度极快:这是最明显的优势。无论是SQLAlchemy的模型定义、FastAPI的依赖注入,还是Pydantic的复杂验证,我无需离开编辑器去搜索文档。只需用自然语言描述意图,就能得到可用的代码草案,开发流程变得异常流畅。
  2. 减少上下文切换与认知负荷:编程时常需要在脑海中和编辑器、终端、浏览器文档之间来回切换。AI助手将这些上下文整合在一个聊天窗口里。思考“如何用SQLAlchemy设置一个带时区的时间戳默认值”时,答案直接出现在我思考的流中,思维不被中断。
  3. 优秀的“草案作者”和“细节提醒者”:它非常擅长根据我的高层描述,快速生成结构良好、符合惯例的代码草案。同时,它能注意到我可能忽略的细节,比如密码哈希、JWT过期、局部更新数据(exclude_unset)、测试后的数据清理等。
  4. 提升测试与文档的完整性:编写测试和文档往往是开发中最枯燥的部分。AI能快速生成覆盖基础场景的测试用例和格式规范的文档骨架,我只需进行审查和补充,这大大提高了项目的完整度。

局限与需要注意的地方:

  1. 它不负责“设计”与“决策”:AI无法替代架构师。项目整体采用MVC还是DDD?数据库选型是SQLite还是PostgreSQL?何时引入缓存?这些决策必须由开发者做出。AI只是一个高效的执行者。
  2. 代码需要“审查”,而非“信任”:AI生成的代码并非总是完美或最优。有时它会采用过时的方法,或对复杂业务逻辑的理解出现偏差。我的角色从“编写者”变成了“审查与集成者”,这要求我对代码有更强的理解力和批判性思维。
  3. 对复杂、模糊需求的处理能力有限:当需求描述不够精确时,AI容易产生误解。例如,我说“需要一个权限系统”,它可能生成一个简单的角色模型,但无法理解我心中复杂的多租户权限体系。清晰的沟通变得比以往任何时候都重要。
  4. 可能产生“幻觉”:在极少数情况下,AI会引用不存在的库函数或API。虽然Berserk在这方面的表现很稳定,但开发者仍需对关键代码保持警惕,不能盲目复制粘贴。

对我工作流的真实改变:

最大的改变是,我不再“孤独地编程”。以前遇到问题,我需要打断思路去搜索;现在,我可以像问同事一样自然提问。整个编程过程更像是一场持续的、高带宽的对话。我将更多脑力资源分配给了系统设计、业务逻辑梳理和代码质量审查,而将语法记忆、API查阅和样板代码编写交给了AI。

它没有让我失业,而是让我更像一个“技术领航员”和“资深工程师”,去处理更有价值的工作。


整体体验下来,与UNIT-00:Berserk Interface的结对编程是一次非常高效和愉悦的旅程。它显著加速了从想法到原型的过程,特别是在搭建项目骨架、实现标准功能和编写配套代码方面。它就像一个反应迅速、知识全面的初级开发者,能够完美地执行清晰的指令。

当然,它无法替代工程师的核心价值——创造性解决问题、做出技术权衡和设计复杂系统。未来的AI编程,或许不是“AI取代程序员”,而是“会使用AI的程序员取代不会使用AI的程序员”。掌握与AI协作的技巧,清晰地表达需求,有效地审查和集成AI的输出,将成为开发者新的核心竞争力。如果你还没试过,我强烈建议你找一个具体的项目,亲自体验一下这种新的编程范式,它可能会改变你对“写代码”这件事的看法。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐