一、项目需求

1.1 一句话描述

在终端运行 commit-agent,自动读取当前 git diff,调用 DeepSeek API 生成规范化的 commit message,用户确认后提交。

1.2 功能清单(v1)

功能优先级说明
读取 git diffP0自动获取当前仓库的变更
调用 DeepSeek API 生成 commit messageP0使用 DeepSeek Function Calling
预览确认P0展示生成的 message,让用户 Y/N 确认
CLI 入口P1支持 --model--stage 等参数
自动暂存P1--stage 参数自动 git add -A

1.3 非功能性需求

  • Token 消耗低:单次调用不超过 2000 tokens
  • 零外部依赖:除了 openai SDK 不需要其他第三方库
  • 容错:git diff 为空、API 调用失败等场景有明确的错误提示

二、系统架构

2.1 整体架构图

┌──────────────────────────────────────────────────────┐
│                   用户终端 (CLI)                      │
│  $ commit-agent [--stage] [--model deepseek-chat]    │
└─────────────────────┬────────────────────────────────┘
                      │
┌─────────────────────▼────────────────────────────────┐
│                   agent.py                           │
│              Agent 核心流程协调器                      │
│  ┌──────────────────────────────────────────────────┐ │
│  │  ① 读取 diff (git_utils)                         │ │
│  │  ② 调用 DeepSeek API (llm_client + 工具定义)      │ │
│  │  ③ 解析响应,提取 commit message                  │ │
│  │  ④ 返回结果给 CLI                                 │ │
│  └──────────────────────────────────────────────────┘ │
└─────────────────────┬────────────────────────────────┘
          ┌───────────┼───────────┐
          │           │           │
          ▼           ▼           ▼
┌─────────────┐ ┌──────────┐ ┌──────────┐
│  git_utils   │ │llm_client│ │ prompts  │
│  git 操作封装 │ │API 封装  │ │ 模板管理  │
└─────────────┘ └──────────┘ └──────────┘

2.2 数据流

Step 1: git_utils.get_full_diff()
        ──→ 返回 diff 字符串(或空字符串)

Step 2: agent.py 组装 system prompt + diff
        ──→ 调用 llm_client.send_with_tools()

Step 3: llm_client 返回 DeepSeek 响应
        ──→ message 中可能包含 tool_calls

Step 4: agent.py 解析 tool_calls
        ──→ 提取 tool_call.function.arguments 中的 title / type / body

Step 5: cli.py 展示给用户
        ──→ 用户确认后调用 git_utils.commit()

三、模块划分

3.1 模块总览

commit_agent/
├── __init__.py
├── cli.py          # CLI 入口,参数解析,用户交互
├── agent.py        # Agent 核心流程编排
├── git_utils.py    # git diff/commit/stage 操作
├── llm_client.py   # DeepSeek API 封装 + 工具定义
└── prompts.py      # System prompt 模板

3.2 各模块职责

模块职责对外暴露
cli.py解析命令行参数、展示预览、处理用户输入、调用 agent 和 git_utils 完成完整流程main()
agent.py编排 Agent 流程:读 diff → 调 API → 解析响应 → 返回结构化结果generate_commit_message()
git_utils.py封装所有 git 子进程调用get_full_diff(), commit(), stage_all()
llm_client.py封装 DeepSeek API(OpenAI 兼容 SDK) + 工具定义LLMClient
prompts.py管理 system prompt 和消息模板SYSTEM_PROMPT, build_diff_prompt()

四、核心接口设计

4.1 git_utils.py

def get_full_diff() -> str
    """获取工作区所有变更(staged + unstaged)的 diff"""

def get_staged_diff() -> str
    """仅获取已暂存的 diff"""

def stage_all() -> None
    """暂存所有变更:git add -A"""

def commit(message: str) -> None
    """执行 git commit -m "<message>"
    失败时抛出 RuntimeError"""

4.2 prompts.py

