n8n插件增加repeat_penalty参数适配Qwen3
问题起因
n8n是一个不错的大模型Agent工作流平台,内置了很多有用的节点。尤其对原生AI的支持变成除了dify以外的新宠。但是最近在使用过程中由于要适配阿里的Qwen3模型,出现了问题。
按照Qwen3的官方指引,需要设置repeat_penalty的值为1.1,否则很可能出现复读机的问题。需要设置这个参数。
使用Ollama作为LLM运行支持
使用ollama的话,可以在模型的Modelfile配置的PARAMETER里直接设置,是没有什么影响的。但是ollama由于性能的问题,不合适生产环境。生产环境更适合vllm方式的推理,使用openai模式接口。
使用VLLM作为LLM运行支持
使用vllm作为llm运行支持的话。如果不是直接使用python调用,则需要使用openAI模式的接口。而openAI接口 的Parameter里,竟然不支持repeat_penalty。经过一昼夜折腾,终于实现了repeat_penalty的设置方式,如图:
修改代码
由于官方的openAI Chat插件不支持这个参数,因此需要修改源码。分两个部分的代码需要修改,一个是界面配置的,一个是逻辑执行的,缺一不可。
注意这里说的修改源码,不需要clone n8n项目,直接在dist目录里修改即可。因此即使是-g全局安装的n8n也没有关系。
界面代码
如果不特别申明的话,以下相对路径都是以n8n的运行目录为初始位置。
nodes.json
node_modules/@n8n/n8n-nodes-langchain/dist/types/nodes.json
编译完的应该是压缩的json格式,可以用工具格式化以下,方便查看也方便插入。找到
"displayName": "OpenAI Chat Model"
下的节点:
{
"displayName": "Presence Penalty",
"name": "presencePenalty",
"default": 0,
"typeOptions": {
"maxValue": 2,
"minValue": -2,
"numberPrecision": 1
},
"description": "Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics",
"type": "number"
},
注意一定要是OpenAI Chat Model下的,其它的不用改,因为VLLM我们只用Opai API接口。
在后面插入一条:
{
"displayName": "Repeat Penalty",
"name": "repeatPenalty",
"default": 1.0,
"typeOptions": { "maxValue": 2, "minValue": 0, "numberPrecision": 1 },
"description": "重复内容惩罚for Qwen 3",
"type": "number"
},
LmChatOpenAi.node.js
node_modules/@n8n/n8n-nodes-langchain/dist/nodes/llms/LMChatOpenAi/LmChatOpenAi.node.js
在
{
displayName: "Presence Penalty",
name: "presencePenalty",
default: 0,
typeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },
description: "Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics",
type: "number"
},
之后插入一个节点:
{
displayName: "Repeat Penalty",
name: "repeatPenalty",
default: 1.0,
typeOptions: { maxValue: 2, minValue: 0, numberPrecision: 1 },
description: "重复内容惩罚for Qwen 3",
type: "number"
},
这样界面的修改就完成了
服务逻辑代码
服务逻辑这里找了大半天才找到,本以为界面看到就可以了。结果发现请求的时候始终没有记录repeat_penalty,才发现服务端逻辑也需要修改。折腾结果记录如下:
由于使用的是包 @langchain/openai,因此扩充openAI的参数需要修改包下面的代码,如果使用pnpm则可能会修改到全局的模块,是否要复制出来随意。
需要修改的代码都在
node_modules/@langchain/openai/dist/
之下:
涉及的代码清单
- chat_models.cjs
- chat_models.d.ts
- chat_models.js
- llms.cjs
- llms.d.ts
- llms.js
修改的地方无非就是多传一个值,直接搜索frequencyPenalty,在后面依葫芦画瓢添加repeatPenalty的代码,以下代码红色部分:
frequencyPenalty?: number;
repeatPenalty?: number;
presencePenalty?: number;
以及
/** Penalizes repeated tokens according to frequency */
frequencyPenalty: number;
/** Qwen3参数 */
repeatPenalty: number;
/** Penalizes repeated tokens */
presencePenalty: number;
还有
this.frequencyPenalty = fields?.frequencyPenalty ?? this.frequencyPenalty;
this.repeatPenalty = fields?.repeatPenalty ?? this.repeatPenalty;
this.presencePenalty = fields?.presencePenalty ?? this.presencePenalty;
frequency_penalty: this.frequencyPenalty,
repeat_penalty: this.repeatPenalty,
presence_penalty: this.presencePenalty,
"frequencyPenalty",
"repeatPenalty",
"presencePenalty",
Object.defineProperty(this, "frequencyPenalty", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "repeatPenalty", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "presencePenalty", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
修改完后,重启n8n应用,ctrl+F5强制刷新一下,应该就可以发现repeat_penalty已经生效,和我截图的效果一致,输出的结果也能印证这点。
例如:参数repeat_penalty = 2.0
prompt:念20遍:我爱祖国
看看重复惩罚的规则生效能不能把AI给罚跪了😏