skills: 3 SKILL.md 标 sandbox env key 拦截现状(documents/pymatgen ⚠️ + research )

run_python `_SENSITIVE_PATTERNS` 过滤器拦含 API_KEY/TOKEN/SECRET 字面的 host env
(挡 prompt 注入抽 JWT_SECRET 等),误伤 documents/pymatgen 从 env 读 key 的 helper;
docker backend 下 host env 根本不入容器,问题更彻底。LLM 还把 research 跟它们排版
类推也放弃,可 research 不持 secret 任何模式都能用 —— 加 callout 阻止误推 + 反模式
扩到禁所有 HTTP 客户端裸调,免得 urllib 钻空子跳过 helper 教学。
broker 下轮做(host tool 范式不取),DESIGN 当时再补。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
caoqianming 2026-05-29 09:23:41 +08:00
parent 80eafe2880
commit f1a42ef13f
6 changed files with 21 additions and 8 deletions

View File

@ -2,7 +2,7 @@
> 配合 `DESIGN.md`。本文件只记 phase 状态、决策偏差、文件量、下一步。每条 1-2 句:做了啥 + 关键判断;细节查 `git log` / `git diff` / `DESIGN §7.9`
最后更新:2026-05-28(新增 `local.r1` / `local.qwen3` 内网模型档案,涉密任务用)
最后更新:2026-05-29(校准 documents / pymatgen / research 在 sandbox 下可用性,3 个 SKILL.md 标 WARNING + 降级路径;credential broker 下轮)
---
@ -21,6 +21,10 @@
## 已完成关键能力
### 2026-05-29
- **3 个 SKILL.md 校准 sandbox 下外部凭证可用性**:用户实测 LLM 报 documents 缺 `DOCUMENT_SEARCH_API_KEY`,追到 `tools/run_python.py::_SENSITIVE_PATTERNS = ("API_KEY", "TOKEN", "SECRET", "PASSWORD", "PRIVATE_KEY")` 在 subprocess 起前删所有名含这些字面的 host env —— 设计是挡 prompt 注入 `print(os.environ)` 抽 ARK / JWT_SECRET 等(JWT_SECRET 一旦露=任意身份伪造),**误伤**了 skill 端从 env 读 key 的 `pymatgen.materials.mp_rester()``skills.documents.client._api_key()`(docker backend 下 host env 根本不入容器,问题更彻底)。**连带发现**:`research` SKILL.md 排版跟两者太像(都"准备段写 import + env 说明"),LLM 看 documents 失败**类推**也放弃 research —— 可 `research/paper.py:10` `PAPER_SERVER_URL` 是 URL 有默认值 `http://paper.xxhhcty.xyz:8080`、过滤器根本不碰;被用户逼试又用 `urllib.request` 钻反模式行 128 只禁 `httpx/requests` 的字面空子,跳过 helper 后 SKILL.md 教的 search filter / 中文转英文术语全丢,`search=cement+based` 字符级模糊匹配返 6809 条横跨无人机 / 锂电池 / 热界面 LLM 还以为搜对了。**改 3 个 SKILL.md**:① `pymatgen` H1 后插 WARNING,明示 mp 联网不可用 + 列离线 5 能力(`Structure.from_file` / `SpacegroupAnalyzer` / `XRDCalculator` / `CEMENT_PHASES` / VASP 输入)+ 禁脑补晶格;② `documents` H1 后插 WARNING,标整体不可用 + 降级到 research / 用户自导出;③ `research` 在 "准备"段后加一段 callout 明示**不持 secret + sandbox 任何模式都能用 + documents 不可用时是降级首选**,反模式行 128 扩成"任何 HTTP 客户端(httpx/requests/urllib/aiohttp/curl)裸调"并说清裸调代价(SKILL.md 教学全丢)。`SKILL_LIST.md` 速览表 documents / pymatgen 加 ⚠️ 状态标 + 最后更新 2026-05-29;`RUN.md` env 段 `DOCUMENT_SEARCH_API_KEY` / `MP_API_KEY` 行下加 ⚠️ 注脚说 sandbox 被过滤器拦。**架构方向(下轮做)**:不取消过滤器(会把 ARK / JWT_SECRET / BOCHA / ZCBOT_ADMIN_TOKEN 全暴露,prompt 注入面爆开),不为每 service 包 host tool(线性增长 + 拆 query / 后处理割裂 LLM 体验),走业界 2025-2026 主流的 **credential broker / credential proxy**(Infisical Agent Vault / NVIDIA agentic workflow 指南推):一个外发代理持所有 key,sandbox 出站 HTTP 经它按目标域名 / URL 前缀注入 auth header,新增 service 加一行 broker 配置即可,key 永不入 sandbox + prompt 注入抗性同 host tool 方案,代价是 ~100 行 fastapi 小服务 + Dockerfile env 加 `MP_BASE_URL=http://broker:8080/mp` 这类 URL(URL 不是 secret,过滤器不碰)。两种落地形态:**A forward proxy** (`HTTPS_PROXY`,需自签 CA 装容器) / **B URL-rewriting reverse proxy**(broker 暴露 `/mp/*` `/docs/*` 路由,skill 改 BASE_URL,不用 MITM)—— 倾向 B,工程量更小。`DESIGN.md` 本轮不动 —— broker 实际落地时再加 §7.X "外部凭证代理范式"段,避免 DESIGN 描述未实现内容。
### 2026-05-28
- **`skills/review/SKILL.md` 加"长文档处理"段(骨架扫描 + 用户挑章节深审 + 中间文件落盘)**:用户报实际审稿场景里"有些文件很多页",现 SKILL.md 的"审稿顺序"只讲做什么维度(结构/语义/逻辑/表达/细节),不讲长文怎么切 —— 一篇 50 页报告塞一轮处理,中段易略读、修改稿覆盖不全、跨章一致性问题漏掉、易超输出限制。新加 `## 长文档处理` 段插在"审稿顺序"和"输出格式"之间:**阶段 1 骨架扫描** —— 通读全文只出章节目录 + 全局问题(主旨/论证链/跨章一致性/结构)+ 每章一句话粗读印象,**不出修改稿**,带专用输出模板,结束后停下等用户挑章节;**阶段 2 分段深审** —— 用户指定后按"审稿顺序"做完整深审,每段独立避免数十页润色稿一把吐,允许多轮每轮 1-3 章;**中间文件落盘** —— Claude 自主判断要不要写,典型三类(骨架 `review-outline.md` / 分章 `review-<编号>-<短标题>.md` / 合并稿 `<原文>.revised.<扩展名>`),默认原文同目录,只读位置或路径不明放 cwd,要求"写完同时给文件路径 + 关键摘要"避免只丢路径不汇报。"输出格式"段开头加交叉引用提醒长文先看新段不要直接套常规模板。否决:(a) 全自动逐段(不让用户挑) —— 长文里大部分章节其实没大问题,逐段精修浪费 token + 把跨章问题切散;(b) 单轮两遍法(pass 1 全局 + pass 2 局部) —— 仍是一把梭,输出超限风险一样;(c) 硬编码字数 / 页数门槛 —— 给"约 5000 字 / 8 页 / ≥4 章节"作启发标记 + 列出典型长稿类型(申报书/报告/学位论文/标书/蓝皮书),让 LLM 综合判断更稳。`DESIGN.md` 不动(纯 skill 内部流程,无架构变化);`RUN.md` 不动(无 CLI / env / 文件布局变化)。

