🚀 从零打造你的 Git 提交 AI 助手:React + Express + Ollama 全栈实战指南

42 阅读6分钟

🚀 从零打造你的 Git 提交 AI 助手:React + Express + Ollama 全栈实战指南

在现代软件开发中,规范的 Git 提交信息不仅是代码历史的“日记本”,更是团队协作、代码审查、自动化发布甚至个人技术成长的重要依据。然而,很多开发者(尤其是新手)常常写出如 fix bugupdate 这样模糊不清的提交信息,严重影响了项目的可维护性。

有没有一种方式,能让我们像资深工程师一样,自动生成专业、清晰、符合 Conventional Commits 规范的提交信息?

答案是:有!而且你可以自己动手做一个!

本文将带你从零开始,用 React(前端) + Express(后端) + Ollama(本地大模型)  搭建一个属于你自己的 Git 提交 AI 神器。整个过程不仅实用,还能让你深入理解前后端通信、跨域、API 设计、本地大模型调用等核心开发技能。


🌟 项目目标:输入 Git Diff,输出高质量 Commit Message

  • 用户在终端执行 git diff,得到一段代码变更。
  • 将这段 diff 发送给我们的 Web 应用。
  • 后端调用本地部署的大语言模型(LLM),根据 diff 内容生成规范的提交信息。
  • 前端展示结果,用户复制即可使用。

✅ 最终效果:
输入:+ console.log('hello')
输出:feat: add hello log for debugging


🧱 技术栈全景图

表格

层级技术作用
前端React + Vite + Tailwind CSS + Axios用户界面、发起请求、响应式更新
后端Node.js + Express接收请求、调用 AI、返回结果
AI 引擎Ollama + DeepSeek-R1:8B本地运行开源大模型,生成 commit message
工具链CORS、Nodemon、LangChain解决跨域、热重载、简化 LLM 调用

🛠 第一步:搭建后端服务(Express)

1. 初始化项目

mkdir git-commit-ai-server
cd git-commit-ai-server
npm init -y
npm install express cors @langchain/ollama @langchain/core
npm install -D nodemon

2. 编写 server.js

// server.js
import express from 'express';
import cors from 'cors';
import { ChatOllama } from '@langchain/ollama';
import { ChatPromptTemplate } from '@langchain/core/prompts';
import { StringOutputParser } from '@langchain/core/output_parsers';

// 创建 Express 应用
const app = express();

// 中间件:解析 JSON 请求体 + 允许跨域
app.use(express.json());
app.use(cors());

// 配置本地大模型(通过 Ollama)
const model = new ChatOllama({
  baseUrl: "http://localhost:11434", // Ollama 默认地址
  model: "deepseek-r1:8b",          // 使用 DeepSeek 开源模型
  temperature: 0.1                  // 降低随机性,输出更稳定
});

// 定义提示词模板(Prompt Engineering)
const prompt = ChatPromptTemplate.fromMessages([
  ["system", "你是一位专业的 Git 提交信息撰写专家。请根据以下代码变更(git diff),生成一条符合 Conventional Commits 规范的简短提交信息。只输出提交信息,不要任何解释或额外内容。"],
  ["user", "{diff}"]
]);

// 构建处理链:提示词 → 模型 → 字符串输出
const chain = prompt.pipe(model).pipe(new StringOutputParser());

// 路由:健康检查
app.get('/hello', (req, res) => {
  res.send('Hello from Git Commit AI Server!');
});

// 核心路由:接收 diff,返回 commit message
app.post('/chat', async (req, res) => {
  const { message: diff } = req.body;

  // 参数校验
  if (!diff || typeof diff !== 'string') {
    return res.status(400).json({ error: 'Invalid or missing "message" field' });
  }

  try {
    // 调用 AI 链
    const commitMessage = await chain.invoke({ diff });
    res.json({ data: commitMessage.trim() }); // 返回干净字符串
  } catch (error) {
    console.error('AI generation failed:', error);
    res.status(500).json({ error: 'Failed to generate commit message' });
  }
});

// 启动服务器
const PORT = 3000;
app.listen(PORT, () => {
  console.log(`✅ Server running on http://localhost:${PORT}`);
});

3. 启动后端

确保你已安装 Ollama 并拉取模型:

ollama pull deepseek-r1:8b

然后启动服务:

npx nodemon server.js

✅ 访问 http://localhost:3000/hello 应看到 “Hello from Git Commit AI Server!”


💻 第二步:构建前端界面(React + Vite)

1. 创建前端项目

npm create vite@latest git-commit-ai-frontend -- --template react
cd git-commit-ai-frontend
npm install axios
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

配置 tailwind.config.js

export default {
  content: ["./index.html", "./src/**/*.{js,jsx,ts,tsx}"],
  theme: { extend: {} },
  plugins: [],
}

在 src/index.css 中加入:

@tailwind base;
@tailwind components;
@tailwind utilities;

