赞
踩
FastGPT 是一个基于 LLM 大语言模型的知识库问答系统,提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的问答场景!
在之前使用Gitlab CI进行AI Code Review的时候发现一些痛点,这次为了解决这些问题故在FastGPT平台上进行二次开发
优化提示词后需要多个项目同步修改
收集使用反馈困难
改动较多时候评论太多,影响人工评审
重试不方便
Review结果不佳
为了解决这些问题从两个角度出发
将Review任务放到平台上,发起合并请求的时候使用gitlab CI触发该任务(当前二次开发部分)
维护知识库,提高Review质量
NextJs + TS + ChakraUI + Mongo + Postgres (Vector 插件)
将项目下载到本地后对关键路径进行分析
fastgpt/projects/app/src/service: 存入mongo时的存储内容,相当于表设计
fastgpt/projects/app/src/web/core:接口使用
fastgpt/projects/app/src/pages:页面路由
fastgpt/projects/app/src/pages/api:API路由
每个工程都可以选择对应的应用或者提示词来进行代码评审
- // projects/app/src/types/mongoSchema.d.ts
- export interface ReviewSchema {
- _id: string;
- appName: string;
- projectId: string;
- prompt?: string;
- appId?: string;
- createTime: Date;
- lastUsedTime?: Date;
- }
实现增删改查
增加/修改
- // 增/改
- const { appName, prompt, projectId, appId, _id } = req.body;
- if (_id) {
- // 传入了_id则为修改
- response = await Review.updateOne({ _id }, { $set: { appName, prompt, appId, projectId } });
- } else {
- // 否则为新增
- response = await Review.create({ appName, prompt, appId, projectId });
- }
删除
- const { id } = req.query;
- await Review.deleteOne({ _id: id });
查看
- const { appName, id } = req.query;
- let response;
- if (appName) {
- response = await Review.find({ appName });
- } else if (id) {
- response = await Review.find({ _id: id });
- } else {
- response = await Review.find();
- }
每次Review都是一次任务
- // projects/app/src/types/mongoSchema.d.ts
- export interface ReviewJobSchema {
- _id: string;
- reviewId: string; // 对应ReviewSchema的_id
- projectId: string; // 对应ReviewSchema的projectId
- mrId: string;
- createTime: Date;
- }
查看任务
- const { projectId } = req.query;
- let response = await ReviewJob.find({ projectId }).sort({ createTime: -1 })
每个任务中有多条结果记录
- // projects/app/src/types/mongoSchema.d.ts
- export interface ReviewResultSchema {
- _id: string;
- jobId: string; // 对应ReviewJobSchema的_id
- newPath?: string;
- newLine?: number;
- oldPath?: string;
- oldLine?: number;
- body: string;
- ref: GitlabDiffRef;
- effective?: string | null;
- createTime: Date;
- }
查看结果
- const { jobId } = req.query;
- let response = await ReviewResult.find({ jobId }).sort({ createTime: -1 });
功能实现采用的是【第2924期】如何在 Gitlab 中使用 ChatGPT 进行 CodeReview:https://mp.weixin.qq.com/s/Dyk1cYg63oOs13f9_gf9ug
另外需要打通使用应用库来进行CodeReview的操作
从官方文档可以看出,FastGPT使用API访问
时,除域名外其他用法与直接使用Chatgpt一致,所以稍微修改一下原有的 chatgpt.ts
文件即可
这样就有两个执行文件了
- import run1 from '@/utils/review/chatgpt';
- import run2 from '@/utils/review/fastgpt';
执行任务的时候就是
根据传参查询指定工程
判断使用提示词还是应用
使用提示词则使用run1
使用的应用则使用run2
其中应用采用的是API访问,如果之前没有创建过,则新建一个,使用.lean()
从数据库中拿到API Key来进行操作
- let { projectId, mrId, target = /\.(js|jsx|ts|tsx|java)$/} = req.query
- let response = await Review.find({ projectId });
- let prompt = response[0].prompt;
- let appId = response[0].appId;
- // 创建review任务
- let response1 = await ReviewJob.create({
- reviewId: response[0]._id,
- projectId,
- mrId
- });
- let jobId = response1._id;
- if (appId) {
- // 当有appId时,使用fastgpt
- let res2;
- res2 = await MongoOpenApi.findOne({ appId }).lean();
- if (!res2?.apiKey) {
- let res1 = await MongoUser.findOne({ username: 'root' });
- let userId = res1?._id;
- const nanoid = customAlphabet(
- 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890',
- Math.floor(Math.random() * 14) + 24
- );
- let apiKey = `${global.systemEnv?.openapiPrefix || 'fastgpt'}-${nanoid()}`;
- await MongoOpenApi.create({
- userId,
- apiKey,
- appId,
- name: 'review',
- limit: {
- credit: -1
- }
- });
- }
- res2 = await MongoOpenApi.findOne({ appId }).lean();
- if (!res2?.apiKey) throw new Error('apiKey获取失败');
- run2({
- gitlabConfig: {
- host: 'https://gitlab.qunhequnhe.com',
- token: 'xxx',
- projectId,
- mrIId: mrId,
- target
- },
- fastgptConfig: {
- apikey: res2.apiKey,
- chatId: jobId
- },
- projectId,
- jobId
- });
- } else {
- // 当没有appId时,使用chatgpt
- run1({
- gitlabConfig: {
- host: 'https://gitlab.qunhequnhe.com',
- token: 'xxx',
- projectId,
- mrIId: mrId,
- target
- },
- chatgptConfig: {
- model: 'gpt-3.5-turbo-16k',
- prompt,
- language: 'Chinese'
- },
- projectId,
- jobId
- });
- }
- import { GET, POST, DELETE, PUT } from '@/web/common/api/request';
- import { CreateReviewParams } from '@/types/review';
-
- /**
- * 创建一个review工程任务
- */
- export const createReviewItem = (data: CreateReviewParams) => POST<string>('/review/create', data);
-
- /**
- * 获取review工程任务列表
- */
- export const getReviewList = (appName: string | null, id: string | null) =>
- GET<any>(`/review/list?appName=${appName}&id=${id}`);
-
- /**
- * 删除review工程任务
- */
- export const delReviewItem = (_id: string) => DELETE<any>(`/review/del?id=${_id}`);
-
- /**
- * 开始review工程任务
- * */
- export const startReviewItem = (projectId: string, mrId: string, target: string) =>
- GET<any>(`/review/work?projectId=${projectId}&mrId=${mrId}&target=${target}`);
-
- /**
- * 查询review结果
- * */
- export const getReviewResult = (projectId: string | null, jobId: string | null) =>
- GET<any>(`/review/results?projectId=${projectId}&jobId=${jobId}`);
-
- /**
- * 数据概览
- * */
- export const getReviewOverview = () => GET<any>(`/review/overview`);
-
- /**
- * 修改结果是否有效
- * */
- export const setEvaluateReviewResult = (_id: string, effective: string) =>
- POST<any>(`/review/evaluateResult?_id=${_id}&effective=${effective}`);
-
- /**
- * 通过jobId获取appId
- * */
- export const getAppIdByJobId = (jobId: string) =>
- GET<any>(`/review/getAppIdByJobId?jobId=${jobId}`);
页面部分代码略,展示样式
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。