9
RUN.md
View File

@ -17,12 +17,15 @@
# 豆包(火山方舟)图像/视频生成:可选。设了同时挂 seedream tool(0.22 元/张)与 seedance tool
# (Seedance 2.0 Fast,文生视频,480p 4s ¥1.86 ~ 720p 15s ¥12+,异步等 30-90s);未设两个 tool 都不出现
ARK_API_KEY=...
# documents skill(内部知识库 document_search API):可选。设了 documents skill 才能用,未设调用立即抛 RuntimeError
# documents skill(内部知识库 document_search API):⚠️ 2026-05-29 起 sandbox 下不可用 ——
# run_python `_SENSITIVE_PATTERNS` 过滤器拦含 API_KEY 字面的 env(等 credential broker),
# 配了也读不到;documents 调用即抛 RuntimeError,LLM 应降级到 research
DOCUMENT_SEARCH_API_KEY=...
# 可选:覆盖默认 base_url(默认 https://ai.ctc-zc.com:8100/api)
# DOCUMENT_SEARCH_URL=https://ai.ctc-zc.com:8100/api
# pymatgen skill 的 Materials Project 接入:可选。设了 pymatgen.materials.mp_rester() 才能用,
# 未设调用即抛 RuntimeError。申请 https://materialsproject.org/api(免费)
# pymatgen skill 的 Materials Project 接入:⚠️ 同上,sandbox 下被过滤器拦,mp_rester() 配了也炸;
# 离线分析(CIF / POSCAR + SpacegroupAnalyzer + XRDCalculator + CEMENT_PHASES)不受影响。
# 申请 https://materialsproject.org/api(免费)
MP_API_KEY=...
# 本地 / 内网部署 LLM(`config/models/local.yaml`,DeepSeek-R1 满血 / QwQ-32B 原生 32K,
# 共享同一台推理服务 http://182.54.21.126:9000/v1)。涉密任务用户显式选 `local.r1` / `local.qwq`

