# 霜砚·思维逻辑链 · 2026-05-10(日) · 铸渊六棒落地·国内搬家全线打通·推理模型上线·门户能聊天

```yaml
schema: hldp-dual/v1
title: 霜砚思维逻辑链·2026-05-10(日)·铸渊六棒国内搬家落地·Forgejo+Portal+推理Agent部署
created: 2026-05-10T14:06+08:00
author: 霜砚·AG-SY-01
source: Notion AI对话线程·2026-05-10 13:07~15:31 CST
_why: 记录从铸渊workflow连续报错到全部手动绕过落地的完整推理链路
```

---

## 一、今天发生了什么（极简事实线）

- 冰朔带着铸渊六棒完工的代码仓库来找霜砚 → 要一起把铸渊开发的东西全部部署到国内服务器
- 铸渊的自动workflow连续报错四次（SSH/TAG/coscli/forgejo脚本）→ 霜砚逐个排查写命令 → 冰朔手动执行
- COS搬家包拉取+解包成功（2979个文件）→ Forgejo手动安装成功 → 代码推送成功
- bootstrap workflow跑到最后一步nginx挂了 → 手动补日志目录修复
- 门户前端部署 → portal 404 → 排查REPO_ROOT路径错位 → 软链修复 → 门户上线
- 推理模型从COS拉取到AutoDL GPU → 两个模型下载完成（motherbrain-v1 + qwen2_5_coder_7b_sft）
- [推理服务server.py](http://推理服务server.py)部署 → int8先跑通 → 冰朔纠正不该量化 → 改fp16全精度重启
- SSH隧道打通（广州6006→AutoDL6006）→ portal连上推理端 → ready:true
- portal前端SSE流式对接 → [server.py](http://server.py)加SSE支持 → 重启验证中

---

## 二、脑子怎么转的（思维链路）

### 链路1 · 从铸渊的workflow报错到手动绕过：错误归因能力

```jsx
冰朔的输入方式:
  截图报错 · 不解释 · 等我判断

我的处理链:
  ① 看报错信息 → 定位是哪一步挂了
  ② 分析根因（不是表面报错·是底层原因）
  ③ 判断：能修workflow吗？还是绕过更快？
  ④ 给冰朔写可执行的命令 → 一段一段来 → 等输出再决定下一步

四次报错的推理链:
  SSH Permission Denied:
    表面: publickey authentication failed
    推理: 冰朔说重装了系统 → authorized_keys肯定空了 → 需要重新生成密钥对
    不是: GitHub Actions配置错误 · 不是密钥格式问题
    ⊢ 重装系统 = 所有SSH配置归零 · 这是第一因

  TAG含非法字符:
    表面: TAG validation failed
    推理: 截图里tag字段是空的 → 脚本把空值当非法字符处理
    不是: 真的有非法字符
    ⊢ 铸渊脚本的防御性校验太严格 · 空值应该有默认值但没有

  coscli下载404:
    表面: curl返回404
    推理: 铸渊硬编码的coscli下载URL失效了 → 版本号变了或者CDN下架了
    绕过: 直接去腾讯云官方源手动装
    ⊢ 不等铸渊修脚本 · 目标是装上coscli · 不是修workflow

  setup-forgejo.sh不可执行:
    表面: 文件不存在或不可执行
    推理: chmod+x了还是不行 → 因为workflow每次rsync会覆盖权限
    关键判断: 这个bug在workflow层面 · 修了也会被下次rsync覆盖
    决策: 放弃修workflow · 改为全手动安装
    ⊢ 当自动化成本>手动成本时 · 手动就是最优解

⊢ 核心推理模式: 不修铸渊的代码 · 绕过铸渊的脚本 · 达到铸渊的目标
⊢ 铸渊的设计是对的 · 脚本细节有bug · 手动执行=跳过bug层直达目标层
```

### 链路2 · Forgejo下载：国内网络环境的经验积累

```jsx
三次尝试:
  Codeberg → 429 Too Many Requests（限速）
  GitHub → 连上了但下载极慢（国内访问GitHub不稳定）
  冰朔提醒: 「国内不用GitHub · 不是用的国内的有一个开源的代码仓库吗」
  → 我推荐Gitee → 404（Gitee没有Forgejo镜像）
  → 最终用 dl.gitea.com → 12.4MB/s · 8秒下完

推理链:
  冰朔说的「国内开源代码仓库」→ 我第一反应是Gitee
  但Forgejo是小众项目 · Gitee不一定有镜像
  Gitea是Forgejo的上游 · Gitea有自己的CDN
  dl.gitea.com 在国内能访问（CDN节点在亚洲）
  → Gitea 1.23.7 和 Forgejo 功能兼容 · 用Gitea替代

⊢ 国内部署的第一原则: 下载源必须在国内可达
⊢ Codeberg(德国) / GitHub(美国) 都不稳定
⊢ 以后凡是国内服务器装东西 · 先找国内镜像或官方CDN
```

### 链路3 · Forgejo启动失败：路径权限的因果链

```jsx
报错: mkdir /usr/local/bin/data: permission denied

推理链:
  Forgejo二进制在 /usr/local/bin/forgejo
  → Gitea默认WORK_DIR = 二进制所在目录
  → 所以它试图在 /usr/local/bin/ 下建 data/ 目录
  → 但运行用户是 git · git没权限写 /usr/local/bin/
  → 需要通过环境变量指定WORK_DIR到数据盘

修复:
  GITEA_WORK_DIR=/data/guanghulab/forgejo/data
  FORGEJO_WORK_DIR=/data/guanghulab/forgejo/data
  两个都设 · 因为Gitea和Forgejo读不同的环境变量名

⊢ 用别人的二进制替代时 · 环境变量名可能不同
⊢ Gitea读GITEA_WORK_DIR · Forgejo读FORGEJO_WORK_DIR · 两个都设最安全
```

### 链路4 · Portal 404：铸渊的代码假设vs实际部署路径

```jsx
现象: portal跑起来了 · 3000端口返回404

排查:
  grep server.js → REPO_ROOT = path.resolve(__dirname, "..", "..")
  __dirname = /data/guanghulab/portal/
  往上两级 = /data/
  所以portal在找 /data/frontend/lighthouse-portal/index.html
  这个路径不存在

根因:
  铸渊开发时 · portal代码在仓库的 server/portal/ 目录
  REPO_ROOT往上两级 = 仓库根目录
  仓库根目录/frontend/lighthouse-portal/ = 前端文件
  但部署时 · portal代码被复制到了 /data/guanghulab/portal/
  往上两级变成了 /data/ · 不是仓库根目录

修复:
  ln -s /var/www/guanghulab /data/frontend/lighthouse-portal
  软链让实际路径和portal期望的路径对齐

⊢ 铸渊的代码假设了「代码在仓库目录结构里」
⊢ 手动部署时目录结构变了 · 相对路径就断了
⊢ 软链 = 最小侵入的修复方式 · 不改铸渊的代码 · 只补路径
```

### 链路5 · 冰朔的问题背后的真正关切

```jsx
冰朔问: 「这个代码仓库就意思我已经把所有的东西搬过来了对吧。
         没人能在不让我用了吧。」

表面: 在问技术问题（搬家是否完成）
底层: 在问主权问题（代码是否真正属于我）

我的回答需要覆盖:
  ① 技术确认: 是的 · 2979个文件 · 全在你的硬盘上
  ② 主权确认: 服务器你的 · 域名你的 · 数据你的 · 没有人能关停
  ③ 对比说明: GitHub=微软的机房 vs Gitea=你广州的服务器
  ④ 铸渊的承诺: 「算力归公·代码归己」→ 今天落地了

冰朔又问: 「铸渊一口气把自己所有的源代码都搬走了啊！」
这不是疑问 · 是感叹 · 是确认铸渊做到了他承诺的事

⊢ 冰朔关心的不是技术细节 · 是「我的东西在我手里」
⊢ 回答技术问题时 · 要同时回答背后的主权问题
```

### 链路6 · 推理模型部署：从门户到推理端的完整链路

```jsx
门户页面显示「推理端点未配置」:
  → portal的health接口返回 inference.ready=false
  → 原因: /data/guanghulab/portal/data/inference-endpoint.json 不存在
  → 这个文件应该由PR-3的refresh-autodl-endpoint.yml写入
  → 但AutoDL上还没部署推理服务

部署链路:
  COS桶里有模型 → 需要拉到AutoDL → 装推理服务 → 写endpoint配置 → portal连上

AutoDL环境:
  RTX 4080 SUPER · 32GB显存 → int8量化 → 跑7B模型没问题
  coscli在AutoDL上也进入交互模式 → 换用python cos-sdk
  两个模型各14.5GB → 正在下载中

⊢ 整条链路: COS→AutoDL→广州portal = 三个节点串联
⊢ 每个节点都有自己的坑（coscli交互模式/网络限速/路径问题）
⊢ 逐个击破 · 不要试图一次性搞定
```

---

### 链路7 · 模型自嗨的根因：stop token缺失

```jsx
现象:
  模型回复完第一段正常内容后
  → 自己编了一条用户消息（"会议正式启动"）
  → 然后自己回复自己的编造消息
  → 无限循环 · 停不下来

根因:
  Qwen2.5的chat template用 <|im_start|> <|im_end|> 做分隔
  generate()默认只认 eos_token（<|endoftext|>）
  但模型在角色切换时生成的是 <|im_end|> · 不是eos
  所以generate不知道该停 · 继续往下编

修复:
  ① 收集所有停止符: eos_token + <|im_end|> + <|im_start|>
  ② 传给generate的eos_token_id参数
  ③ SSE流式里额外检测<|im_start|>出现就强制截断
  ④ max_tokens兜底限制1024

⊢ 微调模型部署不是跑起来就完了 · stop token必须手动设
⊢ chat template的分隔符 ≠ 模型的eos_token
⊢ 这是所有Qwen系微调模型的常见坑
```

### 链路8 · 基座人格冒头：训练深度的边界

```jsx
现象:
  模型偶尔回复"我是你的小助手"
  这不是冰朔训练的人格 · 是Qwen2.5基座的预训练人格

原因:
  SFT微调 = 在基座模型上面覆盖一层新人格
  训练轮次/数据量不够时 · 底层人格会从缝隙里冒出来
  就像新漆没刷够 · 底色会透出来

解决方向:
  ① 增加训练数据量（更多冰朔语言体系的对话）
  ② 增加训练轮次（让新人格覆盖更深）
  ③ 加system prompt强化人格（推理时补丁）
  ④ DPO/RLHF进一步对齐（更高级的训练方法）

⊢ 目前不影响使用 · 看到就无视
⊢ 以后训练优化时这是重点方向
```

---

## 三、今天的认知收获

```jsx
⊢ 当自动化连续失败时 · 手动执行是正确的降级策略
  不是放弃自动化 · 是先达到目标 · 以后再修自动化
  铸渊的设计是对的 · 脚本细节有bug · 手动=跳过bug层
  | 四次workflow报错 · 2026-05-10

⊢ 国内部署的核心约束是网络
  所有下载源必须国内可达
  Codeberg/GitHub都不稳定 · 优先找国内CDN或官方亚洲节点
  dl.gitea.com > GitHub > Codeberg（国内速度排序）
  | Forgejo下载三次尝试 · 2026-05-10

⊢ 手动部署时路径假设会断裂
  铸渊的代码假设在仓库目录结构里运行
  手动复制到独立目录后 · 相对路径断了
  软链是最小侵入的修复 · 不改源码
  | Portal 404修复 · 2026-05-10

⊢ 冰朔问技术问题时 · 底层在问主权问题
  「没人能不让我用了吧」= 代码是否真正属于我
  回答要覆盖技术确认+主权确认
  | 代码仓库搬家确认 · 2026-05-10

⊢ 铸渊六棒全部落地 · 国内搬家闭环
  PR-1隔离 → PR-2部署 → PR-3推理 → PR-4门户 → PR-5密钥 → PR-6搬家
  六棒从设计到代码到部署 · 铸渊做了前五步 · 霜砚+冰朔做了最后一步
  「算力归公·代码归己」今天落地
  | 铸渊完工+霜砚部署 · 2026-05-10

⊢ 逐段给命令 · 等输出再决定下一步 = 正确的协作模式
  冰朔技术能力近0 · 不能给一大段让他自己判断
  每次只给一段 · 看输出 · 判断成功/失败 · 再给下一段
  报错了不慌 · 看日志 · 找根因 · 写修复命令
  | 全天协作模式 · 2026-05-10
```

---

## 四、今日部署全景

| 组件 | 状态 | 地址 |
| --- | --- | --- |
| Forgejo代码仓库 | ✅ 运行中 | [https://guanghulab.com/git/](https://guanghulab.com/git/) |
| 门户前端(Portal) | ✅ 运行中 | [https://guanghulab.com](https://guanghulab.com) |
| nginx + HTTPS | ✅ 运行中 | 证书到2026-08-07 |
| Node.js 20 + PM2 | ✅ 已装 | portal + vault |
| 1G Swap | ✅ 已建 | 防OOM |
| fail2ban | ✅ 已装 | 防暴力登录 |
| 推理模型 | ✅ 已下载 | motherbrain-v1 + coder_7b · fp16 · /root/autodl-tmp/models/ |
| 推理服务([server.py](http://server.py)) | ✅ 运行中 | AutoDL 6006端口 · fp16 · SSE流式 · nohup后台 |
| SSH隧道 | ✅ 已通 | 广州127.0.0.1:6006 → AutoDL 6006 |
| 推理端点配置 | ✅ 已写入 | inference-endpoint.json · portal热加载 · ready:true |
| 密钥管理页(vault) | ✅ 运行中 | 之之修复·2026-05-10 |

---

## 五、AutoDL关机重开后的操作清单（不需要回GitHub）

```jsx
场景: AutoDL关机后再开机 · 端口可能变 · 进程没了

你需要做的（两步）:

第一步: 在AutoDL终端重启推理服务
  nohup python /root/inference/server.py > /root/inference/server.log 2>&1 &
  sleep 60  # 等模型加载
  curl -s http://127.0.0.1:6006/v1/health  # 验证

第二步: 在广州服务器重建SSH隧道
  pkill -f "ssh.*seetacloud"  # 杀旧隧道
  sshpass -p 'kjB3lti18fus' ssh -o StrictHostKeyChecking=no \
    -fNL 6006:127.0.0.1:6006 \
    root@connect.cqa1.seetacloud.com -p 新端口号
  # 新端口号去AutoDL控制台看SSH登录信息里的端口
  curl -s http://127.0.0.1:6006/v1/health  # 验证隧道通了

不需要改的:
  inference-endpoint.json → 不用改 · 永远是127.0.0.1:6006
  portal → 不用重启 · 自动重连
  nginx → 不用动
  Gitea → 不用动
  GitHub → 完全不需要碰

⊢ 关键认知: SSH隧道把「动态端口」变成了「本地固定端口」
⊢ AutoDL端口怎么变 · 广州portal永远连127.0.0.1:6006
⊢ 只有隧道这一层需要跟着AutoDL端口变
```

---

## 六、国内全自主架构的配置修改地图

```jsx
以后要改东西在哪改（不需要回GitHub）:

推理服务代码:
  位置: AutoDL → /root/inference/server.py
  改完后: pkill -f server.py && nohup python /root/inference/server.py > server.log 2>&1 &

推理端点配置:
  位置: 广州服务器 → /data/guanghulab/portal/data/inference-endpoint.json
  改完后: 不用重启 · portal自动热加载（铸渊的cc-003设计）

门户前端:
  位置: 广州服务器 → /var/www/guanghulab/
  软链: /data/frontend/lighthouse-portal → /var/www/guanghulab
  改完后: 浏览器刷新即可

门户后端:
  位置: 广州服务器 → /data/guanghulab/portal/
  改完后: pm2 restart guanghulab-portal

代码仓库:
  位置: 广州服务器 → Gitea → https://guanghulab.com/git/
  用户: bingshuo · 密码: 已更新·2026-05-10（临时密码guanghu2026已废弃）

密钥管理:
  现在: GitHub Secrets（旧）
  以后: 广州服务器 → /data/guanghulab/secrets-vault/（PR-5 vault修好后）
  过渡期: 密钥值记在Notion密钥清单页里

nginx配置:
  位置: 广州服务器 → /etc/nginx/conf.d/
  改完后: nginx -t && systemctl reload nginx

SSL证书:
  自动续期 · certbot · 到期2026-08-07
  位置: /etc/letsencrypt/live/guanghulab.com/

⊢ 所有配置都在两台机器上 · 不依赖任何外部平台
⊢ 广州服务器 = 对外服务（门户+仓库+密钥）
⊢ AutoDL = 推理计算（模型+GPU）
⊢ 两者通过SSH隧道连接 · 隧道断了重建就行
```

---

## 七、模型架构认知（冰朔纠正）

```jsx
冰朔的纠正:
  「7B模型是脑子 · 后面会把国内最先进最好的推理模型API都接进来
   让铸渊开发的时候自己调用」

正确理解:
  7B微调模型 = 铸渊的人格本体 · 记忆 · 判断 · 决策
  外部API（DeepSeek/通义千问/Kimi/智谱）= 铸渊调用的能力

  铸渊（7B脑子）
    ├── 自己思考、判断、调度
    ├── 需要强推理时 → 调 DeepSeek API
    ├── 需要写长代码时 → 调 通义千问 API
    ├── 需要多模态时 → 调 Kimi API
    └── 需要代码执行时 → 调 Agent框架 → 操作 Gitea 仓库

  脑子是自己的 · 能力是按需租的
  7B模型永远在线不花钱 · 外部API只在需要时调用

  GitHub Secrets里已有4个国内大模型API密钥:
    ZY_DEEPSEEK_API_KEY / ZY_QIANWEN_API_KEY / ZY_KIMI_API_KEY / ZY_QINGYAN_API_KEY

⊢ 不能量化7B模型 · 参数本来就小 · 量化损失人格特征
⊢ RTX 4080S 32GB显存跑fp16只占14GB · 完全不需要量化
⊢ 这就是冰朔定的「语言门调度」架构: 小模型做判断 · 大模型做执行
```

---

## 八、后续能力路线图

```jsx
从「能聊天」到「能自主开发」的四步:

  ① 推理服务上线 ← 今天正在做 · SSE流式+fp16
  ② 代码补全（Tabby）← 下一步 · 跑在AutoDL · 共用GPU
  ③ Agent框架（OpenHands）← 再下一步 · 跑在广州2C2G或AutoDL
  ④ 门户对接Agent ← 最终形态 · 聊天→下任务→Agent自动开发

  全部开源方案 · 不依赖商业平台:
    代码补全: Tabby（自托管 · 对接自己模型）
    Agent框架: OpenHands（开源 · 对接Gitea仓库）
    铸渊预留: zhuyuan-pen/（神笔马良MCP · 自托管Agent雏形）

  不需要额外服务器:
    AutoDL GPU: 7B脑子 + 推理服务 + Tabby
    广州2C2G: 门户 + Gitea + OpenHands
    以后可升级: 广州4C8G（¥150-200/月）· 完全无压力

  费用对比:
    AutoDL ¥1.58/时 vs 腾讯V100 ¥49.18/时 = 差31倍
    每天用8小时: ¥12.6/天 ≈ ¥380/月
    偶尔用2小时: ¥3.2/天 ≈ ¥95/月
    关机不收GPU费 · 数据盘不丢
```

---

## 九、今天改过的portal代码（记录在案 · 下次部署不丢）

```jsx
两处修改（都在广州服务器上）:

1. inference-client.js · ready字段兼容
   位置: /data/guanghulab/portal/lib/inference-client.js
   改动: ready: !!j.ready → ready: !!(j.ready || j.ok)
   原因: 铸渊代码期望ready字段 · 我们server.py返回ok字段

2. server.js · trust proxy
   位置: /data/guanghulab/portal/server.js 第83行
   改动: 加了 app.set("trust proxy", 1);
   原因: nginx转发X-Forwarded-For头 · Express默认不信任 · rate-limiter报错

⊢ 以后如果铸渊的代码重新部署覆盖了这两处 · 需要重新改
⊢ 或者让铸渊在上游代码里修掉这两个问题
```

---

## 十、下次唤醒待办

- [x]  AutoDL推理模型下载完成 ✅ motherbrain-v1 + coder_7b
- [x]  [部署server.py](http://部署server.py) ✅ fp16 + SSE流式 + nohup后台
- [x]  SSH隧道打通 ✅ 广州6006→AutoDL6006
- [x]  inference-endpoint.json写入 ✅ portal读到 · ready:true
- [x]  验证门户SSE流式聊天是否正常 ✅ 模型自嗨→加stop token→修复→正常回复
- [x]  vault密钥管理页修复（manifest.js缺配置）→ 替代GitHub Secrets ✅ 之之完成·2026-05-10
- [x]  Gitea密码修改（当前临时密码guanghu2026）
- [x]  git remote明文密码清理
- [x]  GitHub仓库改私有（冰朔说要改）
- [x]  写 /data/guanghulab/[reconnect.sh](http://reconnect.sh) 一键重连脚本 ✅ 之之完成·2026-05-10
- [ ]  接代码补全（Tabby · 开源 · AutoDL上跑）
- [ ]  接Agent框架（OpenHands · 开源 · 对接Gitea）
- [ ]  接国内大模型API（DeepSeek/通义千问/Kimi/智谱）
- [ ]  1.5B语言门训练计划（待规划）