Changes: - Rename skill.md to SKILL.md (uppercase required) - Add YAML frontmatter with name and description - Reorganize templates/ and examples/ into references/ - Remove extra documentation files (README.md, QUICK_REF.md) - Follow progressive disclosure pattern: keep SKILL.md lean The skill now complies with the official Claude Code skill format. Co-Authored-By: Claude <noreply@anthropic.com>
327 lines
8.7 KiB
Markdown
327 lines
8.7 KiB
Markdown
# 完整协作会话示例
|
||
|
||
## 场景:实现用户认证功能
|
||
|
||
### 阶段 1:需求分析
|
||
|
||
**用户需求**:
|
||
```
|
||
我需要为我的 FastAPI 应用添加用户认证功能,包括:
|
||
1. 用户注册(邮箱+密码)
|
||
2. 用户登录(返回JWT token)
|
||
3. Token验证中间件
|
||
4. 密码重置功能
|
||
```
|
||
|
||
**Claude Code 调用 Codex**:
|
||
```python
|
||
# 第一阶段:需求分析
|
||
codex(
|
||
PROMPT="""
|
||
请分析以下用户认证需求,并提供:
|
||
1. 需求理解和目标拆解
|
||
2. 技术方案建议
|
||
3. 风险点和注意事项
|
||
4. 实施建议
|
||
|
||
需求:
|
||
- 用户注册(邮箱+密码)
|
||
- 用户登录(返回JWT token)
|
||
- Token验证中间件
|
||
- 密码重置功能
|
||
|
||
项目背景:
|
||
- FastAPI 应用
|
||
- PostgreSQL 数据库
|
||
- 已有用户表(id, email, created_at)
|
||
""",
|
||
cd="/project",
|
||
sandbox="read-only",
|
||
return_all_messages=False
|
||
)
|
||
```
|
||
|
||
**Codex 返回**:
|
||
```json
|
||
{
|
||
"success": true,
|
||
"SESSION_ID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
|
||
"agent_messages": "## 需求分析结果\n\n### 1. 需求理解\n核心需求是实现完整的用户认证系统...\n\n### 2. 技术方案建议\n- 使用 passlib 进行密码哈希\n- 使用 python-jose 处理 JWT\n- 使用 FastAPI Depends 实现中间件\n\n### 3. 风险点\n- 密码安全:必须使用 bcrypt 且 salt rounds >= 12\n- Token 安全:使用 RS256 签名,设置合理过期时间\n- 密码重置:需要安全的 token 生成机制\n\n### 4. 实施建议\n按以下顺序实现:\n1. 密码哈希工具\n2. JWT 工具\n3. 注册端点\n4. 登录端点\n5. 认证中间件\n6. 密码重置"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 阶段 2:方案讨论
|
||
|
||
**Claude Code 继续讨论**:
|
||
```python
|
||
# 使用同一 SESSION_ID 继续对话
|
||
codex(
|
||
PROMPT="""
|
||
关于你的方案,我有几个疑问:
|
||
|
||
1. 关于密码重置,你建议使用什么机制生成重置 token?
|
||
2. JWT 的过期时间建议设置为多长?
|
||
3. 是否需要实现 refresh token 机制?
|
||
4. 数据库是否需要新增字段?
|
||
|
||
请详细说明。
|
||
""",
|
||
cd="/project",
|
||
SESSION_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890",
|
||
sandbox="read-only"
|
||
)
|
||
```
|
||
|
||
**Codex 返回详细解答**...
|
||
|
||
---
|
||
|
||
### 阶段 3:请求代码原型
|
||
|
||
**Claude Code 请求原型**:
|
||
```python
|
||
# 请求代码原型(仅 unified diff patch)
|
||
codex(
|
||
PROMPT="""
|
||
基于我们讨论的方案,请提供代码实现原型。
|
||
|
||
**重要要求**:
|
||
- 仅提供 unified diff patch 格式
|
||
- 不要实际修改任何代码
|
||
- 包含完整的类型注解
|
||
- 关键逻辑添加注释说明
|
||
|
||
需要实现的模块:
|
||
1. src/auth/password.py - 密码哈希工具
|
||
2. src/auth/jwt.py - JWT 工具
|
||
3. src/api/endpoints/auth.py - 认证端点
|
||
4. src/auth/dependencies.py - FastAPI 依赖
|
||
|
||
请按文件分别提供 diff。
|
||
""",
|
||
cd="/project",
|
||
SESSION_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890",
|
||
sandbox="read-only"
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
### 阶段 4:Claude Code 实现
|
||
|
||
**Claude Code 基于 Codex 的原型,重新编写生产级代码**:
|
||
```python
|
||
# Claude Code 使用 Edit 工具编写实际代码
|
||
|
||
# 1. 创建密码哈希模块
|
||
# src/auth/password.py
|
||
from passlib.context import CryptContext
|
||
|
||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||
|
||
def verify_password(plain_password: str, hashed_password: str) -> bool:
|
||
"""验证密码"""
|
||
return pwd_context.verify(plain_password, hashed_password)
|
||
|
||
def get_password_hash(password: str) -> str:
|
||
"""生成密码哈希"""
|
||
return pwd_context.hash(password)
|
||
|
||
# 2. 创建 JWT 工具模块
|
||
# src/auth/jwt.py
|
||
from datetime import datetime, timedelta
|
||
from jose import JWTError, jwt
|
||
from typing import Optional
|
||
|
||
SECRET_KEY = "your-secret-key-here"
|
||
ALGORITHM = "HS256"
|
||
|
||
def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
|
||
"""创建访问令牌"""
|
||
to_encode = data.copy()
|
||
expire = datetime.utcnow() + (expires_delta or timedelta(minutes=15))
|
||
to_encode.update({"exp": expire})
|
||
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
|
||
|
||
# 3. 创建认证端点
|
||
# src/api/endpoints/auth.py
|
||
from fastapi import APIRouter, HTTPException, Depends
|
||
from pydantic import BaseModel
|
||
|
||
router = APIRouter()
|
||
|
||
class LoginRequest(BaseModel):
|
||
email: str
|
||
password: str
|
||
|
||
@router.post("/login")
|
||
async def login(req: LoginRequest):
|
||
# 实现登录逻辑
|
||
pass
|
||
|
||
# 4. 创建认证依赖
|
||
# src/auth/dependencies.py
|
||
from fastapi import Depends, HTTPException, status
|
||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||
|
||
security = HTTPBearer()
|
||
|
||
async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)):
|
||
"""获取当前用户"""
|
||
# 实现 token 验证逻辑
|
||
pass
|
||
```
|
||
|
||
---
|
||
|
||
### 阶段 5:代码审查
|
||
|
||
**Claude Code 完成编码后,立即请求审查**:
|
||
```python
|
||
# 请求 Codex 审查代码
|
||
codex(
|
||
PROMPT=f"""
|
||
请审查以下代码改动:
|
||
|
||
## 改动文件列表
|
||
- src/auth/password.py(新建):密码哈希工具
|
||
- src/auth/jwt.py(新建):JWT 工具
|
||
- src/api/endpoints/auth.py(新建):认证端点
|
||
- src/auth/dependencies.py(新建):认证依赖
|
||
|
||
## 改动说明
|
||
实现了完整的用户认证系统:
|
||
1. 使用 bcrypt 进行密码哈希(salt rounds=12)
|
||
2. 使用 HS256 算法生成 JWT,默认15分钟过期
|
||
3. 提供 /login 和 /register 端点
|
||
4. 实现 get_current_user 依赖用于保护路由
|
||
|
||
## 原始需求
|
||
实现用户注册、登录、Token验证和密码重置功能
|
||
|
||
请按以下维度审查:
|
||
1. 正确性 - 是否正确实现需求
|
||
2. 代码质量 - 可读性和可维护性
|
||
3. 安全性 - 密码和 token 安全
|
||
4. 边界情况 - 异常处理
|
||
5. 测试覆盖 - 是否需要测试
|
||
|
||
请提供:
|
||
1. 总体评价
|
||
2. 必须修复的问题(如有)
|
||
3. 建议改进的地方
|
||
""",
|
||
cd="/project",
|
||
SESSION_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
||
)
|
||
```
|
||
|
||
**Codex 审查结果**:
|
||
```json
|
||
{
|
||
"success": true,
|
||
"agent_messages": "## 审查结果\n\n### 总体评价:良好\n\n### 必须修复的问题:\n1. SECRET_KEY 硬编码在代码中,应该从环境变量读取\n2. 缺少密码强度验证\n3. jwt.decode() 没有异常处理\n\n### 建议改进:\n1. 建议添加 refresh token 机制\n2. 密码重置功能还未实现\n3. 建议添加速率限制防止暴力破解\n4. 建议添加日志记录"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 阶段 6:根据审查调整
|
||
|
||
**Claude Code 根据审查意见进行调整**:
|
||
```python
|
||
# 修复必须修复的问题
|
||
|
||
# 1. 修改 jwt.py,从环境变量读取 SECRET_KEY
|
||
import os
|
||
from dotenv import load_dotenv
|
||
|
||
load_dotenv()
|
||
SECRET_KEY = os.getenv("JWT_SECRET_KEY")
|
||
if not SECRET_KEY:
|
||
raise ValueError("JWT_SECRET_KEY environment variable is not set")
|
||
|
||
# 2. 添加密码强度验证
|
||
# src/auth/validators.py
|
||
import re
|
||
|
||
def validate_password_strength(password: str) -> bool:
|
||
"""验证密码强度"""
|
||
if len(password) < 8:
|
||
return False
|
||
if not re.search(r"[A-Z]", password):
|
||
return False
|
||
if not re.search(r"[a-z]", password):
|
||
return False
|
||
if not re.search(r"\d", password):
|
||
return False
|
||
return True
|
||
|
||
# 3. 添加 JWT 异常处理
|
||
# src/auth/jwt.py
|
||
def decode_token(token: str):
|
||
"""解码 JWT token"""
|
||
try:
|
||
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
|
||
return payload
|
||
except JWTError as e:
|
||
raise HTTPException(
|
||
status_code=status.HTTP_401_UNAUTHORIZED,
|
||
detail=f"Invalid token: {str(e)}"
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
### 阶段 7:最终审查
|
||
|
||
**Claude Code 再次请求审查**:
|
||
```python
|
||
codex(
|
||
PROMPT="""
|
||
我已根据你的审查意见进行了修复:
|
||
1. SECRET_KEY 从环境变量读取
|
||
2. 添加了密码强度验证
|
||
3. 添加了 JWT 异常处理
|
||
|
||
请再次审查,确认是否还有问题。
|
||
""",
|
||
cd="/project",
|
||
SESSION_ID="a1b2c3d4-e5f6-7890-abcd-ef1234567890"
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 协作流程总结
|
||
|
||
```
|
||
用户需求
|
||
↓
|
||
[阶段1] Codex 需求分析 → 获得 SESSION_ID
|
||
↓
|
||
[阶段2] 多轮讨论完善方案 → 使用同一 SESSION_ID
|
||
↓
|
||
[阶段3] 请求代码原型(unified diff)→ 使用同一 SESSION_ID
|
||
↓
|
||
[阶段4] Claude Code 重写生产级代码
|
||
↓
|
||
[阶段5] Codex 代码审查 → 使用同一 SESSION_ID
|
||
↓
|
||
[阶段6] 根据审查调整代码
|
||
↓
|
||
[阶段7] 最终审查确认 → 使用同一 SESSION_ID
|
||
↓
|
||
完成
|
||
```
|
||
|
||
## 关键要点
|
||
|
||
1. **始终使用同一 SESSION_ID**:保持上下文连贯
|
||
2. **批判性思维**:对 Codex 的建议保持审视
|
||
3. **安全优先**:使用 sandbox="read-only"
|
||
4. **重写代码**:基于原型编写生产级代码
|
||
5. **即时审查**:完成后立即让 Codex review
|