专题十一:新 Agent 类型 max_tokens 不持久化,导致 UI 修改后又回到 8192
本专题记录 Dify 1.16 新 Agent 类型中的一个控制台持久化问题:
在 Agent 的「配置」页里把模型参数
Max Tokens从8192改成2048,点「构建 / 发布」后没有真正写入数据库,重新打开配置抽屉又变回8192。本文给出根因、数据库定位方法、逐步修改方法、验证方法、回滚方法,以及本次环境中的真实 ID 和现成 SQL。
运行环境:业务脚本均在 207 固定目录
/opt/workbuddy执行,Python 为/usr/bin/python3。 Windows 开发机仅保留_probe_*调试脚本;同步命令:python scripts_cursor/完整代码约定/00_部署_workbuddy到207.py。
一、现象
用户在 Dify 控制台中操作新 Agent:
- 打开 Agent 的「配置」页。
- 点击模型名
qwen3.6-27b或其右侧设置图标。 - 在参数抽屉中找到「最大 token 数 / Max Tokens」。
- 把值从
8192改成2048。 - 点击右上角「构建 / 发布」。
表面现象是:
- 点击发布后看起来没有明显报错,但也没有真正保存成功。
- 再次打开模型参数抽屉时,
Max Tokens又恢复成8192。 - 继续对话时,运行行为也仍然像是在使用默认的
8192。
这说明问题不是“用户没点对按钮”,而是“控制台修改没有真正落库”。
二、根因
根因已经确认:
- 这个问题发生在 Dify 1.16 新 Agent 类型 的模型参数持久化流程里。
- 控制台里虽然允许修改
max_tokens,但保存时 没有把该值正确写入新 Agent 的配置 JSON。 - 数据库里实际存的仍然是:
{
"model": {
"model": "qwen3.6-27b",
"model_provider": "langgenius/openai/openai",
"model_settings": {
"max_tokens": null,
"temperature": null,
"top_p": null,
"presence_penalty": null,
"frequency_penalty": null,
"response_format": null,
"stop": null
}
}
}关键点在这里:
"max_tokens": null当 max_tokens 是 null 时,Dify 不会把它当作用户显式设置的值,而是回退到插件 schema 里该模型的默认参数值。当前克隆出来的 OpenAI 兼容模板默认值是 8192,因此就会出现:
- 你明明在 UI 里改成了
2048 - 但重新打开后又显示
8192 - 实际运行时也还是按默认值去处理
所以这次不是插件代码逻辑错误,也不是模型服务本身错误,而是:
新 Agent 配置页修改了参数,但保存动作没有把 model.model_settings.max_tokens 写进数据库。
三、为什么不优先改插件代码
理论上,另一种思路是去修改 OpenAI 插件里该模型 schema 的默认 parameter rule,把默认 max_tokens 从 8192 改成 2048。
但这不是这次的首选方案,原因有四个:
- 影响面过大
- 改插件默认值会影响同一插件下所有依赖该 schema 的模型实例或后续新增实例。
- 这不是针对“某一个 Agent”的精确修复。
- 不能解决 UI 不持久化这个根因
- 即使你把默认值改成
2048,新 Agent 的 UI 仍然存在“保存不进库”的问题。 - 只是因为默认值碰巧变成了你想要的数,看起来像“好了”,但问题仍然在。
- 插件改动需要重启验证
- 改完插件通常要重启
plugin_daemon。 - 之前本环境已经踩过一次插件 patch 的坑:临时调试代码、
from __future__顺序、schema 解析等都可能引入新故障。
- 本问题最小修复面就是改库
- 问题本质是“某个 Agent 的配置 JSON 没写进去”。
- 那么最稳的修法就是:直接把这个 Agent 的配置 JSON 改对。
因此,本专题采用的方案是:
只改数据库中这个 Agent 的配置快照和编辑草稿,把 max_tokens 从 null 写成 2048。
四、新 Agent 到底读哪张表
这一步非常关键,因为很多人会下意识去改 app_model_configs,但 新 Agent 类型并不主要读取那张表。
本次排查确认,新 Agent 至少涉及下面两张表:
4.1 agent_config_snapshots
作用:
- 存放 已发布 / 活动中的 Agent 配置快照
- 运行时真正执行对话时,后端读的是这份配置
如果只改这一张表:
- 运行时会变成
2048 - 但控制台重新打开时,UI 可能还是显示旧值
4.2 agent_config_drafts
作用:
- 存放控制台配置页正在编辑的 草稿配置
- 前端打开 Agent 配置抽屉时,看到的参数值通常来自这里
如果只改这一张表:
- UI 里能看到
2048 - 但运行时真正执行仍可能用旧快照
4.3 为什么两张都要改
因为这两张表分别服务于两条链路:
- 运行链路:
agent_config_snapshots - UI 展示链路:
agent_config_drafts
只有同时修改,才能保证:
- 控制台再次打开时显示的是
2048 - 实际运行时读到的也是
2048 - 不会出现“UI 和运行值不一致”的情况
五、要改的 JSON 路径是什么
这两张表里都存在一列:
config_snapshot这一列存的是 JSON 文本。要改的路径统一是:
config_snapshot
-> model
-> model_settings
-> max_tokens也就是 JSON 里的:
{
"model": {
"model_settings": {
"max_tokens": 2048
}
}
}PostgreSQL 里对应的 jsonb_set 路径写法是:
'{model,model_settings,max_tokens}'六、本次环境信息
本次专题对应环境如下:
| 项目 | 值 |
|---|---|
| 服务器 | 192.168.110.207 |
| Dify 版本 | 1.16.1 |
| 数据库容器 | docker-db_postgres-1 |
| 数据库名 | dify |
| 数据库用户 | postgres |
| 目标模型 | qwen3.6-27b |
| 目标值 | max_tokens = 2048 |
本次真实操作中定位到的对象 ID 为:
| 对象 | UUID |
|---|---|
应用 app_id | 40e95fd3-e7f5-44f2-a03b-dc3e60413540 |
智能体 agent_id | 01a012e7-bed3-7574-b0d1-a5cc79a0d3de |
活动快照 snapshot_id | 01a0135c-320e-79dc-97a0-94da9b904c13 |
编辑草稿 draft_id | 01a012e7-bf60-7673-a894-64551d984a23 |
这组 ID 只适用于本次这个 Agent。别的 Agent 需要重新查询。
七、正式操作前的原则
直接改生产库前,先记住以下原则:
- 一定先备份原始 JSON
- 因为这不是普通标量字段,而是一大段配置 JSON。
- 如果改错 UUID 或误操作,最稳的恢复办法是把整段 JSON 覆盖回去。
- 必须精确按主键
id更新
- 不要用模糊条件,不要只按
agent_id批量 update。 - 推荐按
snapshot_id、draft_id两个具体主键分别改。
- 只改
max_tokens,不要顺手改别的参数
- 本次目的是精准修复 UI 不持久化,不是重写整份配置。
- 用
jsonb_set只覆盖目标字段,风险最小。
- 改完无需重启
- 这里改的是数据库配置,不是 Python 代码。
- 运行时读活动快照,数据落库后即可生效。
- 改完不要再依赖 UI 发布去“确认保存”
- 当前 bug 就在 UI 持久化链路上。
- 你再点发布,有可能又把值写回
null。
八、操作步骤
导读:UI 改 max_tokens 刷新又变 8192 → 改 Postgres 快照+草稿(§四~§八),改完勿点发布(§十)。
| 现象 | 处理 |
|---|---|
| UI 显示 8192 但 SQL 已是 32768 | 硬刷新;查 draft 与 snapshot 是否都改 |
| 点发布后变 null | 专题十二 空泡;重新 §八 SQL |
| 作业 4 验收后变 2048 | 作业 4 --restore |
8.1 第一步:进入数据库
SSH 登录 207 服务器后,进入 PostgreSQL:
完整脚本:scripts_bash_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_01.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_01.sh
#!/usr/bin/env bash
set -euo pipefail
docker exec -it docker-db_postgres-1 psql -U postgres -d dify正常会进入:
dify=#如果不确定容器名,可以先查:
完整脚本:scripts_bash_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_02.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_02.sh
#!/usr/bin/env bash
set -euo pipefail
docker ps --format '{{.Names}}' | grep postgres8.2 第二步:查出目标 Agent、快照、草稿
先列出所有新 Agent,并带出活动快照和草稿:
SELECT
ap.name AS app_name,
a.id AS agent_id,
a.active_config_snapshot_id AS snapshot_id,
d.id AS draft_id
FROM agents a
JOIN apps ap ON ap.id = a.app_id
LEFT JOIN agent_config_drafts d ON d.agent_id = a.id
ORDER BY ap.name;如果你知道应用名,也可以按名称过滤:
SELECT
ap.name AS app_name,
a.id AS agent_id,
a.active_config_snapshot_id AS snapshot_id,
d.id AS draft_id
FROM agents a
JOIN apps ap ON ap.id = a.app_id
LEFT JOIN agent_config_drafts d ON d.agent_id = a.id
WHERE ap.name ILIKE '%知识%';你需要记住三项:
agent_idsnapshot_iddraft_id
其中真正用于修改的是后两项。
8.3 第三步:确认当前值确实是 null
看活动快照里的 model_settings:
SELECT config_snapshot::json -> 'model' -> 'model_settings'
FROM agent_config_snapshots
WHERE id = '01a0135c-320e-79dc-97a0-94da9b904c13';看草稿里的 model_settings:
SELECT config_snapshot::json -> 'model' -> 'model_settings'
FROM agent_config_drafts
WHERE id = '01a012e7-bf60-7673-a894-64551d984a23';本次改前的典型输出是:
{
"frequency_penalty": null,
"max_tokens": null,
"presence_penalty": null,
"response_format": null,
"stop": null,
"temperature": null,
"top_p": null
}如果这里已经是 2048,说明该智能体已经改过,不需要重复更新。
8.4 第四步:备份两份原始 JSON
先备份活动快照:
SELECT config_snapshot
FROM agent_config_snapshots
WHERE id = '01a0135c-320e-79dc-97a0-94da9b904c13';再备份编辑草稿:
SELECT config_snapshot
FROM agent_config_drafts
WHERE id = '01a012e7-bf60-7673-a894-64551d984a23';把输出复制出来,分别保存成:
backup_snap.jsonbackup_draft.json
如果你习惯在宿主机直接导出到文件,也可以用:
完整脚本:scripts_bash_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_03.sh
运行/引用:bash /opt/workbuddy/scripts_bash_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_03.sh
#!/usr/bin/env bash
set -euo pipefail
docker exec docker-db_postgres-1 psql -U postgres -d dify -t -A -c \
"SELECT config_snapshot FROM agent_config_snapshots WHERE id='01a0135c-320e-79dc-97a0-94da9b904c13'" \
> backup_snap.json
docker exec docker-db_postgres-1 psql -U postgres -d dify -t -A -c \
"SELECT config_snapshot FROM agent_config_drafts WHERE id='01a012e7-bf60-7673-a894-64551d984a23'" \
> backup_draft.json本次环境里我们当时就是先把两份 JSON 备份了,再执行更新。
8.5 第五步:把 max_tokens 写成 2048
最推荐的写法是:用一个事务,同时改两张表。
BEGIN;
UPDATE agent_config_snapshots
SET config_snapshot = jsonb_set(
config_snapshot::jsonb,
'{model,model_settings,max_tokens}',
'2048'::jsonb
)::text
WHERE id = '01a0135c-320e-79dc-97a0-94da9b904c13';
UPDATE agent_config_drafts
SET config_snapshot = jsonb_set(
config_snapshot::jsonb,
'{model,model_settings,max_tokens}',
'2048'::jsonb
)::text
WHERE id = '01a012e7-bf60-7673-a894-64551d984a23';
COMMIT;8.6 每一行 SQL 在干什么
为了避免“知道能跑,但不知道为什么这么写”,下面把关键点讲清楚:
config_snapshot::jsonb
原字段是文本,所以先转成 jsonb,这样 PostgreSQL 才能对 JSON 路径做更新。
jsonb_set(...)
这是 PostgreSQL 修改 JSON 某个节点的标准函数。
语义是:
- 找到目标路径
- 只修改那个节点
- 其它 JSON 内容原样保留
'{model,model_settings,max_tokens}'
这是目标路径:
- 第一层
model - 第二层
model_settings - 第三层
max_tokens
'2048'::jsonb
这里刻意转成 JSON 数字,不是字符串。
正确:
'2048'::jsonb错误:
'"2048"'::jsonb如果写成字符串,后续某些逻辑可能把它当文本,不是我们要的类型。
)::text
因为原列是文本而不是 jsonb 列,所以最后再转回文本写回去。
8.7 如何判断 UPDATE 成功
每条 UPDATE 执行后,应该返回:
UPDATE 1这表示确实命中了 1 行。
如果看到:
UPDATE 0说明:
- UUID 写错了
- 或者查错环境 / 查错库 / 查错表
这时不要继续,应该立刻:
ROLLBACK;重新核对 ID 再来。
九、验证方法
更新完成后,必须做两层验证。
9.1 第一层:数据库验证
再次查询两个表里的 max_tokens:
SELECT 'snapshot' AS which,
config_snapshot::json -> 'model' -> 'model_settings' -> 'max_tokens' AS max_tokens
FROM agent_config_snapshots
WHERE id = '01a0135c-320e-79dc-97a0-94da9b904c13'
UNION ALL
SELECT 'draft',
config_snapshot::json -> 'model' -> 'model_settings' -> 'max_tokens'
FROM agent_config_drafts
WHERE id = '01a012e7-bf60-7673-a894-64551d984a23';正确结果应类似:
which | max_tokens
---------+-----------
snapshot | 2048
draft | 2048这一步是最关键的验证,因为它说明:
- 运行时配置已是
2048 - UI 读取的草稿也是
2048
9.2 第二层:控制台验证
在浏览器里:
- 对 Dify 控制台强制刷新一次,例如
Ctrl + F5 - 重新进入该 Agent 的「配置」页
- 打开模型参数抽屉
- 查看
Max Tokens
正确现象应该是:
- 抽屉里显示
2048 - 不需要再点击“发布”来让它生效
9.3 第三层:运行验证
直接在该 Agent 的预览 / 对话页发起一次普通问答即可。
由于运行时读取的是活动快照,如果数据库里 snapshot 已经是 2048,那么这次对话就已经按 2048 执行。
十、为什么改完以后不要再点“发布”
这是很多人最容易下意识去做的一步。
直觉会觉得:
我虽然改了库,但还是想回控制台点一下发布,让它“正式生效”。
但本专题里 不建议这么做,原因是:
- 当前问题本身就出在新 Agent 的 UI 持久化链路
- 你重新点发布,Dify 可能又会把这份草稿重新保存成:
"max_tokens": null这样你刚才手工写进去的 2048 就会被覆盖掉。
因此正确做法是:
- 改库
- 验证库
- 强刷 UI 看显示
- 直接测试问答
不要多做那一步“发布确认”。
十一、回滚方法
如果出现以下任一情况:
- 改错了 Agent
- 错把别的业务配置写坏了
- 想恢复成改前状态
最稳的办法是把之前备份出来的整段 JSON 原样覆盖回去。
11.1 用整段 JSON 回滚
BEGIN;
UPDATE agent_config_snapshots
SET config_snapshot = '这里粘贴 backup_snap.json 的完整内容'
WHERE id = '01a0135c-320e-79dc-97a0-94da9b904c13';
UPDATE agent_config_drafts
SET config_snapshot = '这里粘贴 backup_draft.json 的完整内容'
WHERE id = '01a012e7-bf60-7673-a894-64551d984a23';
COMMIT;注意:
- 如果 JSON 文本中带单引号,需要按 SQL 规则写成两个单引号
'' - 最稳妥的做法仍然是从文件导入或脚本化执行
11.2 只把 max_tokens 改回 null
如果你不想整段回滚,只想恢复“Dify 默认行为”,也可以只把该字段改回 null:
UPDATE agent_config_snapshots
SET config_snapshot = jsonb_set(
config_snapshot::jsonb,
'{model,model_settings,max_tokens}',
'null'::jsonb
)::text
WHERE id = '01a0135c-320e-79dc-97a0-94da9b904c13';
UPDATE agent_config_drafts
SET config_snapshot = jsonb_set(
config_snapshot::jsonb,
'{model,model_settings,max_tokens}',
'null'::jsonb
)::text
WHERE id = '01a012e7-bf60-7673-a894-64551d984a23';这样做的效果是:
- UI 又可能显示回默认
8192 - 运行时也重新走默认 schema 的回退值
十二、本次环境中已经验证过的现成 SQL
如果你现在就是在 207 这台机器 上,且目标就是这次同一个 Agent,那么可以直接使用下面这一版:
BEGIN;
UPDATE agent_config_snapshots
SET config_snapshot = jsonb_set(
config_snapshot::jsonb,
'{model,model_settings,max_tokens}',
'2048'::jsonb
)::text
WHERE id = '01a0135c-320e-79dc-97a0-94da9b904c13';
UPDATE agent_config_drafts
SET config_snapshot = jsonb_set(
config_snapshot::jsonb,
'{model,model_settings,max_tokens}',
'2048'::jsonb
)::text
WHERE id = '01a012e7-bf60-7673-a894-64551d984a23';
COMMIT;验证 SQL:
SELECT 'snapshot' AS which,
config_snapshot::json -> 'model' -> 'model_settings' -> 'max_tokens' AS max_tokens
FROM agent_config_snapshots
WHERE id = '01a0135c-320e-79dc-97a0-94da9b904c13'
UNION ALL
SELECT 'draft',
config_snapshot::json -> 'model' -> 'model_settings' -> 'max_tokens'
FROM agent_config_drafts
WHERE id = '01a012e7-bf60-7673-a894-64551d984a23';十三、如果是别的 Agent,怎么套用
如果你后续还要改别的 Agent,不需要重新研究原理,按下面套模板就行:
- 先查出该 Agent 的:
agent_idsnapshot_iddraft_id
- 先看两份
model_settings是否还是max_tokens = null - 先备份两份
config_snapshot - 用
jsonb_set把两个表里的max_tokens同时改成目标值 - 再跑验证 SQL
- 强刷 UI 看显示
唯一需要替换的通常只有三处:
snapshot_iddraft_id- 目标值
2048
比如要改成 1024,只需要把:
'2048'::jsonb换成:
'1024'::jsonb十四、常见误区
14.1 误区一:去改 app_model_configs
旧版应用很多配置确实会落在 app_model_configs,但本次这个新 Agent 问题,真正需要改的是:
agent_config_snapshotsagent_config_drafts
改错表等于白改。
14.2 误区二:只改一张表
只改快照:
- 运行时可能好了
- UI 还不对
只改草稿:
- UI 看起来好了
- 实际运行还是旧值
必须两张都改。
14.3 误区三:把 2048 写成字符串
不要写成:
'"2048"'::jsonb要写成:
'2048'::jsonb我们要的是 JSON 数字,不是字符串。
14.4 误区四:改完再去点发布
这次 bug 恰恰就在发布 / 保存链路里。 你再点一次,可能把修复结果覆盖掉。
14.5 误区五:为了这件事去改插件默认值
这不是最小修复面,而且会扩大影响范围。 本专题的重点是修复某个 Agent 当前配置未持久化的问题,不是全局重构默认参数策略。
十五、本次修复后的结论
本次在 207 环境里,已经完成并验证:
agent_config_snapshots中该 Agent 的model.model_settings.max_tokens已写成2048agent_config_drafts中该 Agent 的model.model_settings.max_tokens已写成2048- 两边一致
- 运行时和 UI 显示值保持一致
- 不需要修改插件代码
- 不需要重启服务
因此,这个问题的最稳修法可以概括为一句话:
Dify 1.16 新 Agent 的
max_tokens在 UI 中未持久化时,直接改agent_config_snapshots与agent_config_drafts两张表的config_snapshot -> model -> model_settings -> max_tokens即可。
十六、附:本次用于自动化处理的脚本思路
本次实际操作时,曾使用脚本做了三件事:
- 读取两张表的原始
config_snapshot - 导出为本地备份文件
- 对两个主键执行
jsonb_set(... max_tokens = 2048 ...) - 再次查询并验证结果
脚本本质上做的事与本文 SQL 完全一致,核心更新语句就是:
UPDATE {table}
SET config_snapshot = jsonb_set(
config_snapshot::jsonb,
'{model,model_settings,max_tokens}',
'2048'::jsonb
)::text
WHERE id = '{具体主键}';也就是说,后续如果你想把这套动作封装成固定运维脚本,可以直接基于本文的 SQL 实现,不需要额外猜测底层逻辑。
十七、最终建议
在 Dify 官方修复这个新 Agent 参数持久化问题之前,建议这样使用:
- UI 主要用于查看,不作为
max_tokens的最终真相来源 - 涉及关键模型参数时,以数据库查询结果为准
- 新 Agent 若需精确控制
max_tokens,优先走改库 - 若后续在 UI 修改了提示词、知识库或其它配置,改完后再核查一次
max_tokens是否被写回null
这样可以避免同一类问题反复出现。
本专题 Python 程序一览
| 文件 | 用途 | |---|---|| 专题十一_01_查max_tokens现状.py | 专题十一 · 步骤 1:只读查看快照与草稿当前 max_tokens(期望改前为 null)。 | | 专题十一_02_备份快照与草稿.py | 专题十一 · 步骤 2:备份活动快照与编辑草稿 config_snapshot 到远程文件。 | | 专题十一_03_写max_tokens为2048_修改后.py | 专题十一 · 步骤 3 · 修改后:把快照与草稿 max_tokens 写成 2048(改完不要点发布)。 | | 专题十一_04_验证max_tokens.py | 专题十一 · 步骤 4:验证快照与草稿 max_tokens 均为 2048。 |
专题十一_01_查max_tokens现状.py
运行:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_01_查max_tokens现状.py
完整补丁:patches_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_01.py
运行/引用:见 patches_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_01.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""专题十一 · 步骤 1:只读查看快照与草稿当前 max_tokens(期望改前为 null)。"""
from __future__ import annotations
import json
import sys
import _bootstrap # noqa: F401
import _agent_db as A
import _config as C
from dify_api import Dify
def main() -> int:
d = Dify(C.DIFY_EMAIL, C.DIFY_PASSWORD)
try:
d.login()
for which, table, rid in (
("snapshot", "agent_config_snapshots", C.SNAP_ID),
("draft", "agent_config_drafts", C.DRAFT_ID),
):
out, _ = d.sh(
"docker exec %s psql -U postgres -d dify -t -A -c "
"\"SELECT config_snapshot::json -> 'model' -> 'model_settings' "
"FROM %s WHERE id='%s'\"" % (C.PG_CONTAINER, table, rid)
)
print("=== %s (%s) ===" % (which, rid))
try:
print(json.dumps(json.loads(out), ensure_ascii=False, indent=2))
except Exception:
print(out.strip())
snap_tok = A.read_max_tokens(d, "agent_config_snapshots", C.SNAP_ID)
draft_tok = A.read_max_tokens(d, "agent_config_drafts", C.DRAFT_ID)
print("\nmax_tokens snapshot=%s draft=%s" % (snap_tok, draft_tok))
return 0
finally:
d.close()
if __name__ == "__main__":
sys.exit(main())专题十一_02_备份快照与草稿.py
运行:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_02_备份快照与草稿.py
完整补丁:patches_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_02.py
运行/引用:见 patches_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_02.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""专题十一 · 步骤 2:备份活动快照与编辑草稿 config_snapshot 到远程文件。"""
from __future__ import annotations
import sys
import _bootstrap # noqa: F401
import _agent_db as A
import _config as C
from dify_api import Dify
def main() -> int:
d = Dify(C.DIFY_EMAIL, C.DIFY_PASSWORD)
try:
d.login()
A.backup_snapshot(d, "agent_config_snapshots", C.SNAP_ID, "snap_before_maxtok")
A.backup_snapshot(d, "agent_config_drafts", C.DRAFT_ID, "draft_before_maxtok")
return 0
finally:
d.close()
if __name__ == "__main__":
sys.exit(main())专题十一_03_写max_tokens为2048_修改后.py
运行:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_03_写max_tokens为2048_修改后.py
完整补丁:patches_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_03.py
运行/引用:见 patches_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_03.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""专题十一 · 步骤 3 · 修改后:把快照与草稿 max_tokens 写成 2048(改完不要点发布)。"""
from __future__ import annotations
import sys
import _bootstrap # noqa: F401
import _agent_db as A
import _config as C
from dify_api import Dify
def main() -> int:
d = Dify(C.DIFY_EMAIL, C.DIFY_PASSWORD)
try:
d.login()
sql = "BEGIN;\n"
for table, rid in (
("agent_config_snapshots", C.SNAP_ID),
("agent_config_drafts", C.DRAFT_ID),
):
sql += (
"UPDATE %s SET config_snapshot = jsonb_set("
"config_snapshot::jsonb, '{model,model_settings,max_tokens}', '%s'::jsonb)::text "
"WHERE id='%s';\n" % (table, C.MAX_TOKENS_SMALL, rid)
)
sql += "COMMIT;\n"
print(A.psql(d, sql))
A.verify_max_tokens(d, C.SNAP_ID, C.DRAFT_ID)
print("\n[WARN] 改完不要点「构建/发布」")
return 0
finally:
d.close()
if __name__ == "__main__":
sys.exit(main())专题十一_04_验证max_tokens.py
运行:/usr/bin/python3 /opt/workbuddy/scripts_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_04_验证max_tokens.py
完整补丁:patches_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_04.py
运行/引用:见 patches_cursor/Dify_专题十一_新Agent类型max_tokens不持久化/专题十一_内联_04.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""专题十一 · 步骤 4:验证快照与草稿 max_tokens 均为 2048。"""
from __future__ import annotations
import sys
import _bootstrap # noqa: F401
import _agent_db as A
import _config as C
from dify_api import Dify
def main() -> int:
d = Dify(C.DIFY_EMAIL, C.DIFY_PASSWORD)
try:
d.login()
A.verify_max_tokens(d, C.SNAP_ID, C.DRAFT_ID)
snap = A.read_max_tokens(d, "agent_config_snapshots", C.SNAP_ID)
draft = A.read_max_tokens(d, "agent_config_drafts", C.DRAFT_ID)
ok = str(snap) == str(C.MAX_TOKENS_SMALL) and str(draft) == str(C.MAX_TOKENS_SMALL)
print("\n[OK]" if ok else "\n[FAIL]", "期望均为", C.MAX_TOKENS_SMALL)
return 0 if ok else 1
finally:
d.close()
if __name__ == "__main__":
sys.exit(main())