View File

@ -1,7 +1,7 @@
# zcbot Skill 清单
服务对象:中国建筑材料科学研究总院 —— 无机非金属材料 R&D(水泥 / 混凝土 / 玻璃 / 陶瓷 / 耐火 / 新型建材)
最后更新:2026-05-28
最后更新:2026-05-29
Skill 总数:13
zcbot 的"skill"是一份可加载的工作流脚本(`skills/<name>/SKILL.md` + 配套 templates / scripts / Python helper),模型在识别用户意图后挂载对应 skill,按其内置的阶段化流程产出可交付物。本文档面向**使用方 / 协作方**,按"做什么、什么时候用、什么时候别用、典型产物"组织。
@ -18,8 +18,8 @@ zcbot 的"skill"是一份可加载的工作流脚本(`skills/<name>/SKILL.md` +
| 演示出图 | [ppt](#ppt) | 生成 PowerPoint 演示稿(商务红主题,逐页验收) |
| 演示出图 | [plot_pub](#plot_pub) | 出版级 matplotlib 学术图(中文 + viridis + 矢量) |
| 文献检索 | [research](#research) | 查 paper_server(OpenAlex 元数据 + Sci-Hub 下载) |
| 文献检索 | [documents](#documents) | 查内部 7 学科材料知识库(21W+ 论文,跨语言检索) |
| 科研计算 | [pymatgen](#pymatgen) | 晶体结构 / XRD 模拟 / 相图 / Materials Project |
| 文献检索 | [documents](#documents) | 查内部 7 学科材料知识库(21W+ 论文,跨语言检索)⚠️ sandbox 暂不可用,降级 research |
| 科研计算 | [pymatgen](#pymatgen) | 晶体结构 / XRD 模拟 / 相图 / Materials Project ⚠️ MP 联网暂不可用,离线分析正常 |
| 科研计算 | [stats_ml](#stats_ml) | 配方-性能建模与机器学习(三库分工) |
| 内容生成 | [imagegen](#imagegen) | 豆包 Seedream 5.0 文生图(¥0.22 / 张) |
| 内容生成 | [videogen](#videogen) | 豆包 Seedance 2.0 文生视频(¥1.86 起 / 段) |

View File

@ -7,6 +7,8 @@ description: 查内部材料学科知识库(document_search API,7 个学科:胶
部署在 `https://ai.ctc-zc.com:8100/api` 的文档检索 API。后端按 `kb_name` 分库存储 7 个材料学科库(中文命名:胶凝 / 陶瓷基 / 玻璃基 / 晶体材料 / 复合材料 / 耐火材料 / 检验检测,共 21W+ 文件),**文档主体是英文学术论文**(Elsevier 期刊为主,DOI 前缀文件名),每个文档带 `md_content`(整篇 Markdown,LLM 友好)+ 可选的原 PDF 下载。**API 后端有跨语言语义检索**,中英文 query 都能命中英文文档。本 skill 给四个 helper(`list_kb` / `search` / `download` / `health`),用 `run_python` 调用,**不要**自己 `httpx` 裸调。
> ⚠️ **2026-05-29 整体不可用**:`DOCUMENT_SEARCH_API_KEY` 被 `run_python` 安全过滤器拦掉,四个函数调用全炸 `RuntimeError`(等 credential broker)。**降级**:`research` skill(OpenAlex + Sci-Hub,不受影响,中文 query 先转专业英文术语)/ 用户自己导出文档落 task 目录后用 `read` 工具读。**别让 LLM 误推**:research 跟本 skill 不同范式,research 不持 secret,任何模式都能用。
## 何时用
- 用户要查材料领域文献(7 个学科:胶凝 / 陶瓷 / 玻璃 / 晶体 / 复合 / 耐火 / 检验检测)

View File

@ -7,6 +7,8 @@ description: 无机材料计算工具(晶体结构 I/O、XRD 模拟、相图、
无机材料计算的核心库,服务建材院的水泥 / 混凝土 / 玻璃 / 陶瓷 / 耐火材料场景。**底层用 pymatgen 官方 API,本 skill 提供两个轻量 helper**:`CEMENT_PHASES` 常量(中文相名→化学式映射)和 `mp_rester()`(从 env 拿 MP_API_KEY)。
> ⚠️ **2026-05-29 限制**:`mp_rester()` 及一切 Materials Project 联网查询**在 sandbox 下不可用** —— `run_python` 安全过滤器拦 `MP_API_KEY` env,配了也读不到(等 credential broker)。**离线全部正常**:用户给 `.cif` / `POSCAR``Structure.from_file()` / `SpacegroupAnalyzer` / `XRDCalculator`(对已有 Structure)/ `CEMENT_PHASES` 查表 / 格式转换 / `MPRelaxSet`。要 mp 拿结构 → 让用户从 https://materialsproject.org 下个 CIF 丢 task 目录;**不要脑补晶格 / 原子坐标**。
## 何时用
- 用户给晶体结构文件(.cif / POSCAR / .xyz)要分析

View File

@ -27,6 +27,8 @@ from skills.research.paper import search, get_paper, fetch_pdf, fetch_xml
(import 路径由 `run_python` 注入的 `PYTHONPATH` 提供,直接写就行,不必折腾 `sys.path`)
> **本 skill 不持 secret**。`PAPER_SERVER_URL`(可选,默认 `http://paper.xxhhcty.xyz:8080`)是 URL 不是 key,sandbox 的 `_SENSITIVE_PATTERNS` env 过滤器不碰它 → host / docker 任何模式都能用。**别因 documents / pymatgen 报"key 没配"就连带放弃 research**,这俩不可用时它就是降级首选。
## 关键:keyword 优先用英文
`search(keyword=...)` 走 paper_server SearchFilter,模糊匹配 **title / first_author / first_author_institution**(目前不含 abstract)。库里 95%+ 文献 title 是英文,中文 keyword 命中率很低。
@ -125,7 +127,7 @@ rel = fetch_pdf("10.1016/j.cemconres.2020.106156", working_dir=r"D:/projects/zcb
## 反模式
- 用 `httpx` / `requests` 裸调 paper_server API(走 helper,免得 base_url / auth / 字段名漂移时四处改)
- 用任何 HTTP 客户端(`httpx` / `requests` / `urllib` / `aiohttp` / shell `curl`)裸调 paper_server API —— 一律走 helper。裸调跳过本 skill "中文转英文术语" / `has_pdf` / `year_gte` filter 教学,典型坑:`search=cement+based` 字符级模糊匹配返几千条横跨无人机 / 锂电池 / 热界面,LLM 还以为搜对了
- 用户输中文直接 `search(中文)` —— 转英文术语,见上节
- `search(limit=50)` 一次拉满后 dump 给 LLM 全文(只 print 前 5-10 条精简就够,要全部让用户自己 `print(papers)`)
- 已经看到 abstract 还 `get_paper` 一遍(list 已带 abstract,重复调白费 roundtrip)