# 常量
SYSTEM_PROMPT: str
    """System prompt:定义 Agent 角色、commit 规范、输出格式要求"""

# 函数
def build_diff_prompt(diff: str) -> str
    """将 diff 包装成 user message
    若 diff 为空,返回特殊提示"""

4.3 llm_client.py

class LLMClient:
    def __init__(self, api_key: str, model: str = "deepseek-chat"):
        """初始化 DeepSeek 客户端(OpenAI 兼容 SDK)"""

    @staticmethod
    def define_tools() -> list
        """返回工具定义列表(OpenAI Function Calling 格式)
        定义 generate_commit_message 工具:
          - 参数: title(str), type(enum: feat/fix/refactor/...), body(str?)
          - 约束: title 不超过 72 字符,type 必须在枚举中
        """

    def send_with_tools(self, system_prompt: str, user_message: str) -> dict
        """发送请求并返回原始响应
        返回内容包含 message.content 和 message.tool_calls"""

4.4 agent.py

def generate_commit_message(
    api_key: str,
    model: str = "deepseek-chat"
) -> dict
    """Agent 主流程:
    1. 调用 git_utils.get_full_diff()
    2. 组装 prompt,调用 LLMClient
    3. 解析 tool_calls
    4. 返回 {"type": str, "title": str, "body": str}
    或 {"error": str}

    返回值格式(成功):
    {"type": "feat", "title": "feat: 添加用户登录", "body": "..."}
    返回值格式(失败):
    {"error": "没有检测到代码变更"}
    """

4.5 cli.py

def main()
    """CLI 入口,支持参数:
    --model: 模型名称(默认 deepseek-chat)
    --stage: 自动暂存所有变更
    --api-key: API Key(默认读环境变量 DEEPSEEK_API_KEY)

    流程:
    1. 解析参数
    2. 可选:自动暂存
    3. 调用 agent
    4. 展示预览
    5. 交互确认
    6. 执行 commit
    """

五、工具定义设计

这是 Agent 的说明书,定义好坏直接影响 LLM 的调用准确性。采用 OpenAI / DeepSeek 兼容格式:

{
  "type": "function",
  "function": {
    "name": "generate_commit_message",
    "description": "根据 git diff 生成符合 Conventional Commits 规范的 commit message。"
                    "分析变更的类型(feat/fix/refactor/docs/style/test/chore)"
                    "和影响范围,返回格式化的提交标题与正文。",
    "parameters": {
      "type": "object",
      "properties": {
        "title": {
          "type": "string",
          "description": "commit 标题,格式为 <type>: <描述>,不超过 72 字符"
        },
        "type": {
          "type": "string",
          "enum": ["feat", "fix", "refactor", "docs", "style", "test", "chore"],
          "description": "变更类型:feat=新功能, fix=修复, refactor=重构, docs=文档, style=格式, test=测试, chore=构建/工具"
        },
        "body": {
          "type": "string",
          "description": "commit 正文(可选),说明为什么做这个变更而非做了什么,每行不超过 72 字符"
        }
      },
      "required": ["title", "type"]
    }
  }
}

和 Anthropic 格式的对比

对比项AnthropicDeepSeek / OpenAI
外层包装{"type": "function", "function": {...}}
参数名input_schemaparameters
响应方式content 中的 tool_use blockmessage.tool_calls 数组
arguments 类型直接是 dictJSON 字符串

六、总结

设计要点回顾

方面决策理由
架构单 Agent + 单工具复杂度最低,聚焦核心概念
工具数1 个v1 不需要多个工具
APIDeepSeek(OpenAI 兼容格式)你有 API Key,通用性强
SDKopenai (Python)最广泛使用的 LLM SDK
框架无框架,直接调 SDK理解底层,避免抽象泄露
CLIargparse 原生零额外依赖
环境变量DEEPSEEK_API_KEY与 DeepSeek 官方推荐一致
Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