2. 封装 API 请求(src/api/index.js

import axios from 'axios';

// 创建 axios 实例,统一配置
const service = axios.create({
  baseURL: 'http://localhost:3000',
  headers: { 'Content-Type': 'application/json' },
  timeout: 600000, // 10分钟超时(大模型推理可能较慢)
});

// 导出 chat 接口
export const chat = (message) => service.post('/chat', { message });

3. 自定义 Hook:useDiffsrc/hooks/useGitDiff.js

import { useState, useEffect } from 'react';
import { chat } from '../api/index';

// 封装副作用逻辑:当 diff 变化时,自动请求 AI
export const useDiff = (diff) => {
  const [content, setContent] = useState('');
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    if (!diff) return; // 防止空请求

    const fetchCommitMessage = async () => {
      setLoading(true);
      try {
        const { data } = await chat(diff);
        setContent(data); // 响应式更新 UI
      } catch (error) {
        setContent('❌ AI 生成失败,请检查后端或网络');
        console.error(error);
      } finally {
        setLoading(false);
      }
    };

    fetchCommitMessage();
  }, [diff]); // 依赖项:仅当 diff 改变时重新执行

  return { loading, content };
};

4. 主组件:App.jsx

import React, { useState } from 'react';
import { useDiff } from './hooks/useGitDiff';

export default function App() {
  const [input, setInput] = useState(''); // 用户输入的 diff
  const { loading, content } = useDiff(input);

  return (
    <div className="min-h-screen bg-gray-50 flex flex-col items-center justify-center p-6">
      <h1 className="text-3xl font-bold text-indigo-700 mb-6">🤖 Git 提交 AI 助手</h1>

      <textarea
        value={input}
        onChange={(e) => setInput(e.target.value)}
        placeholder="粘贴你的 git diff 内容..."
        className="w-full max-w-2xl h-40 p-4 border border-gray-300 rounded-lg shadow-sm focus:ring-2 focus:ring-indigo-500 focus:outline-none"
      />

      <div className="mt-6 w-full max-w-2xl p-4 bg-white rounded-lg shadow-md min-h-[60px]">
        {loading ? (
          <p className="text-gray-500">🧠 正在思考中,请稍候...</p>
        ) : content ? (
          <p className="font-mono text-green-700 break-words">{content}</p>
        ) : (
          <p className="text-gray-400">提交信息将在这里显示...</p>
        )}
      </div>

      <p className="mt-8 text-sm text-gray-500">
        基于本地大模型 · 无需联网 · 数据安全
      </p>
    </div>
  );
}

5. 启动前端

npm run dev

访问 http://localhost:5173,你应该能看到一个简洁美观的界面!


🔌 关键知识点详解

1. 为什么需要 CORS?

  • 前端运行在 http://localhost:5173
  • 后端运行在 http://localhost:3000
  • 端口不同 → 跨域
  • 浏览器出于安全,默认阻止跨域请求
  • app.use(cors()) 相当于给前端发“签证”,允许它访问后端资源

2. Axios vs Fetch

  • fetch 是浏览器原生 API,但语法繁琐(需手动 .json()
  • axios 更简洁、支持拦截器、自动转换 JSON、更好的错误处理
  • 适合封装统一 API 层

3. useEffect + async 的正确写法

不能直接在 useEffect 中写 async,因为会返回 Promise,而 React 期望返回清理函数。
所以采用 IIFE(立即执行函数)  包裹:

useEffect(() => {
  (async () => {
    // 异步逻辑
  })();
}, []);

4. LangChain 的作用

  • 简化与 LLM 的交互
  • ChatPromptTemplate:结构化提示词
  • StringOutputParser:自动提取纯文本结果
  • 链式调用(.pipe())让代码更清晰

5. Conventional Commits 规范

格式:<type>(<scope>): <subject>

  • feat: 新功能
  • fix: 修复 bug
  • docs: 文档更新
  • style: 代码格式调整
  • refactor: 重构
  • test: 测试相关
  • chore: 构建/工具变更

我们的 AI 会自动遵循这一规范!


🧪 测试你的 AI 助手

  1. 在任意 Git 仓库中运行:

    git diff
    
  2. 复制输出(例如新增一行 console.log('test')

  3. 粘贴到前端文本框

  4. 等待几秒,你会看到类似:

    feat: add test log for debugging
    

🚀 扩展方向

  • 添加“复制到剪贴板”按钮
  • 支持多模型切换(Qwen、Llama3 等)
  • 集成到 VS Code 插件
  • 添加历史记录功能
  • 部署到云服务器(Docker + Nginx)

✅ 总结

你刚刚完成了一个真正有用的全栈 AI 工具:

  • 前端:用 React Hook 封装业务逻辑,UI 简洁响应式
  • 后端:Express 提供稳定 API,集成 LangChain 调用本地大模型
  • AI:Ollama 让你在本地免费运行 8B 参数大模型,数据不出内网
  • 工程化:模块化、错误处理、状态管理一应俱全

这不仅是一个 Git 工具,更是你掌握现代 Web 开发 + 本地 AI 应用的完美起点。

🌈 记住:最好的学习,就是做出能解决实际问题的东西。

现在,去试试吧!让你的每一次 git commit,都像资深工程师一样专业!