Git及dockerhub初体验:Nextchat小改进
- IT
- 10小时前
- 14热度
- 0评论
众所周知nextchat项目(https://github.com/ChatGPTNextWeb/NextChat)的更新是很慢的。这么说其实并不严谨,在Github上它的代码库经常更新,但打包很“懒”,往往代码已经更新了很多轮,但dockerhub上的版本还是几个月之前的。
最让人难以接受的是对bug的反馈。诸如claude系列自从4.1版本开始就不再同时接受temperature和top_p参数了,在issue中提出了很久,一直无人问津。猜想可能大家都已经用上了自定义版本的nextchat,只有我这个“小白”还在依赖官方的docker吧。
曾经尝试过在vps上git clone整个项目后手动编译,但编译对服务器的CPU与内存要求较高,在小鸡上尝试几次均告失败。其实最好的方式是在自己的github上fork一个nextchat,然后在docker hub上创建自己的docker image。
恰逢ChatGPT Codex风头正劲,一直在琢磨着用Codex在Github上干点“大活”,捣腾Github也是迟早的事情,就拿Nextchat先试一试。
1、创建github与dockerhub帐号
这一步不再赘述,其实只需要创建github帐号即可,dockerhub可以直接使用github的凭证登录。
假设github上的帐号名称是mygitname。
2、Fork
进入nextchat的github项目主页,在Code页,右上角点击“Fork”,选择“Create a new fork”。输入合适的项目名称和描述,并勾选“Copy the main branch only”。点击Create fork,这一步将把nextchat的当前仓库中的main分支全部复制到自己的github帐户中。
3、定位并修改anthropic.ts代码
询问ChatGPT可知,Claude的参数传递应该在anthropic.ts中进行设置。对仓库中的文件进行简单分析,很快就能定位到关键代码位于:app/api/anthropic.ts。
进入该文件页面,点击右上角的“Edit this file”,将其中的req.body段稍作修改:
// 读取 body 并做参数检查 / 过滤
if (req.body) {
try {
const clonedBody = await req.text();
const jsonBody = JSON.parse(clonedBody) as {
model?: string;
temperature?: number;
top_p?: number;
};
const modelName = jsonBody.model?.toLowerCase() || "";
// ---------- Claude 参数修正逻辑 ----------
// 仅在 Claude 4.1 及之后版本应用过滤
if (modelName.includes("claude")) {
// 从 4.1 开始的所有模型都会触发参数冲突
const needsFilter =
/claude[-_]?(4(\.|-)|opus|sonnet)/i.test(modelName);
if (
needsFilter &&
jsonBody.temperature !== undefined &&
jsonBody.top_p !== undefined
) {
delete jsonBody.top_p;
console.log(
"[Claude param fix] Removed top_p for model:",
jsonBody.model,
);
}
}
// ---------- 模型白名单检查 ----------
if (
serverConfig.customModels &&
isModelNotavailableInServer(
serverConfig.customModels,
jsonBody.model as string,
ServiceProvider.Anthropic as string,
)
) {
return NextResponse.json(
{
error: true,
message: `you are not allowed to use ${jsonBody?.model} model`,
},
{ status: 403 },
);
}
fetchOptions.body = JSON.stringify(jsonBody);
} catch (e) {
console.error("[Anthropic] filter", e);
}
}
使用正则表达式对Claude系列模型进行匹配,这就实现了4.1及以上版本时,仅传递temperature参数,删除top_p参数,解决了这个bug。
点击右上角“commit changes”保存修改。
4、生成dockerhub secret密钥
下一步是生成修改后的自定义docker image。为了做到这一点,首先需要生成dockerhub的密钥,并设置到github中,这才能实现从github往dockerhub的自动推送。
登录hub.docker.com,在右上角的个人帐户头像中,单击“Accout Settings”,点击左侧的“Personal access tokens”,然后点击Generate new token。这里注意,由于这个token将用于github推送docker,所以要赋予其全部权限(Read, Write, Delete)。描述建议就用nextchat,这样和项目对应起来。生成后,记录用户名并妥善保存token。注意,这个token的内容只会展示一次。
返回到github,进入自己的nextchat项目(https://github.com/mygitname/NextChat)中。进入“Settings”页,在左侧找到“Secrets and Variables” - “Actions”,依次添加两个secrets:DOCKER_USERNAME及DOCKER_TOKEN,分别对应在hub.docker.com上的用户名与刚刚生成的token。
5、创建docker空仓库
再回到https://hub.docker.com,点击Create a repository创建一个空仓库,名称就叫nextchat。由于之前我们假设我们的github用户名、docker用户名均为mygitname,那么,这个docker空仓库的名称就叫“mygitname/nextchat”。创建空仓库这一步是必要的,相当于为后续github action的推送指定了目的地。
6、使用github action创建并推送docker
回到github自己的nextchat项目(https://github.com/mygitname/NextChat)。点击“Actions”页,单击“New workflow”。可以看到github已经贴心地为我们准备好了docker image的模板。点击模板上的configue按钮,编辑其内容如下:
name: Docker Image CI
on:
workflow_dispatch:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
push: true
tags: docker.io/${{ secrets.DOCKER_USERNAME }}/nextchat:latest
这里引用了之前已经设置好的两个secret。
保存之后,在左侧会出现“Docker Image CI”的workflow。点击它,在右侧点击“Run workflow”,github就会自动开始创建并推送docker了。这个过程可能需要几分钟,之后会有成功完成的提示。
检查hub.docker.com,不出意外的话,自定义docker已经发布。那么,接下来就可以在vps上直接使用这个docker了。
7、后记:开源之殇
nextchat之所以如此表现是可以理解的。他们早就开始为企业提供付费服务,在这种情况下还继续开源已经是作贡献了。如果想要顺利地使用这份开源成果,就需要用户自己动手,或自己编译,或自己改改bug然后重新打包——这制造了一个门槛。这个门槛并不高,但它拦住了那些纯“伸手党”。从本质上讲,既然已经到了使用开源软件的程度,那么付出一点点学习成本是再正常不过的,因为天下没有完全免费的午餐,别人手把手教你的时间,也都是有成本的。
对我来说,下一步就是连接Codex和github——新的探险旅程就要开始了。