Compare commits

...

11 Commits

Author SHA1 Message Date
caoqianming 263cdb974a proposal: 阶段二每段卡点附"下一段要点预告"
让用户在下一段动笔前就能改方向, 比读完正文再返工便宜一个量级。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 16:11:18 +08:00
caoqianming b86c051290 cli+core: 加 task 对话导出为 .docx
- core/export_docx.py: 渲染 messages.json 为对话稿,左排小字 + 角色配色
  (user/assistant/tool/tool_call/reasoning),meta 信息表置文档开头,tool
  结果默认前 1000 + 中间省略 + 后 500
- cli.py: 加 `export <task_id>` 子命令(支持 last / -o / --include-system /
  --no-reasoning / --tool-head / --tool-tail)与 REPL `/export [<id>]`
- 默认跳过 system prompt(信息密度低),默认带 reasoning_content(观察价值高)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 14:42:45 +08:00
caoqianming ae93016442 cli: REPL /resume 切 task + 懒创建 task_dir + 切走前空清理
- 加 /resume [last|<id>] REPL 命令,无参数列最近 10 个表格让用户挑;
  和 /new 对称,都在 REPL 内重建五元组。tasks 命令复用 _list_task_rows
- main.py 新建分支不再 session.save() / task_state.save() 占位 ——
  推迟到首条 user 消息触发的 Session.append → save() 才物化 task_dir。
  启动 REPL 立刻 /exit 磁盘无痕,跨进程也安全
- _cleanup_if_empty 在 /exit /quit /new /resume + Ctrl-C/EOF 守门:
  无 user 消息 + 目录在磁盘上 + 文件集 ⊆ {messages.json} 才删,
  state.json 存在(/done /abandon /desc 留下的显式痕迹)就保

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 09:55:56 +08:00
caoqianming 56e414e046 proposal: 阶段二两段式 + render_docx 透传 fenced 代码块
- SKILL.md 阶段二改两段式: 先列 3-6 条要点 → 用户确认 → 再起草 → 用户确认。关键章节 (立项依据/研究方案/技术路线/考核指标) 一段一卡。一次性出全文容易把错方向推到底,要点阶段拦得早
- render_docx.py 支持 ```...``` 围栏: 中文新宋体 + 西文 Consolas + 行距 1.0 + 不缩进 + xml:space=preserve。原先 ASCII 流程图被当散文段落合并,框完全错位
- PROGRESS.md backlog 加 mermaid 预渲染 (mmdc → PNG → add_picture),等 ASCII 透传不够用再做

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:58:18 +08:00
caoqianming f4432cca20 添加col.ps1到gitignore 2026-05-08 08:03:49 +08:00
caoqianming a32cb049bc ppt+proposal: 素材摄取改用 markitdown, 删自研 source_to_md
ppt/proposal 的"素材 → Markdown"逻辑此前各写一份 (source_to_md.py
内联 pypdf/python-docx/openpyxl), 改用微软 markitdown CLI 统一替换:
表格/标题/列表保留更好, 同时多覆盖 xlsx/url/html/csv 等格式。

- requirements.txt: 加 markitdown[pdf,docx,pptx,xlsx]
- skills/ppt/SKILL.md: 资源行改成 markitdown 说明
- skills/proposal/SKILL.md: 阶段零 32 行 Python 代码 → 4 行 CLI
- skills/ppt/scripts/source_to_md.py: 删除 (157 行)
- PROGRESS.md: scripts 列表同步

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 08:03:07 +08:00
caoqianming 72d2b64c40 core/ui: 抽出语义化 console 主题, 调用方去硬编码颜色
新增 core/ui.py 集中定义 Rich Theme:
- 语义样式名: user / assistant / tool / ok / warn / err / info / muted / accent
- 在黑底终端上 readable, 弱化用 grey 而非 dim, 强调走 bright_*
- make_console() 统一应用主题, 以后改主题只动这一处

cli.py / main.py / core/loop.py 把内联的 [red] [green] [blue] [yellow]
[cyan] [dim] 等替换为语义样式; 调用 make_console() 取代 Console()。
2026-05-07 16:10:11 +08:00
caoqianming 647d92f532 proposal+ppt: 路径用 <skill_dir>, 补 spec_lock 模板与 --spec 覆盖度检查
按代码评审建议改的 5 项:

1. 所有脚本/资源路径改成相对 <skill_dir> (load_skill 头里的绝对路径),
   不再假设 cwd 是 zcbot 仓库根。proposal+ppt 的 SKILL.md / icons.md /
   INDEX.md 都改了。

2. quality_check.py REQUIRED_SECTIONS 给 key_rd 补上 11_team /
   12_budget / 13_appendix —— 之前模板有但检查没到, 缺团队/预算/附件
   也会显示结构完整。

3. 新增 templates/spec_lock.md, 把"八条对齐"固化成可复制字段
   (含考核指标矩阵表 + TODO 列表 + 引文清单), 阶段二/三都从这里读。

4. quality_check.py 加 --spec <spec_lock.md> 选项, 解析 spec 中的
   考核指标矩阵, 关键词模糊匹配 sections, 提示哪些指南指标在正文
   未充分覆盖。SKILL.md 阶段三命令同步。

5. SKILL.md 新增"阶段零: 摄取素材", 用 run_python + pypdf/python-docx/
   openpyxl 把 PDF/DOCX/XLSX 转成 source/*.md, 不再要新脚本。同时
   把 spec_lock 字段引用改写到模板。

顺带:
- proposal SKILL.md 明确 7 类基金里只有 3 类 (key_rd/major_project/
  nsfc_joint_fund) 有完整章节模板, 其它 4 类复用骨架, 差异查 fund_types.md
- ppt SKILL.md 阶段三命令路径错误 (python scripts/quality_check.py)
  顺带修了
2026-05-07 16:05:44 +08:00
caoqianming d1f39f05f5 proposal skill 精简: 2888 -> 1712 行 (-41%)
- 删 references/typography.md (90% 已被 render_docx.py 吸收, 剩下进 SKILL 硬规则)
- 删 references/section_templates.md (与 templates/ 大量重叠, 4 个核心 pattern 折进 SKILL "章节骨架速查")
- fund_types.md / review_redlines.md / citation_gbt7714.md / budget_rules.md
  全部去散文留骨架: 表格 / 清单 / 示例 优先, 解释性段落只留必要的
- templates/{key_rd,major_project,nsfc_joint_fund}.md 删冗长写作提示, 只留章节骨架 + 字数预算 + 必填字段
- 脚本逻辑不动, render_docx.py 仅去 docstring 中的 typography.md 引用
2026-05-07 15:32:07 +08:00
caoqianming 3869089a44 DESIGN/PROGRESS: 同步 TUI 打磨 + task_dir 落地
DESIGN: 目录树补全 task_dir 内的 skill 产物;启动顺序 #5 加 task_dir 注入;
3.1 主循环增补 markdown 渲染、spinner 实时耗时/token、每轮成本行。
PROGRESS: 加 2026-05-07 条目;工具基目录决策更新;loop/main 行数刷新。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 14:20:59 +08:00
caoqianming bb9e92bb84 让 <task_dir> 真正落地: 产物收敛到 workspace/tasks/<id>/
之前 SKILL.md 反复说 <task_dir>/spec_lock.md / <task_dir>/sections/,但代码里没把
task_dir 暴露给 agent,只给了 cwd——导致 spec_lock.md 落到 skills/proposal/、
sections/ 落到 repo 根。两者被 .gitignore 通配规则盖住,问题被掩盖。

- main.py system prompt 里显式注入 task_dir 绝对路径 + 强约束(只写 task_dir,不写
  cwd / skills/ / repo 根)。SKILL 里的 <task_dir> 占位符明确指向这个值。
- skills/proposal/SKILL.md + skills/ppt/SKILL.md 的「工作目录约定」前面加一句解释
  <task_dir> 来自 system prompt。
- .gitignore 删掉 sections/ slides/ spec_lock.md 这三条无锚 bandaid——workspace/
  已经覆盖正确路径下的产物;repo 根再写错了要靠 git status 立刻报红,不再靠 ignore
  兜底。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 14:18:35 +08:00
26 changed files with 1533 additions and 2011 deletions

8
.gitignore vendored
View File

@ -21,9 +21,10 @@ venv/
env/
# 用户运行产物 / 临时文件
# task 内产物(sections/ slides/ spec_lock.md/ *.docx/*.pptx)都在 workspace/tasks/<id>/ 下,
# 由上面这条 workspace/ 一并忽略。repo 根级别的 sections/ / slides/ / spec_lock.md
# **故意不忽略**——如果 agent 又写错位置,要靠 git status 立刻暴露,不再用 .gitignore 兜底。
workspace/
slides/
sections/
*.log
# Claude Code 本地状态
@ -41,11 +42,10 @@ desktop.ini
*.tmp.pptx
output.pptx
untitled*.pptx
spec_lock.md
/*.pptx
/*.docx
# 用户本地工具脚本 / 规划文件 (不入库)
规划.docx
cl.ps1
col.bat
col.ps1

View File

@ -56,19 +56,27 @@ zcbot/
├── workspace/
│ └── tasks/<task_id>/
│ ├── state.json # TaskState
│ └── messages.json # Session
│ ├── messages.json # Session
│ ├── spec_lock.md # skill 阶段一产物 (proposal/ppt)
│ ├── source/ # proposal 用户素材 (PDF / 团队介绍)
│ ├── source.md # ppt 转过的素材
│ ├── sections/ # proposal 逐章 md (01_summary.md ... 12_appendix.md)
│ ├── slides/ # ppt 中间素材 (chart_p?.png)
│ └── <topic>.docx / .pptx # 最终产物
├── main.py # 装配 (build_agent)
└── cli.py # CLI: chat / tasks / probe
```
**task_dir = `workspace/tasks/<task_id>/`,所有 skill 产物都写到这里**。task_dir 绝对路径在 system prompt 里显式给 agent,SKILL.md 的 `<task_dir>` 占位符指向它。如果 agent 写错位置(写到 cwd / `skills/` / repo 根),git status 会立刻报红 —— `.gitignore` 不再用无锚通配规则盖住污染。
### 启动时拼装顺序
1. 读 `config/agent.yaml` 拿 default_model
2. `ModelCapabilities.load("deepseek_v4.flash", config/models/)` 拿能力档案
3. `LLM(caps)` 构造,从 env 读 API key
4. 解析 task_dir(新建 or resume)
5. 拼 system prompt:`prompts/system/general_v1.md` + `SkillRegistry.discovery_block()`(skill 列表)+ 当前 cwd
5. 拼 system prompt:`prompts/system/general_v1.md` + `SkillRegistry.discovery_block()`(skill 列表)+ cwd + **task_dir 绝对路径**(产物根)
6. 装配工具集(fs / shell / load_skill / run_python)
7. 写初始 `state.json` + `messages.json`,启动 REPL
7. 启动 REPL —— **新建路径不预占文件**(懒创建,见 §3.6)
---
@ -77,7 +85,9 @@ zcbot/
### 3.1 主循环(`core/loop.py`)
ReAct 风格:LLM → 若有 tool_calls 就执行 → 把结果塞回消息列表 → 再调 LLM。无 tool_call 即返回。
- 工具结果对模型截断到 16K 字符,对用户预览 400 字符
- 用 `console.status("thinking...")` 转圈点,所有日志走 `rich`
- thinking spinner 由后台 daemon 线程每 100ms 刷新文本:`thinking... 1.3s ctx 12,345 tok`(累计 token 反映上下文大小)
- 每轮 LLM 返回追加 dim 一行 `[in N out N t Xs]` —— 留痕本轮成本
- assistant 文字走 `rich.markdown.Markdown` 渲染,粗体/列表/表格/代码块正常展示(非流式,整段渲染)
- `max_iterations` 从 capabilities 读,不同模型不同
### 3.2 Model Profile(`core/capabilities.py` + `config/models/*.yaml`)
@ -126,7 +136,11 @@ yaml 是手填的,可能错。`probe` 用真实 LLM 调用对账:
存储:`workspace/tasks/<task_id>/{state.json, messages.json}`。每轮 `agent.run` 后调 `sync_task_tokens` 把 LLM 累计 tokens 写回。
CLI:`chat --mode coding --desc "..."`;REPL `/status /done /abandon /desc`;`tasks [--status active|completed|abandoned]` 列任务。
**懒创建** —— `build_agent` 新建分支不立刻 save,task_dir 在第一条 user 消息触发 `Session.append → save()` 时才物化(`Session.save` / `TaskState.save``mkdir(parents=True)`)。启动 REPL 后立刻 `/exit` 磁盘无痕,跨进程也安全(没有"另一个 REPL 刚 build_agent 还没说话就被这个进程当空 task 删掉"的窗口)。
**REPL 内 task 切换** —— `/new` 开新 task,`/resume [last|<id>]` 切到已有 task(无参数列最近 10 个表格让用户选),`/done /abandon` 改状态,`/desc` 改描述。切走前 `_cleanup_if_empty` 守门:三条都满足才删 task_dir —— ① session 没 user 消息 ② 目录在磁盘上 ③ 目录里只剩 `messages.json`(state.json 存在 = `/done /abandon /desc` 留下的显式痕迹,要保)。
CLI:`chat --mode coding --desc "..." [--resume last|<id>]`;`tasks [--status active|completed|abandoned]` 列任务。
---

View File

@ -2,7 +2,7 @@
> 配合 `DESIGN.md` 阅读。本文件只记录 phase 状态、决策偏差、文件量、下一步。
最后更新:2026-05-06(Phase 4 + Phase 6 task/state.json 落地;Phase 5 evals 决定不做)
最后更新:2026-05-08(REPL `/resume` + 懒创建 task_dir + 切换前空清理)
---
@ -22,7 +22,7 @@
## 已完成关键能力
**Phase 1-3**(2026 早期):骨架 + skill 系统 + run_python。所有工具基目录是用户当前 cwd(不是 zcbot 仓库本身),agent 操作的是用户项目。`tools/fs.py` 的 `edit` 用 CoreCoder 风格唯一匹配。`tools/run_python.py` 过滤 `*API_KEY *TOKEN *SECRET *PASSWORD *PRIVATE_KEY` 环境变量。三个 skill 中 `ppt/` 最完整(v3:商务红硬约束 + apply_brand 品牌条 + Iconify 图标库 + scripts:fetch_icon / quality_check / source_to_md / render_icon)。
**Phase 1-3**(2026 早期):骨架 + skill 系统 + run_python。所有工具基目录是用户当前 cwd(不是 zcbot 仓库本身),agent 操作的是用户项目。`tools/fs.py` 的 `edit` 用 CoreCoder 风格唯一匹配。`tools/run_python.py` 过滤 `*API_KEY *TOKEN *SECRET *PASSWORD *PRIVATE_KEY` 环境变量。三个 skill 中 `ppt/` 最完整(v3:商务红硬约束 + apply_brand 品牌条 + Iconify 图标库 + scripts:fetch_icon / quality_check / render_icon;素材摄取改用 markitdown CLI)。
**Phase 4**(2026-05-06):
- `core/probe.py` + `cli.py probe` —— basic_chat / parallel_tools / thinking_mode / long_context 四项探测
@ -34,13 +34,24 @@
- CLI 新增 `tasks` 子命令 + REPL `/status /done /abandon /desc`;`chat` 加 `--mode --desc` 选项
- 移除 legacy `workspace/sessions/` 兼容(单一布局)
**TUI 打磨 + task_dir 落地**(2026-05-07):
- assistant 文字走 `rich.markdown.Markdown`,粗体/列表/表格/代码块正常渲染(非流式)
- thinking spinner 由 daemon 线程每 100ms 刷文案,显示实时耗时 + 累计 token;每轮 LLM 返回追加 dim 一行 `[in N out N t Xs]` 留痕
- system prompt 显式注入 `task_dir` 绝对路径,SKILL.md 里 `<task_dir>` 占位符**真正落地**;`spec_lock.md` / `sections/` / `slides/` / 最终 docx/pptx 全收敛到 `workspace/tasks/<id>/`
- `.gitignore``sections/` `slides/` `spec_lock.md` 三条无锚 bandaid —— 现在写错位置 git status 立刻报红,不再靠 ignore 兜底
**REPL 内 task 切换 + 懒创建**(2026-05-08):
- `/resume [last|<id>]` REPL 命令,无参数列最近 10 个 task 表格让用户挑序号或 task_id;和 `/new` 对称,都在 REPL 内重建 (agent, session, sid, task_state, task_dir) 五元组。`tasks` 命令和 `/resume` 共用 `_list_task_rows` helper
- **懒创建 task_dir**:`build_agent` 新建分支不再 `session.save()` / `task_state.save()` 占位,推迟到首条 user 消息触发的 `Session.append → save()`。启动 REPL 立刻 `/exit` 磁盘无痕,跨进程安全(没有"另一个 REPL 刚 build_agent 没说话就被本进程当空 task 删"的窗口)
- `_cleanup_if_empty` 在切走前(`/exit /quit /new /resume` + Ctrl-C/EOF)守门。三条都满足才删 task_dir:① 无 user 消息 ② 目录在磁盘上 ③ 文件集 ⊆ `{messages.json}`(state.json 存在 = 用户跑过 `/done /abandon /desc` 留下显式痕迹,要保)
---
## 关键决策与偏差
| 项 | 决策 | 与设计差异 |
|---|------|-----------|
| 工具基目录 | 用户当前 cwd | 设计未明说;agent 该操作用户项目 |
| 工具基目录 | 用户当前 cwd(读)+ task_dir(写) | system prompt 同时给 cwd 与 task_dir 绝对路径,SKILL.md `<task_dir>` 占位符指向 task_dir |
| Workspace 用途 | `tasks/<id>/{state.json, messages.json}` | memory/ 待 Phase 6 双层记忆 |
| Eval Suite | 不做 | 设计为团队场景;个人工具 dogfooding 替代 |
| 版本化 prompt | 直接 `general_v1.md`,无 active.md 软链接 | Windows 软链接麻烦,真要切版本时再做 |
@ -53,20 +64,20 @@
```
core/capabilities.py 71
core/llm.py 89
core/loop.py 99
core/loop.py 158 ← +markdown 渲染 / spinner 显时长+token
core/probe.py 243 ← Phase 4
core/session.py 77
core/skills.py 81
core/task.py 63 ← Phase 6
tools/base.py 34
tools/fs.py 182
tools/shell.py 63
tools/shell.py 94
tools/run_python.py 84
tools/skill_tool.py 45
main.py 175 ← Phase 6 task 装配
cli.py 265 ← +probe / +tasks 子命令
main.py 185 ← Phase 6 task 装配 / +task_dir 注入 / -占位 save (懒创建)
cli.py 358 ← +probe / +tasks / +/resume / +空 task 清理
─────────────────────────────────
Python 合计 ~1571
Python 合计 ~1764
```
加上 skills/ppt 下的脚本(~600 行)、SKILL.md / references / config / prompts,总仓库约 2500 行可读源码。
@ -80,3 +91,4 @@ Python 合计 ~1571 行
3. **小修打磨**(~半小时)—— `Session.save()` 改原子写(tmp + rename),防 surrogate 等异常 truncate
4. **Phase 7 Docker 沙盒**(~1 天)—— 替换 subprocess,run_python 安全升级
5. **Phase 7 更多 skill / 模型档案**(持续)
6. **Proposal mermaid 流程图预渲染**(~半天,看到第二张图再做)—— 现状是 ASCII 框图走 fenced code 透传 (新宋体 + Consolas + xml:space=preserve),中文与 box drawing 字符宽度对不齐时还是有错位。增强方案: ` ```mermaid ` 块在 `render_docx.py` 里调 `mmdc` (mermaid-cli) → PNG → `add_picture` 嵌入。依赖 Node.js + `npm i -g @mermaid-js/mermaid-cli`,首次配置略麻烦,所以等 ASCII 透传明显不够用再做

440
cli.py
View File

@ -12,14 +12,16 @@
from __future__ import annotations
import json
import shutil
import sys
from pathlib import Path
import click
from rich.console import Console
from rich.prompt import Prompt
from rich.table import Table
from core.task import TaskState
from core.ui import make_console
from main import (
ROOT,
build_agent,
@ -35,126 +37,32 @@ def cli() -> None:
"""zcbot - 个人任务 agent"""
@cli.command()
@click.option("--model", default=None, help="模型档案,如 deepseek_v4.flash 或 deepseek_v4.pro")
@click.option("--workspace", default=None, help="工作目录(存 tasks/ 和 sessions/)")
@click.option("--resume", default=None, help="恢复 task: 'last' 或 task_id")
@click.option("--mode", default="", help="任务模式标签(coding/ppt/proposal/...自由形式)")
@click.option("--desc", default="", help="一句话任务描述,便于 tasks 列表识别")
def chat(model: str, workspace: str, resume: str, mode: str, desc: str) -> None:
"""启动交互式 REPL。每次启动默认开新 task,用 --resume 接老的。"""
console = Console()
def _cleanup_if_empty(task_dir, session, console=None) -> bool:
"""切走前清理 task_dir。三条都满足才删:
1) session 没有 user 消息
2) task_dir 在磁盘上(懒创建后,没说话就没目录,直接 no-op)
3) 目录里只剩 messages.json(state.json 存在 = `/done /abandon /desc` 留下的显式痕迹,要保)
"""
if any(m.get("role") == "user" for m in session.messages):
return False
try:
agent, session, sid, task_state, task_dir = build_agent(
model_name=model,
workspace=workspace,
console=console,
session_id=resume,
resume=bool(resume),
mode=mode,
description=desc,
)
except Exception as e:
console.print(f"[red]启动失败:[/red] {type(e).__name__}: {e}")
sys.exit(1)
if resume:
console.print(
f"[green]恢复 task[/green] [bold]{sid}[/bold] ({len(session.messages)} 条消息) "
f"model: [bold]{agent.caps.model_id}[/bold]"
)
else:
meta_tail = ""
if task_state.mode or task_state.description:
meta_tail = f" mode={task_state.mode!r} desc={task_state.description!r}"
console.print(
f"[green]新 task[/green] [bold]{sid}[/bold] "
f"model: [bold]{agent.caps.model_id}[/bold]{meta_tail}"
)
console.print(
"[dim]/exit 退出 /reset 清空对话(保留 task) /new 开新 task /id /status 查看 "
"/done /abandon 改状态 /desc <文本> 设描述[/dim]\n"
)
while True:
try:
user_input = Prompt.ask("[bold blue]you[/bold blue]")
except (EOFError, KeyboardInterrupt):
console.print("\n[dim]bye[/dim]")
break
cmd = user_input.strip()
if cmd in ("/exit", "/quit"):
break
if cmd == "/reset":
session.reset(keep_system=True)
console.print("[dim]当前 task 对话已重置(保留 system 和 state)[/dim]")
continue
if cmd == "/new":
try:
agent, session, sid, task_state, task_dir = build_agent(
model_name=model, workspace=workspace, console=console,
mode=mode, description=desc,
)
except Exception as e:
console.print(f"[red]新建失败:[/red] {type(e).__name__}: {e}")
continue
console.print(f"[green]新 task[/green] [bold]{sid}[/bold]")
continue
if cmd == "/id":
cwd_disp = session.meta.get("cwd", "?")
model_disp = session.meta.get("model", agent.caps.model_id)
console.print(f"[dim]task: {sid} model: {model_disp} cwd: {cwd_disp}[/dim]")
continue
if cmd == "/status":
console.print(
f"[dim]task {task_state.task_id} status={task_state.status} "
f"mode={task_state.mode!r} desc={task_state.description!r}\n"
f" model={task_state.model} tokens={task_state.tokens_total} "
f"(p={task_state.tokens_prompt}/c={task_state.tokens_completion}) "
f"created={task_state.created_at} updated={task_state.updated_at}[/dim]"
)
continue
if cmd == "/done":
task_state.status = "completed"
task_state.save(task_dir)
console.print(f"[green]task {sid} marked completed[/green]")
break
if cmd == "/abandon":
task_state.status = "abandoned"
task_state.save(task_dir)
console.print(f"[yellow]task {sid} marked abandoned[/yellow]")
break
if cmd.startswith("/desc"):
new_desc = cmd[len("/desc"):].strip()
task_state.description = new_desc
task_state.save(task_dir)
console.print(f"[dim]description set: {new_desc!r}[/dim]")
continue
if not cmd:
continue
try:
agent.run(user_input)
except KeyboardInterrupt:
console.print("\n[yellow]已中断本轮。下一条输入会继续这个 task。[/yellow]")
except Exception as e:
console.print(f"[red]运行错误:[/red] {type(e).__name__}: {e}")
finally:
sync_task_tokens(task_state, task_dir, agent.llm)
entries = list(task_dir.iterdir())
except FileNotFoundError:
return False
if any(p.is_dir() for p in entries):
return False
if {p.name for p in entries if p.is_file()} - {"messages.json"}:
return False
shutil.rmtree(task_dir, ignore_errors=True)
if console is not None:
console.print(f"[muted]清理空 task {task_dir.name}[/muted]")
return True
@cli.command()
@click.option("--workspace", default=None, help="工作目录")
@click.option("--limit", default=20, help="显示最近 N 个")
@click.option("--status", default=None, help="只看某状态: active / completed / abandoned")
def tasks(workspace: str, limit: int, status: str) -> None:
"""列出已有 task(新格式,workspace/tasks/<id>/state.json)。"""
cfg = load_config()
ws = resolve_workspace(workspace, cfg)
tdir = tasks_dir(ws)
rows = [] # (mtime, task_id, status, mode, model, tokens, n_msgs, desc)
def _list_task_rows(workspace_dir, limit=20, status=None):
"""返回 [(mtime, task_id, status, mode, model, tokens, n_msgs, desc), ...] mtime 降序。"""
tdir = tasks_dir(workspace_dir)
rows = []
for d in tdir.iterdir():
if not d.is_dir():
continue
@ -176,10 +84,223 @@ def tasks(workspace: str, limit: int, status: str) -> None:
st.model_profile or st.model, st.tokens_total, n, st.description,
))
rows.sort(reverse=True)
rows = rows[:limit]
return rows[:limit]
@cli.command()
@click.option("--model", default=None, help="模型档案,如 deepseek_v4.flash 或 deepseek_v4.pro")
@click.option("--workspace", default=None, help="工作目录(存 tasks/ 和 sessions/)")
@click.option("--resume", default=None, help="恢复 task: 'last' 或 task_id")
@click.option("--mode", default="", help="任务模式标签(coding/ppt/proposal/...自由形式)")
@click.option("--desc", default="", help="一句话任务描述,便于 tasks 列表识别")
def chat(model: str, workspace: str, resume: str, mode: str, desc: str) -> None:
"""启动交互式 REPL。每次启动默认开新 task,用 --resume 接老的。"""
console = make_console()
try:
agent, session, sid, task_state, task_dir = build_agent(
model_name=model,
workspace=workspace,
console=console,
session_id=resume,
resume=bool(resume),
mode=mode,
description=desc,
)
except Exception as e:
console.print(f"[err]启动失败:[/err] {type(e).__name__}: {e}")
sys.exit(1)
if resume:
console.print(
f"[ok]恢复 task[/ok] [bold]{sid}[/bold] ({len(session.messages)} 条消息) "
f"model: [accent]{agent.caps.model_id}[/accent]"
)
else:
meta_tail = ""
if task_state.mode or task_state.description:
meta_tail = f" mode={task_state.mode!r} desc={task_state.description!r}"
console.print(
f"[ok]新 task[/ok] [bold]{sid}[/bold] "
f"model: [accent]{agent.caps.model_id}[/accent]{meta_tail}"
)
console.print(
"[info]/exit 退出 /reset 清空对话(保留 task) /new 开新 task "
"/resume [last|<id>] 切到已有 task /id /status 查看 "
"/done /abandon 改状态 /desc <文本> 设描述 "
"/export [<id>] 导出对话为 .docx[/info]\n"
)
while True:
try:
user_input = Prompt.ask("[user]you[/user]", console=console)
except (EOFError, KeyboardInterrupt):
console.print("\n[muted]bye[/muted]")
_cleanup_if_empty(task_dir, session, console)
break
cmd = user_input.strip()
if cmd in ("/exit", "/quit"):
_cleanup_if_empty(task_dir, session, console)
break
if cmd == "/reset":
session.reset(keep_system=True)
console.print("[info]当前 task 对话已重置(保留 system 和 state)[/info]")
continue
if cmd == "/new":
_cleanup_if_empty(task_dir, session, console)
try:
agent, session, sid, task_state, task_dir = build_agent(
model_name=model, workspace=workspace, console=console,
mode=mode, description=desc,
)
except Exception as e:
console.print(f"[err]新建失败:[/err] {type(e).__name__}: {e}")
continue
console.print(f"[ok]新 task[/ok] [bold]{sid}[/bold]")
continue
if cmd.startswith("/resume"):
arg = cmd[len("/resume"):].strip()
ws_dir = resolve_workspace(workspace)
target_id = None
if arg == "last":
rs = _list_task_rows(ws_dir, limit=1)
if not rs:
console.print("[warn]没有可恢复的 task[/warn]")
continue
target_id = rs[0][1]
elif arg:
target_id = arg
else:
rs = _list_task_rows(ws_dir, limit=10)
if not rs:
console.print("[warn]没有可恢复的 task[/warn]")
continue
tbl = Table(show_lines=False)
tbl.add_column("#", style="bold")
tbl.add_column("task id")
tbl.add_column("status")
tbl.add_column("mode")
tbl.add_column("msgs", justify="right")
tbl.add_column("desc")
sc = {"active": "status.active", "completed": "status.completed", "abandoned": "status.abandoned"}
for i, (_, tid, st, md, _mdl, _tok, n, dsc) in enumerate(rs, 1):
c = sc.get(st, "info")
d_show = dsc if len(dsc) <= 50 else dsc[:47] + "..."
tbl.add_row(str(i), tid, f"[{c}]{st}[/{c}]", md, str(n), d_show)
console.print(tbl)
try:
sel = Prompt.ask("[user]选编号或输入 task_id (回车取消)[/user]", console=console, default="")
except (EOFError, KeyboardInterrupt):
continue
sel = sel.strip()
if not sel:
continue
if sel.isdigit():
idx = int(sel) - 1
if 0 <= idx < len(rs):
target_id = rs[idx][1]
else:
console.print(f"[err]编号超界: {sel}[/err]")
continue
else:
target_id = sel
if target_id == sid:
console.print(f"[info]已是当前 task: {sid}[/info]")
continue
_cleanup_if_empty(task_dir, session, console)
try:
agent, session, sid, task_state, task_dir = build_agent(
model_name=model, workspace=workspace, console=console,
session_id=target_id, resume=True,
)
except Exception as e:
console.print(f"[err]恢复失败:[/err] {type(e).__name__}: {e}")
continue
console.print(
f"[ok]切到 task[/ok] [bold]{sid}[/bold] ({len(session.messages)} 条消息) "
f"model: [accent]{agent.caps.model_id}[/accent]"
)
continue
if cmd == "/id":
cwd_disp = session.meta.get("cwd", "?")
model_disp = session.meta.get("model", agent.caps.model_id)
console.print(f"[info]task: {sid} model: {model_disp} cwd: {cwd_disp}[/info]")
continue
if cmd == "/status":
console.print(
f"[info]task {task_state.task_id} status={task_state.status} "
f"mode={task_state.mode!r} desc={task_state.description!r}\n"
f" model={task_state.model} tokens={task_state.tokens_total} "
f"(p={task_state.tokens_prompt}/c={task_state.tokens_completion}) "
f"created={task_state.created_at} updated={task_state.updated_at}[/info]"
)
continue
if cmd == "/done":
task_state.status = "completed"
task_state.save(task_dir)
console.print(f"[ok]task {sid} marked completed[/ok]")
break
if cmd == "/abandon":
task_state.status = "abandoned"
task_state.save(task_dir)
console.print(f"[warn]task {sid} marked abandoned[/warn]")
break
if cmd.startswith("/desc"):
new_desc = cmd[len("/desc"):].strip()
task_state.description = new_desc
task_state.save(task_dir)
console.print(f"[info]description set: {new_desc!r}[/info]")
continue
if cmd.startswith("/export"):
arg = cmd[len("/export"):].strip()
target_dir = task_dir
if arg:
ws_dir = resolve_workspace(workspace)
if arg == "last":
rs = _list_task_rows(ws_dir, limit=1)
if not rs:
console.print("[warn]没有 task 可导出[/warn]")
continue
arg = rs[0][1]
target_dir = tasks_dir(ws_dir) / arg
if not (target_dir / "messages.json").exists():
console.print(
f"[warn]无可导出内容: {target_dir.name} 还没有消息[/warn]"
)
continue
try:
from core.export_docx import export_chat_to_docx
out = export_chat_to_docx(target_dir)
except Exception as e:
console.print(f"[err]导出失败:[/err] {type(e).__name__}: {e}")
continue
console.print(f"[ok]已导出[/ok] -> {out}")
continue
if not cmd:
continue
try:
agent.run(user_input)
except KeyboardInterrupt:
console.print("\n[warn]已中断本轮。下一条输入会继续这个 task。[/warn]")
except Exception as e:
console.print(f"[err]运行错误:[/err] {type(e).__name__}: {e}")
finally:
sync_task_tokens(task_state, task_dir, agent.llm)
@cli.command()
@click.option("--workspace", default=None, help="工作目录")
@click.option("--limit", default=20, help="显示最近 N 个")
@click.option("--status", default=None, help="只看某状态: active / completed / abandoned")
def tasks(workspace: str, limit: int, status: str) -> None:
"""列出已有 task(新格式,workspace/tasks/<id>/state.json)。"""
cfg = load_config()
ws = resolve_workspace(workspace, cfg)
rows = _list_task_rows(ws, limit=limit, status=status)
if not rows:
click.echo(f"(no tasks in {tdir})")
click.echo(f"(no tasks in {tasks_dir(ws)})")
return
tbl = Table(show_lines=False)
tbl.add_column("task id", style="bold")
@ -189,12 +310,61 @@ def tasks(workspace: str, limit: int, status: str) -> None:
tbl.add_column("msgs", justify="right")
tbl.add_column("tokens", justify="right")
tbl.add_column("desc")
sc = {"active": "cyan", "completed": "green", "abandoned": "dim"}
sc = {"active": "status.active", "completed": "status.completed", "abandoned": "status.abandoned"}
for _, tid, st, mode, model, tok, n, desc in rows:
c = sc.get(st, "white")
c = sc.get(st, "info")
d_show = desc if len(desc) <= 50 else desc[:47] + "..."
tbl.add_row(tid, f"[{c}]{st}[/{c}]", mode, model, str(n), str(tok), d_show)
Console().print(tbl)
make_console().print(tbl)
@cli.command()
@click.argument("task_id")
@click.option("--workspace", default=None, help="工作目录")
@click.option("-o", "--output", default=None,
help="输出 .docx 路径,默认 <task_dir>/chat_<task_id>.docx")
@click.option("--include-system", is_flag=True,
help="包含 system prompt(默认跳过,信息密度低)")
@click.option("--no-reasoning", is_flag=True,
help="不包含 reasoning_content(默认带)")
@click.option("--tool-head", default=1000, type=int,
help="tool 结果保留前 N 字符(默认 1000)")
@click.option("--tool-tail", default=500, type=int,
help="tool 结果保留后 N 字符(默认 500)")
def export(task_id: str, workspace: str, output: str, include_system: bool,
no_reasoning: bool, tool_head: int, tool_tail: int) -> None:
"""把指定 task 的对话导出为 .docx。task_id 用 'last' 取最近一个。"""
from core.export_docx import export_chat_to_docx
console = make_console()
cfg = load_config()
ws = resolve_workspace(workspace, cfg)
if task_id == "last":
rs = _list_task_rows(ws, limit=1)
if not rs:
console.print("[err]没有 task 可导出[/err]")
sys.exit(1)
task_id = rs[0][1]
td = tasks_dir(ws) / task_id
if not (td / "messages.json").exists():
console.print(f"[err]task 不存在或无 messages.json:[/err] {td}")
sys.exit(1)
out = Path(output).resolve() if output else None
try:
path = export_chat_to_docx(
td, out,
include_system=include_system,
include_reasoning=not no_reasoning,
tool_head=tool_head,
tool_tail=tool_tail,
)
except Exception as e:
console.print(f"[err]导出失败:[/err] {type(e).__name__}: {e}")
sys.exit(1)
console.print(f"[ok]导出完成[/ok] -> {path}")
@cli.command()
@ -209,25 +379,25 @@ def probe(model: str, long_context: bool) -> None:
cfg = load_config()
name = model or cfg["default_model"]
console = Console()
console = make_console()
try:
caps = ModelCapabilities.load(name, ROOT / cfg["models_dir"])
except Exception as e:
console.print(f"[red]档案加载失败:[/red] {type(e).__name__}: {e}")
console.print(f"[err]档案加载失败:[/err] {type(e).__name__}: {e}")
sys.exit(1)
console.print(
f"[bold]probing[/bold] [cyan]{caps.model_id}[/cyan] (profile: {name}) "
f"[dim]long-context={long_context}[/dim]\n"
f"[bold]probing[/bold] [accent]{caps.model_id}[/accent] (profile: {name}) "
f"[muted]long-context={long_context}[/muted]\n"
)
try:
llm = LLM(caps)
except Exception as e:
console.print(f"[red]LLM 构造失败:[/red] {type(e).__name__}: {e}")
console.print(f"[err]LLM 构造失败:[/err] {type(e).__name__}: {e}")
sys.exit(1)
with console.status("[dim]running probes...[/dim]", spinner="dots"):
with console.status("[muted]running probes...[/muted]", spinner="dots"):
report = probe_capabilities(caps, llm, include_long_context=long_context)
tbl = Table(show_lines=False)
@ -236,9 +406,9 @@ def probe(model: str, long_context: bool) -> None:
tbl.add_column("observed")
tbl.add_column("status")
tbl.add_column("detail")
color = {"ok": "green", "mismatch": "yellow", "error": "red", "skip": "dim"}
color = {"ok": "ok", "mismatch": "warn", "error": "err", "skip": "muted"}
for r in report.results:
c = color.get(r.status, "white")
c = color.get(r.status, "info")
tbl.add_row(
r.name,
str(r.declared),
@ -250,14 +420,14 @@ def probe(model: str, long_context: bool) -> None:
if report.has_mismatch:
console.print(
"\n[yellow]存在能力对账差异 —— 看 detail,必要时改 "
f"config/models/{caps.family}.yaml[/yellow]"
"\n[warn]存在能力对账差异 —— 看 detail,必要时改 "
f"config/models/{caps.family}.yaml[/warn]"
)
sys.exit(2)
if any(r.status == "error" for r in report.results):
console.print("\n[red]部分探测出错(见 detail)[/red]")
console.print("\n[err]部分探测出错(见 detail)[/err]")
sys.exit(3)
console.print("\n[green]全部能力声明与实测一致。[/green]")
console.print("\n[ok]全部能力声明与实测一致。[/ok]")
if __name__ == "__main__":

372
core/export_docx.py Normal file
View File

@ -0,0 +1,372 @@
"""把 task 的 messages.json 渲染为 .docx 对话稿。
布局:
- 文档开头 meta (task_id / 模式 / 描述 / 模型 / 创建时间 / 消息数 / tokens / 导出时间)
- 主体每条消息一组段落,全部左排,小字号,角色用不同颜色加粗区分
- assistant reasoning_content 默认带,灰色斜体
- tool 结果保留前 head + 中间省略 + tail 三段
- tool_calls function + 参数 JSON 单列展示
调用入口:
- 顶层函数 export_chat_to_docx(task_dir, out_path=None, ...)
- CLI 子命令 `python cli.py export <task_id>` REPL `/export [<task_id>]` 都走它
"""
from __future__ import annotations
import json
from datetime import datetime
from pathlib import Path
from typing import Optional
from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Cm, Pt, RGBColor
# ───────────────────────── 配色 ─────────────────────────
# 选 Word 浅底高对比度的 GitHub-ish 色板,不刺眼也能区分
COLOR_USER = RGBColor(0x6F, 0x42, 0xC1) # 紫
COLOR_ASSISTANT = RGBColor(0x1F, 0x6F, 0xEB) # 蓝
COLOR_TOOL_CALL = RGBColor(0xBF, 0x63, 0x10) # 橙(深一点保证可读)
COLOR_TOOL_RESULT = RGBColor(0x1A, 0x7F, 0x37) # 绿
COLOR_REASONING = RGBColor(0x6E, 0x76, 0x81) # 中灰,斜体
COLOR_SYSTEM = RGBColor(0x57, 0x60, 0x6A) # 暗灰
COLOR_META_LABEL = RGBColor(0x57, 0x60, 0x6A)
# ───────────────────────── 字体辅助 ─────────────────────────
def _set_run_fonts(run, *, cn_font: str = "宋体", en_font: str = "Times New Roman") -> None:
rPr = run._element.get_or_add_rPr()
rFonts = rPr.find(qn("w:rFonts"))
if rFonts is None:
rFonts = OxmlElement("w:rFonts")
rPr.append(rFonts)
rFonts.set(qn("w:eastAsia"), cn_font)
rFonts.set(qn("w:ascii"), en_font)
rFonts.set(qn("w:hAnsi"), en_font)
def _preserve_spaces(run) -> None:
"""让 docx 不压缩连续空格 — 代码块/JSON 缩进必须留住。"""
for t in run._element.iter(qn("w:t")):
t.set(qn("xml:space"), "preserve")
# ───────────────────────── 文档骨架 ─────────────────────────
def _init_doc() -> Document:
doc = Document()
section = doc.sections[0]
section.page_height = Cm(29.7)
section.page_width = Cm(21)
section.top_margin = Cm(2.0)
section.bottom_margin = Cm(2.0)
section.left_margin = Cm(2.5)
section.right_margin = Cm(2.0)
normal = doc.styles["Normal"]
normal.font.name = "Times New Roman"
normal.font.size = Pt(9.5)
pf = normal.paragraph_format
pf.line_spacing = 1.3
pf.space_before = Pt(0)
pf.space_after = Pt(0)
pf.first_line_indent = None
return doc
# ───────────────────────── 段落原语 ─────────────────────────
def _add_role_header(doc: Document, label: str, color: RGBColor) -> None:
p = doc.add_paragraph()
pf = p.paragraph_format
pf.first_line_indent = None
pf.space_before = Pt(8)
pf.space_after = Pt(2)
p.alignment = WD_ALIGN_PARAGRAPH.LEFT
run = p.add_run(label)
run.font.size = Pt(10.5)
run.font.bold = True
run.font.color.rgb = color
_set_run_fonts(run, cn_font="黑体", en_font="Consolas")
def _add_text(
doc: Document,
text: str,
*,
color: Optional[RGBColor] = None,
italic: bool = False,
mono: bool = False,
size: Pt = Pt(9.5),
indent_left: Optional[Pt] = None,
) -> None:
"""整段文本输出。保留 \n 换行;mono 用等宽中文(新宋体)+ Consolas。"""
if not text:
return
p = doc.add_paragraph()
pf = p.paragraph_format
pf.first_line_indent = None
pf.line_spacing = 1.25
pf.space_before = Pt(0)
pf.space_after = Pt(2)
if indent_left is not None:
pf.left_indent = indent_left
p.alignment = WD_ALIGN_PARAGRAPH.LEFT
cn_font = "新宋体" if mono else "宋体"
en_font = "Consolas" if mono else "Times New Roman"
lines = text.split("\n")
for i, line in enumerate(lines):
if i > 0:
br = p.add_run()
br.add_break()
run = p.add_run(line)
run.font.size = size
if color is not None:
run.font.color.rgb = color
if italic:
run.italic = True
_set_run_fonts(run, cn_font=cn_font, en_font=en_font)
if mono:
_preserve_spaces(run)
# ───────────────────────── 工具结果裁剪 ─────────────────────────
def _truncate_with_ellipsis(text: str, head: int, tail: int) -> str:
"""前 head + 省略 + 后 tail。整体短于阈值则原样返回。"""
if text is None:
return ""
if len(text) <= head + tail + 80:
return text
omitted = len(text) - head - tail
return f"{text[:head]}\n\n... [omitted {omitted} chars] ...\n\n{text[-tail:]}"
def _format_args(args_str: str) -> str:
"""tool_call 参数若是合法 JSON 就 pretty,否则原样返回。"""
if not args_str:
return ""
try:
parsed = json.loads(args_str)
return json.dumps(parsed, ensure_ascii=False, indent=2)
except Exception:
return args_str
# ───────────────────────── Meta 区块 ─────────────────────────
def _add_meta_block(
doc: Document, meta: dict, task_state: dict, n_msgs: int, source_path: Path
) -> None:
p = doc.add_paragraph()
p.alignment = WD_ALIGN_PARAGRAPH.LEFT
p.paragraph_format.first_line_indent = None
p.paragraph_format.space_before = Pt(0)
p.paragraph_format.space_after = Pt(4)
title = f"Task 对话记录 - {meta.get('id') or task_state.get('task_id') or '?'}"
run = p.add_run(title)
run.font.size = Pt(14)
run.font.bold = True
_set_run_fonts(run, cn_font="黑体", en_font="Consolas")
desc = task_state.get("description") or ""
mode = task_state.get("mode") or ""
status = task_state.get("status") or ""
model = meta.get("model") or task_state.get("model") or ""
profile = meta.get("model_profile") or task_state.get("model_profile") or ""
cwd = meta.get("cwd") or task_state.get("cwd") or ""
created = meta.get("created_at") or task_state.get("created_at") or ""
updated = task_state.get("updated_at") or ""
tp = task_state.get("tokens_prompt", 0)
tc = task_state.get("tokens_completion", 0)
rows = [
("Task ID", meta.get("id") or task_state.get("task_id") or "?"),
("模式", mode),
("描述", desc),
("状态", status),
("模型", model),
("Profile", profile),
("CWD", cwd),
("创建时间", created),
("更新时间", updated),
("消息数", str(n_msgs)),
("Tokens", f"{tp} prompt / {tc} completion / {tp + tc} total"),
("源文件", str(source_path)),
("导出时间", datetime.now().isoformat(timespec="seconds")),
]
table = doc.add_table(rows=len(rows), cols=2)
try:
table.style = "Light Grid Accent 1"
except KeyError:
pass
for ri, (k, v) in enumerate(rows):
c1 = table.rows[ri].cells[0]
c1.text = ""
p1 = c1.paragraphs[0]
p1.paragraph_format.first_line_indent = None
p1.paragraph_format.line_spacing = 1.15
run = p1.add_run(k)
run.font.size = Pt(9)
run.font.bold = True
run.font.color.rgb = COLOR_META_LABEL
_set_run_fonts(run, cn_font="宋体", en_font="Times New Roman")
c2 = table.rows[ri].cells[1]
c2.text = ""
p2 = c2.paragraphs[0]
p2.paragraph_format.first_line_indent = None
p2.paragraph_format.line_spacing = 1.15
run = p2.add_run(str(v) if v else "-")
run.font.size = Pt(9)
_set_run_fonts(run, cn_font="宋体", en_font="Times New Roman")
# ───────────────────────── 单条消息渲染 ─────────────────────────
def _render_message(
doc: Document,
msg: dict,
*,
include_reasoning: bool,
tool_head: int,
tool_tail: int,
) -> None:
role = msg.get("role")
if role == "system":
_add_role_header(doc, "[system]", COLOR_SYSTEM)
content = msg.get("content") or ""
# system prompt 通常 2-5KB,导出时也压一下
content = _truncate_with_ellipsis(content, 1500, 500)
_add_text(doc, content, color=COLOR_SYSTEM, size=Pt(8.5), mono=True)
return
if role == "user":
_add_role_header(doc, "[user]", COLOR_USER)
_add_text(doc, msg.get("content") or "", size=Pt(10))
return
if role == "assistant":
_add_role_header(doc, "[assistant]", COLOR_ASSISTANT)
if include_reasoning:
rc = msg.get("reasoning_content") or ""
if not rc:
psf = msg.get("provider_specific_fields") or {}
rc = psf.get("reasoning_content") or ""
if rc:
_add_text(
doc, "▎reasoning",
color=COLOR_REASONING, size=Pt(8.5), italic=True,
)
_add_text(
doc, rc,
color=COLOR_REASONING, size=Pt(9), italic=True,
indent_left=Pt(12),
)
content = msg.get("content") or ""
if content:
_add_text(doc, content, size=Pt(10))
for call in msg.get("tool_calls") or []:
fn_obj = call.get("function") or {}
fn = fn_obj.get("name", "?")
args = fn_obj.get("arguments", "")
cid = call.get("id", "")
_add_text(
doc, f"▎tool_call -> {fn} ({cid})",
color=COLOR_TOOL_CALL, size=Pt(9), italic=True,
)
_add_text(
doc, _format_args(args),
color=COLOR_TOOL_CALL, size=Pt(8.5), mono=True,
indent_left=Pt(12),
)
return
if role == "tool":
cid = msg.get("tool_call_id", "")
_add_role_header(doc, f"[tool result] ({cid})", COLOR_TOOL_RESULT)
content = msg.get("content") or ""
truncated = _truncate_with_ellipsis(content, tool_head, tool_tail)
_add_text(
doc, truncated,
color=COLOR_TOOL_RESULT, size=Pt(8.5), mono=True,
indent_left=Pt(12),
)
return
# 兜底:未知 role
_add_role_header(doc, f"[{role or 'unknown'}]", COLOR_SYSTEM)
_add_text(doc, msg.get("content") or "", size=Pt(9.5))
# ───────────────────────── 顶层入口 ─────────────────────────
def export_chat_to_docx(
task_dir: Path,
out_path: Optional[Path] = None,
*,
include_system: bool = False,
include_reasoning: bool = True,
tool_head: int = 1000,
tool_tail: int = 500,
) -> Path:
"""渲染 task_dir 下的 messages.json 为 .docx,返回写入路径。
out_path 缺省落到 task_dir/chat_<task_id>.docx
include_system 默认 False(system prompt 信息密度低,默认跳过)
include_reasoning 默认 True(模型思考过程,有观察价值)
tool 结果默认前 1000 + 500,中间省略
"""
msg_path = task_dir / "messages.json"
if not msg_path.exists():
raise FileNotFoundError(f"messages.json 不存在: {msg_path}")
data = json.loads(msg_path.read_text(encoding="utf-8"))
if isinstance(data, list):
meta = {}
messages = data
elif isinstance(data, dict):
meta = data.get("meta") or {}
messages = data.get("messages") or []
else:
raise ValueError(f"messages.json 格式不识别: {type(data).__name__}")
state_path = task_dir / "state.json"
task_state: dict = {}
if state_path.exists():
try:
task_state = json.loads(state_path.read_text(encoding="utf-8")) or {}
except Exception:
task_state = {}
if out_path is None:
tid = meta.get("id") or task_state.get("task_id") or task_dir.name
out_path = task_dir / f"chat_{tid}.docx"
doc = _init_doc()
_add_meta_block(doc, meta, task_state, len(messages), msg_path)
doc.add_paragraph() # 与 meta 表保持一行间距
for msg in messages:
if msg.get("role") == "system" and not include_system:
continue
_render_message(
doc, msg,
include_reasoning=include_reasoning,
tool_head=tool_head,
tool_tail=tool_tail,
)
out_path.parent.mkdir(parents=True, exist_ok=True)
doc.save(str(out_path))
return out_path

View File

@ -13,6 +13,7 @@ from rich.markdown import Markdown
from .capabilities import ModelCapabilities
from .llm import LLM
from .session import Session
from .ui import make_console
def _extract_usage(usage: Any) -> Tuple[int, int]:
@ -43,7 +44,7 @@ class AgentLoop:
self.session = session
self.caps = capabilities
self.max_iterations = max_iterations or capabilities.max_iterations
self.console = console or Console()
self.console = console or make_console()
@contextmanager
def _thinking(self):
@ -55,7 +56,7 @@ class AgentLoop:
elapsed = time.monotonic() - start
total = self.llm.token_counter.total
tail = f" ctx {total:,} tok" if total else ""
return f"[dim]thinking... {elapsed:.1f}s{tail}[/dim]"
return f"[muted]thinking... {elapsed:.1f}s{tail}[/muted]"
class Ctx:
elapsed: float = 0.0
@ -95,13 +96,13 @@ class AgentLoop:
pt, ct = _extract_usage(getattr(response, "usage", None))
self.console.print(
f"[dim][in {pt:,} out {ct:,} t {t.elapsed:.1f}s][/dim]"
f"[info][in {pt:,} out {ct:,} t {t.elapsed:.1f}s][/info]"
)
tool_calls = getattr(msg, "tool_calls", None) or []
content = getattr(msg, "content", None)
if content:
self.console.print("[cyan]assistant>[/cyan]")
self.console.print("[assistant]assistant>[/assistant]")
self.console.print(Markdown(content))
if not tool_calls:
@ -130,7 +131,7 @@ class AgentLoop:
preview = json.dumps(args, ensure_ascii=False)
if len(preview) > 200:
preview = preview[:200] + "..."
self.console.print(f"[yellow]tool>[/yellow] {name}({preview})")
self.console.print(f"[tool]tool>[/tool] {name}({preview})")
tool = self.tools.get(name)
if tool is None:
@ -153,5 +154,5 @@ class AgentLoop:
# 给用户预览(截短)
preview = result if len(result) < 400 else result[:400] + "..."
self.console.print(f"[dim]{preview}[/dim]")
self.console.print(f"[muted]{preview}[/muted]")
return result

38
core/ui.py Normal file
View File

@ -0,0 +1,38 @@
"""Rich 控制台主题: 统一 dark 终端友好的配色。
设计目标: 在黑底终端上,所有文字 readable,且语义有层次
- 弱化用 grey50/grey70 而不是 dim 一些终端把 dim 渲染得过暗
- 强调色一律走 bright_* 8 色版的 blue/cyan Windows 深底太黯
- 用语义样式名(user / assistant / tool / ok / warn / err / info / muted),
避免在调用处硬编码颜色,以后改主题只动这一处
"""
from __future__ import annotations
from rich.console import Console
from rich.theme import Theme
ZCBOT_THEME = Theme(
{
# 通用层次
"info": "grey70", # 普通信息(系统反馈、路径、命令提示)
"muted": "grey50", # 真要弱化的次要内容(预览、spinner 文本)
"accent": "bright_cyan", # 强调(模型名等)
# 角色
"user": "bold bright_magenta",
"assistant": "bold bright_cyan",
"tool": "bold bright_yellow",
# 状态
"ok": "bright_green",
"warn": "bright_yellow",
"err": "bold bright_red",
# task 状态列
"status.active": "bright_cyan",
"status.completed": "bright_green",
"status.abandoned": "grey50",
}
)
def make_console() -> Console:
"""创建带 zcbot 主题的 Console。所有 TUI 入口都应通过这个工厂拿 console。"""
return Console(theme=ZCBOT_THEME)

22
main.py
View File

@ -103,10 +103,10 @@ def build_agent(
saved_cwd = session.meta.get("cwd")
if saved_cwd and console is not None and saved_cwd != str(tool_base):
console.print(
f"[yellow]提示:[/yellow] 当前 cwd 与 task 记录不同 —— "
f"[warn]提示:[/warn] 当前 cwd 与 task 记录不同 —— "
f"工具基于 current cwd,不会自动切回。\n"
f" task cwd: [dim]{saved_cwd}[/dim]\n"
f" current cwd: [dim]{tool_base}[/dim]"
f" task cwd: [info]{saved_cwd}[/info]\n"
f" current cwd: [info]{tool_base}[/info]"
)
task_state = TaskState.load(task_dir)
if task_state is None:
@ -126,7 +126,17 @@ def build_agent(
system_prompt = (ROOT / cfg["system_prompt"]).read_text(encoding="utf-8")
if skills.skills:
system_prompt += f"\n\n## 可用 skill (用 load_skill 加载完整指引)\n{skills.discovery_block()}"
system_prompt += f"\n\n## 当前工作目录\n{tool_base}"
task_dir_abs = task_dir.resolve()
system_prompt += (
f"\n\n## 工作目录\n"
f"- cwd(用户启动时所在目录,只读用): `{tool_base}`\n"
f"- **task_dir(所有产物写到这里)**: `{task_dir_abs}`\n\n"
f"SKILL 文档里出现的 `<task_dir>` 占位符,一律指上面这个绝对路径。"
f"产物示例: `{task_dir_abs}/spec_lock.md`、"
f"`{task_dir_abs}/sections/01_summary.md`、"
f"`{task_dir_abs}/slides/`、最终 .docx/.pptx。\n"
f"⛔ 不要把产物写到 cwd / `skills/` / repo 根 —— 只写到 task_dir。"
)
now_iso = datetime.now().isoformat(timespec="seconds")
meta = {
"id": sid,
@ -136,7 +146,8 @@ def build_agent(
"model_profile": model,
}
session = Session(system_prompt=system_prompt, path=session_path, meta=meta)
session.save() # 占住文件名
# 懒创建:不预占文件。首条 user 消息触发 Session.append → save() 才会 mkdir + 落盘。
# task_state 同步推迟到首轮 sync_task_tokens。直到那一刻为止,task_dir 在磁盘上不存在。
task_state = TaskState(
task_id=sid,
mode=mode,
@ -148,7 +159,6 @@ def build_agent(
cwd=str(tool_base),
created_at=now_iso,
)
task_state.save(task_dir)
tools = {}
for cls in (ReadTool, WriteTool, EditTool, GlobTool, GrepTool, ShellTool):

View File

@ -7,3 +7,6 @@ rich>=13.7.0
python-pptx>=0.6.21
python-docx>=1.1.0
matplotlib>=3.8.0
# 素材摄取: PDF/DOCX/PPTX/XLSX/HTML/URL → Markdown (ppt 阶段零 + proposal 阶段零)
markitdown[pdf,docx,pptx,xlsx]>=0.0.1

View File

@ -12,7 +12,7 @@ description: 生成 PowerPoint 演示文稿 (.pptx)。当用户要求做汇报 P
- `references/layouts.md` —— 9 种版式的 python-pptx 起手代码 + 安全区/越界保护 + `apply_brand` 品牌条
- `references/icons.md` —— 业务图标两层:Iconify (在线/本地缓存) / unicode 字形兜底
- `assets/icons/` —— 本地图标缓存 (Iconify 拉过的图存这,见 `INDEX.md` 推荐清单)
- `scripts/source_to_md.py` —— PDF/DOCX/PPTX/URL → 干净 Markdown
- 素材摄取: 直接用 `markitdown` CLI (PDF/DOCX/PPTX/XLSX/HTML/URL → 干净 Markdown)
- `scripts/fetch_icon.py` —— 从 Iconify CDN 拉 SVG/PNG (染主题色,缓存本地)
- `scripts/render_icon.py` —— unicode 字形 → 透明 PNG (Iconify 没有时兜底)
- `scripts/quality_check.py` —— 产物 .pptx 验收 (越界 / 文本溢出 / 颜色一致)
@ -57,8 +57,8 @@ description: 生成 PowerPoint 演示文稿 (.pptx)。当用户要求做汇报 P
每页前 **必须 read 一次 `spec_lock.md`**,只用里面定的颜色/字体/图标 —— **不允许凭记忆或临时发挥**。这条规则是为了对抗长 deck 中的上下文漂移。
每页流程:
1. 读 `spec_lock.md` (即使刚读过)
2. **图标先于版式**: 这一页要用什么概念图标? 先 `glob skills/ppt/assets/icons/` 看本地有没有,没有就 `python skills/ppt/scripts/fetch_icon.py <name> --set tabler --color C00000 --size 128 -o skills/ppt/assets/icons/...` 拉一个;`add_picture` 嵌入。**几何形状(圆点/徽章/装饰线)不算图标,走 layouts.md helper 即可**
1. 读 `<task_dir>/spec_lock.md` (即使刚读过)
2. **图标先于版式**: 这一页要用什么概念图标? 先 `glob <skill_dir>/assets/icons/` 看本地有没有 (`<skill_dir>` 是 `load_skill` 头里的绝对路径),没有就 `python <skill_dir>/scripts/fetch_icon.py <name> --set tabler --color C00000 --size 128 -o <skill_dir>/assets/icons/...` 拉一个;`add_picture` 嵌入。**几何形状(圆点/徽章/装饰线)不算图标,走 layouts.md helper 即可**
3. 写一个 `run_python` block,用 python-pptx 添加这一页 (载入已有 .pptx → append slide → save)
4. 报这一页:版式、标题、要点条数、用了哪些图标
5. 用户确认 / 微调后再下一页
@ -70,7 +70,7 @@ description: 生成 PowerPoint 演示文稿 (.pptx)。当用户要求做汇报 P
### 阶段三: 验收
```bash
python scripts/quality_check.py <output.pptx> --spec spec_lock.md
python <skill_dir>/scripts/quality_check.py <task_dir>/<output.pptx> --spec <task_dir>/spec_lock.md
```
不通过的项,回头 edit 对应页。
@ -89,9 +89,12 @@ python scripts/quality_check.py <output.pptx> --spec spec_lock.md
- 详细规则见 `references/design_principles.md`
## 工作目录约定
下文 `<task_dir>` = system prompt 里「task_dir」给的**绝对路径**(形如 `…/workspace/tasks/<task_id>/`)。**所有产物都写到 task_dir 下**,不要写到 cwd / `skills/` / repo 根;`assets/icons/` 是 skill 自带的图标缓存,继续走 `skills/ppt/assets/icons/`
```
<task_dir>/
├── source.md # source_to_md.py 转出的素材
├── source.md # markitdown 转出的素材
├── spec_lock.md # 八条对齐落定
├── slides/
│ └── chart_p3.png # 各页用到的图片素材

View File

@ -16,23 +16,23 @@
按下面 3 行命令拉取首批最常用 18 个,够覆盖 80% 商务汇报场景:
```bash
ICONS_DIR=skills/ppt/assets/icons
ICONS_DIR=<skill_dir>/assets/icons # <skill_dir> 来自 load_skill 头
# 战略 / 目标 / 启动
for n in target rocket flag bulb; do
python skills/ppt/scripts/fetch_icon.py $n --set tabler --color C00000 --size 128 \
python <skill_dir>/scripts/fetch_icon.py $n --set tabler --color C00000 --size 128 \
-o "$ICONS_DIR/tabler_${n}_C00000_128.png"
done
# 数据 / 趋势 / 报表
for n in chart-bar chart-line trending-up calculator; do
python skills/ppt/scripts/fetch_icon.py $n --set tabler --color C00000 --size 128 \
python <skill_dir>/scripts/fetch_icon.py $n --set tabler --color C00000 --size 128 \
-o "$ICONS_DIR/tabler_${n}_C00000_128.png"
done
# 团队 / 流程 / 时间
for n in users settings calendar clock check shield-check arrow-right alert-triangle currency-yuan circle-check; do
python skills/ppt/scripts/fetch_icon.py $n --set tabler --color C00000 --size 128 \
python <skill_dir>/scripts/fetch_icon.py $n --set tabler --color C00000 --size 128 \
-o "$ICONS_DIR/tabler_${n}_C00000_128.png"
done
```

View File

@ -14,7 +14,7 @@
## §A. Iconify 个性化图标 (本地缓存 + 网络拉取)
### A1. 本地库
路径: `skills/ppt/assets/icons/`,详见 [INDEX.md](../assets/icons/INDEX.md)。
路径: `<skill_dir>/assets/icons/`,详见 [INDEX.md](../assets/icons/INDEX.md)。
命名规约: `<set>_<name>_<colorhex>_<sizepx>.png`(如 `tabler_rocket_C00000_128.png`)
**用之前先 `glob` 检查本地有没有**,有就直接 `add_picture`,免去网络往返。
@ -22,12 +22,12 @@
### A2. fetch_icon.py 拉新图标
```bash
# 主红色 128px PNG (推荐)
python skills/ppt/scripts/fetch_icon.py rocket --set tabler --color C00000 \
--size 128 -o skills/ppt/assets/icons/tabler_rocket_C00000_128.png
python <skill_dir>/scripts/fetch_icon.py rocket --set tabler --color C00000 \
--size 128 -o <skill_dir>/assets/icons/tabler_rocket_C00000_128.png
# 强调色金黄
python skills/ppt/scripts/fetch_icon.py target --set tabler --color FFC107 \
--size 128 -o skills/ppt/assets/icons/tabler_target_FFC107_128.png
python <skill_dir>/scripts/fetch_icon.py target --set tabler --color FFC107 \
--size 128 -o <skill_dir>/assets/icons/tabler_target_FFC107_128.png
```
`--set` 默认 `tabler`(4500+ 商务图标,MIT)。其它选 `lucide / heroicons / material-symbols / carbon / fluent / mdi`。**整 deck 只用一个 set**。
@ -37,7 +37,7 @@ PNG 转换需 `pip install cairosvg`(推荐)或 `pip install svglib`。没装也
### A3. 嵌入幻灯片
```python
slide.shapes.add_picture(
"skills/ppt/assets/icons/tabler_rocket_C00000_128.png",
"<skill_dir>/assets/icons/tabler_rocket_C00000_128.png",
Inches(1.0), Inches(2.5),
width=Inches(0.8), # 装饰图标 0.5-1.5 in;别超 2 in
)
@ -53,7 +53,7 @@ slide.shapes.add_picture(
```python
from pptx.util import Inches, Pt
stages = ["调研","设计","开发","测试","上线"]
icon_path = "skills/ppt/assets/icons/tabler_chevron-right_C00000_64.png"
icon_path = "<skill_dir>/assets/icons/tabler_chevron-right_C00000_64.png"
for i, label in enumerate(stages):
x = 0.7 + i * 2.4
add_textbox(slide, x, 3.7, 1.8, 0.5, label, 16, bold=True,
@ -79,7 +79,7 @@ Iconify 都没合适的时候用。避 emoji,用单色符号:
```bash
# 强调色对号 96px → PNG
python scripts/render_icon.py "✓" --color "#C00000" --size 96 -o slides/check.png
python <skill_dir>/scripts/render_icon.py "✓" --color "#C00000" --size 96 -o <task_dir>/slides/check.png
```
## §C. 硬规则

View File

@ -1,157 +0,0 @@
"""source_to_md.py: 把素材转成干净 Markdown,作为后续策略阶段的输入。
用法:
python source_to_md.py <input> # 自动按扩展名识别
python source_to_md.py <url> # http/https 走 web 抓
python source_to_md.py file.pdf -o source.md
支持:
.pdf pypdf 提取文本
.docx python-docx 段落
.pptx python-pptx 提取每页文字
.txt/.md 直读
URL requests + 简易 HTML 剥离
设计原则:模型在策略阶段只看 Markdown,不读二进制 / 不爬复杂排版
"""
from __future__ import annotations
import argparse
import re
import sys
from pathlib import Path
from urllib.parse import urlparse
def from_pdf(path: Path) -> str:
try:
from pypdf import PdfReader
except ImportError:
return "[error] pip install pypdf"
reader = PdfReader(str(path))
parts = [f"# {path.stem}\n"]
for i, page in enumerate(reader.pages, 1):
text = (page.extract_text() or "").strip()
if text:
parts.append(f"\n## Page {i}\n\n{text}\n")
return "\n".join(parts)
def from_docx(path: Path) -> str:
try:
from docx import Document
except ImportError:
return "[error] pip install python-docx"
doc = Document(str(path))
parts = [f"# {path.stem}\n"]
for para in doc.paragraphs:
text = para.text.strip()
if not text:
continue
style = (para.style.name or "").lower() if para.style else ""
if "heading 1" in style:
parts.append(f"\n## {text}\n")
elif "heading 2" in style:
parts.append(f"\n### {text}\n")
elif "heading 3" in style:
parts.append(f"\n#### {text}\n")
else:
parts.append(f"\n{text}\n")
return "".join(parts)
def from_pptx(path: Path) -> str:
try:
from pptx import Presentation
except ImportError:
return "[error] pip install python-pptx"
prs = Presentation(str(path))
parts = [f"# {path.stem}\n"]
for i, slide in enumerate(prs.slides, 1):
parts.append(f"\n## Slide {i}\n")
for shape in slide.shapes:
if shape.has_text_frame:
txt = shape.text_frame.text.strip()
if txt:
parts.append(f"\n{txt}\n")
return "".join(parts)
def from_text(path: Path) -> str:
return path.read_text(encoding="utf-8", errors="replace")
_TAG_RE = re.compile(r"<[^>]+>")
_WS_RE = re.compile(r"\n{3,}")
def from_url(url: str) -> str:
try:
import requests
except ImportError:
return "[error] pip install requests"
r = requests.get(url, timeout=30, headers={
"User-Agent": "Mozilla/5.0 (compatible; ppt-source-to-md/1.0)"
})
r.raise_for_status()
html = r.text
# 极简剥离:script/style 删,标签去除
html = re.sub(r"<script[\s\S]*?</script>", "", html, flags=re.I)
html = re.sub(r"<style[\s\S]*?</style>", "", html, flags=re.I)
title_m = re.search(r"<title[^>]*>([^<]+)</title>", html, re.I)
title = title_m.group(1).strip() if title_m else url
# 块级标签转换行
html = re.sub(r"</?(p|div|br|li|h[1-6]|tr)[^>]*>", "\n", html, flags=re.I)
text = _TAG_RE.sub("", html)
text = re.sub(r"&nbsp;", " ", text)
text = re.sub(r"&amp;", "&", text)
text = re.sub(r"&lt;", "<", text)
text = re.sub(r"&gt;", ">", text)
text = re.sub(r"&quot;", '"', text)
text = "\n".join(line.strip() for line in text.splitlines())
text = _WS_RE.sub("\n\n", text).strip()
return f"# {title}\n\nSource: {url}\n\n{text}\n"
def dispatch(src: str) -> str:
parsed = urlparse(src)
if parsed.scheme in ("http", "https"):
return from_url(src)
path = Path(src)
if not path.exists():
return f"[error] not found: {src}"
ext = path.suffix.lower()
if ext == ".pdf":
return from_pdf(path)
if ext == ".docx":
return from_docx(path)
if ext == ".pptx":
return from_pptx(path)
if ext in (".txt", ".md"):
return from_text(path)
return f"[error] unsupported extension: {ext}"
def main():
ap = argparse.ArgumentParser()
ap.add_argument("src", help="文件路径或 http(s) URL")
ap.add_argument("-o", "--output", type=Path, default=None,
help="写到文件;默认打印到 stdout")
args = ap.parse_args()
md = dispatch(args.src)
if args.output:
args.output.write_text(md, encoding="utf-8")
print(f"[ok] {args.output} ({len(md)} chars)")
else:
sys.stdout.write(md)
if __name__ == "__main__":
main()

View File

@ -5,112 +5,125 @@ description: 撰写中国科研项目申报书 / 课题任务书 (国家重点
# 科研申报
把课题信息变成可提交的申报书 .docx。**先定基金类型,再对齐,再逐章节起草,再验收** —— 不要一口气出全文。
把课题信息变成可提交的申报书 .docx。**先定基金类型 → 八条对齐 → 逐章起草 → 验收渲染** —— 不要一口气出全文。
## 资源
- `references/fund_types.md` —— 6 种主流基金的章节骨架 + 字数预算 + 特殊要求 (国自然面上/青年/联合基金、重点研发、重大专项、省基金、横向),决定了 spec_lock 的填法
- `references/section_templates.md` —— 通用章节写作骨架 (立项依据三段式 / 研究方案四段式 / 创新点三特征 / 考核指标矩阵)
- `references/review_redlines.md` —— 评审雷区清单 (假大空话术、指南脱靶、指标无法考核、经费不合理、限项违规等)
- `references/citation_gbt7714.md` —— GB/T 7714 顺序编码制 + 文献真实性铁律
- `references/budget_rules.md` —— 直接/间接费用比例规则、设备费、劳务费红线
- `references/typography.md` —— 字体/字号/行距/页面/表格的硬规则 (中文宋体小四 / 英文 Times New Roman / 1.5 倍行距等)
- `templates/` —— 三类基金的章节级 md 框架 (major_project / nsfc_joint_fund / key_rd)
- `scripts/render_docx.py` —— 按基金类型把 sections/*.md 渲染成 .docx,带正确字体/行距/页眉
- `scripts/word_count.py` —— 章节字数核算,对照 `fund_types.md` 的预算
- `scripts/quality_check.py` —— 申报书验收 (结构完整 / 字数合规 / 引文真实性提示)
## 两阶段工作流
下面所有路径都相对 **`<skill_dir>`** —— `load_skill` 返回头里的 `[skill=proposal, dir=<绝对路径>]`,用这个绝对路径拼脚本/资源,不要假设 cwd。
### 阶段一: 策略 (Strategist) — 八条对齐
- `<skill_dir>/references/fund_types.md` —— 6 类基金的章节骨架 + 字数预算 + 必填表格 (always read)
- `<skill_dir>/references/review_redlines.md` —— 评审雷区与不可考核词清单
- `<skill_dir>/references/citation_gbt7714.md` —— GB/T 7714 顺序编码制 + 文献真实性铁律
- `<skill_dir>/references/budget_rules.md` —— 间接费用台阶 + B1-B4 表
- `<skill_dir>/templates/spec_lock.md` —— 阶段一八条对齐的固定字段模板 (复制到 `<task_dir>/spec_lock.md`)
- `<skill_dir>/templates/{key_rd,major_project,nsfc_joint_fund}.md` —— **有完整章节模板**的 3 类基金;其它 4 类 (`nsfc_general` / `nsfc_youth` / `provincial` / `enterprise`) 复用 `nsfc_joint_fund``key_rd` 骨架,差异看 `fund_types.md` § 4-6
- `<skill_dir>/scripts/render_docx.py` —— md→docx,自动加目录、解析 `**bold**`/`*italic*`/`` `code` ``、列表分行
- `<skill_dir>/scripts/word_count.py` —— 章节字数 vs 预算
- `<skill_dir>/scripts/quality_check.py` —— 结构完整性 / 假大空话术 / 占位符未替换 / 指南覆盖度 (--spec 选项)
产物: `spec_lock.md` (申报书"宪法",阶段二每章前都要重读)。
## 阶段零: 摄取素材 (有 PDF/DOCX/XLSX/URL 时才走)
**先读 `references/fund_types.md` 确认基金类型**,因为大纲、字数、必填表格各不相同。然后按下表给用户预览,⛔ **BLOCKING:用户确认/修改后才能进阶段二**
| # | 项 | 默认/示例 |
|---|----|---------|
| 1 | 基金类型 | 必须明确,例: `key_rd` 国家重点研发计划 / `major_project` 国家科技重大专项 / `nsfc_joint_fund` NSFC 联合基金重点支持 / `nsfc_general` 国自然面上 / `nsfc_youth` 国自然青年 / `provincial` 省基金 / `enterprise` 横向 |
| 2 | 指南方向 | 严格对照指南文本填,**一字不改**。无指南的(青年项目)填研究方向 |
| 3 | 关键科学/技术问题 | 1-2 个,与指南对齐;**问题不是任务**(任务是研究内容) |
| 4 | 创新点 | 3 条以内,每条 ≤500 字。**小而尖**,带方法/理论/知识产权特征 |
| 5 | 研究内容骨架 | 5-8 个研究模块,与课题分解一致 (重点研发要分课题) |
| 6 | 申报/牵头单位 + 团队 | 含主要参与单位,主要负责人 (无具体人选填占位符 `<TODO>`) |
| 7 | 考核指标 | 量化、可考核、与指南完全覆盖。形式: 软件 N 个 / 平台 N 个 / 专利 N 项 / 标准 N 项 / 论文 N 篇 |
| 8 | 经费预算量级 | 总额 + 中央财政 + 自筹 + 其他渠道。看 `budget_rules.md` 的间接费用上限 |
**spec_lock 写定后不再改**。如阶段二发现冲突,回头重新对齐。
### 阶段二: 执行 (Executor) — 逐章节起草
每章前 **必须 read 一次 `spec_lock.md` + `references/section_templates.md` 中本章的写作骨架**,只用 spec_lock 已固化的内容,不允许凭记忆或临时发挥写新指标/单位/数据。
每章流程:
1. 读 `spec_lock.md``references/fund_types.md` 拿本章的字数预算与必填要素
2. 读 `references/section_templates.md` 拿本章的写作骨架
3. 起草成 `sections/NN_xxx.md` —— 一次只写一章
4. 报告: 章节名 / 实际字数 / 字数预算 / 与指南对齐情况
5. 用户确认/微调后再下一章
**为什么逐章?** 申报书 1.5-3 万字,一次出全文中途调方向就要重写。逐章可以在第 2 章就发现问题。
**例外**: 用户明确说"别问,直接全做"——一次跑完,但跑完必须用 `quality_check.py` 验收。
### 阶段三: 验收 + 渲染
用户给指南 PDF / 团队介绍 DOCX / 预算 XLSX / 政策网页 URL → 先转成 `<task_dir>/source/<name>.md`,后续阶段一才能读。统一用 `markitdown` CLI,表格 / 列表 / 标题层级会自动保留:
```bash
python skills/proposal/scripts/word_count.py <task_dir>/sections/ --spec <task_dir>/spec_lock.md
python skills/proposal/scripts/quality_check.py <task_dir>/sections/ --fund-type key_rd
python skills/proposal/scripts/render_docx.py <task_dir>/sections/ --fund-type key_rd -o <task_dir>/<topic>.docx
markitdown <path>/guide.pdf -o <task_dir>/source/guide.md
markitdown <path>/team.docx -o <task_dir>/source/team.md
markitdown <path>/budget.xlsx -o <task_dir>/source/budget.md
markitdown https://example.com/x -o <task_dir>/source/policy.md
```
不通过的项,回头 edit 对应章节
转完后 spec_lock 阶段直接 `read <task_dir>/source/*.md` 拿事实,不要凭印象写。
## 工作目录约定
## 阶段一: 八条对齐
产物 `<task_dir>/spec_lock.md` —— 申报书"宪法",阶段二每章前都要重读。
1. **复制模板**: `read <skill_dir>/templates/spec_lock.md``write <task_dir>/spec_lock.md`
2. **先读 `<skill_dir>/references/fund_types.md` 选基金类型**(章节、字数、表格各不相同)
3. 按 spec_lock.md 字段填,给用户预览
4. ⛔ **BLOCKING:用户确认后才进阶段二**
字段清单见 `<skill_dir>/templates/spec_lock.md` (基金类型 / 指南方向 / 关键科学技术问题 / 创新点 / 研究内容骨架 / 团队 / 考核指标矩阵 / 经费预算 / TODO 列表)。
## 阶段二: 逐章起草
每章两段式:**先列要点 → 用户确认 → 再起草 → 用户确认**。不要直接出正文。
**A. 起草前列要点** (改要点比改正文便宜):
1. 读 `<task_dir>/spec_lock.md``<skill_dir>/references/fund_types.md`,拿本章字数预算与必填要素
2. 列出 3-6 条要点骨架: 本章打算覆盖的论点 / 数据 / 表格,每条贴上对齐的指南要素与预估字数
3. ⛔ **BLOCKING:用户确认要点 (改 / 加 / 删) 后才动正文**
**B. 正文起草**:
4. 复制 `<skill_dir>/templates/<fund_type>.md` 对应小节到 `<task_dir>/sections/NN_xxx.md`,按要点填
5. **关键章节一段一卡** —— 立项依据 / 研究方案 / 技术路线 / 考核指标矩阵: 写一段 → 报字数 + **预告下一段** → 等用户确认 → 写下一段
普通章节一节一卡: 整节写完再报 + **预告下一节要点**
6. 报告格式 (每次卡点都按这个出):
- **本段 (节)**: 章节名 / 实际字数 / 字数预算 / 与指南对齐情况
- **下一段 (节) 预告**: 标题 + 3-5 条要点骨架 (论点 / 数据 / 表格,每条贴对齐的指南要素与预估字数);若已是本章最后一段,改预告**下一章**首段要点
- 提问: "本段可以了吗?下一段要点要改 / 加 / 删什么?"
7. ⛔ **BLOCKING:停下来等用户明确反馈** ("OK"、"下一段"、"继续") 后才动笔。"看起来不错"、沉默、追问都不算确认 —— 用户对下一段要点没异议也算默认通过,但**字数 / 与指南对齐异常**时必须主动追问
**为什么两段式 + 强等 + 下一段预告?** 申报书 1.5-3 万字,模型连续生成容易自我加速、把错方向推到底。要点阶段拦得早,关键章节段段卡可以在第 2 段被用户拦下。**预告下一段要点**让用户在下一段还没动笔时就能改方向 —— 比读完正文再返工成本低一个量级。
**例外**: 用户**主动且明确**说"别问,直接全做"或"一气呵成" —— 才能一次跑完,跑完必须 `quality_check.py`。"逐章太慢"/"段段太碎"之类的抱怨**不算**例外指令,继续问。
## 阶段三: 验收 + 渲染
```bash
python <skill_dir>/scripts/word_count.py <task_dir>/sections/ --fund-type key_rd
python <skill_dir>/scripts/quality_check.py <task_dir>/sections/ --fund-type key_rd --spec <task_dir>/spec_lock.md
python <skill_dir>/scripts/render_docx.py <task_dir>/sections/ --fund-type key_rd -o <task_dir>/<topic>.docx
```
`--spec` 让质量检查交叉对照 spec_lock,提示哪些指南考核指标在 sections 里没出现。不通过的项,回头 edit 对应章节。
## 工作目录
`<task_dir>` = system prompt 给的**绝对路径**(`…/workspace/tasks/<task_id>/`)。**所有产物都写到 task_dir 下**,不要写到 cwd / `skills/` / repo 根。
```
<task_dir>/
├── source/ # 用户给的素材 (指南 PDF / 前期成果 / 团队介绍)
├── spec_lock.md # 阶段一定调
├── sections/ # 阶段二逐章产物
│ ├── 00_basic_info.md # 基本信息表 (基金类型决定填什么字段)
│ ├── 01_summary.md # 项目简介 (重点研发 1500 字 / 国自然 800 字)
│ ├── 02_background.md # 立项依据 / 国内外现状
│ ├── 03_objectives.md # 研究目标与考核指标
│ ├── 04_content.md # 研究内容
│ ├── 05_method.md # 研究方法与技术路线
│ ├── 06_innovation.md # 创新点
│ ├── 07_basis.md # 研究基础与团队
│ ├── 08_schedule.md # 进度安排 / 年度计划 / 里程碑
│ ├── 09_organization.md # 组织实施与保障 (重点研发/重大专项必填)
│ ├── 10_ip_risk.md # 知识产权与风险分析
│ ├── 11_budget.md # 经费预算
│ └── 12_appendix.md # 附件清单
└── <topic>.docx # 最终产物 (按课题命名,不要 output.docx)
├── source/ # 用户给的素材 (指南 PDF / 前期成果)
├── spec_lock.md # 阶段一定调
├── sections/ # 阶段二逐章产物 (按 templates/<fund_type>.md 切的小节命名)
└── <topic>.docx # 最终产物 (按课题命名,不要 output.docx)
```
## 硬规则速查 (违反即扣分项)
## 章节骨架速查
- **字体**: 标题黑体四号; 正文中文**宋体小四**; 英文/数字 **Times New Roman 小四**; 行距 **1.5 倍**;`typography.md` 起手代码强制
- **指南对齐**: 项目名称 / 指南方向 / 创新分类 / 考核指标必须**字面对齐**指南文本,不得自己改写。要么写"完全相关",要么"完全相关并超出"
- **不降低指标**: 任务书填报内容**不得低于**申报指南和申报书,只能持平或加码
- **量化考核**: 每条考核指标必须可测量、可验收。"显著提升性能"❌;"实现 10000 TPS 以上吞吐量、秒级响应"✅
- **真实文献**: 不可编造作者、年份、期刊、DOI。需要引用先告诉用户来源,让用户提供文献清单
- **经费比例**: 间接费用按 `budget_rules.md` 的台阶 (≤500 万部分 ≤30% / 500-1000 万 ≤25% / >1000 万 ≤20%)
- **限项检查**: 在研重点研发/重大专项/农业关键核心技术 ≤2 项;同年同人不重复申请
- **不堆形容词**: "首次提出""填补空白""国际领先"一律不用,除非用户明确要这种话术
- **逻辑先行**:
- 立项依据 = 现状(国内外格局) → 痛点(具体到指标差距) → 本项目切入点(为什么是我们)
- 研究方案 = 总体目标 → 任务分解 → 关键技术路线 → 可行性论证
写每章前在脑子里过一遍这 4 个 pattern:
- **立项依据三段式**: 现状 (国内外格局,40%) → 痛点 (具体到指标差距,30%) → 切入点 (本项目为什么是我们,30%)
- **研究方案四要素**: 总体目标 → 任务分解 → 关键技术路线 → 可行性论证
- **创新点三特征**: 基本形态 (新方法/模型/机制) + 前沿性 (与 SOTA 比) + 知识产权特征 (专利/标准/论文)
- **考核指标矩阵**: 指南指标(字面抄) → 本项目指标(可超出不能低于) → 立项时已有值 → 完成时值 → 考核方式(CNAS/CMA / 测试大纲专家评审 / 应用示范报告)
边界 (最容易混):
- 立项依据回答 **WHY** (背景+痛点) | 研究目标回答 **WHAT 终态** (量化指标) | 研究内容回答 **WHAT 任务** (技术清单) | 研究方法回答 **HOW 原理** (算法/模型) | 技术路线回答 **HOW 流程** (输入→处理→输出)
## 硬规则速查 (违反即扣分)
- **字体**: 标题黑体四号; 正文中文宋体小四 / 英文 Times New Roman; 行距 1.5 倍 —— `render_docx.py` 已强制
- **指南对齐**: 项目名称 / 方向 / 创新分类 / 考核指标**字面对齐**指南文本,不得改写
- **不降低指标**: 任务书内容**不得低于**申报指南和申报书,只能持平或加码
- **量化考核**: "显著提升性能"❌ ;"10000 TPS、秒级响应"✅
- **真实文献**: 不可编造作者/期刊/DOI;需要引用先要用户提供清单,详见 `citation_gbt7714.md`
- **经费比例**: 间接费用 ≤500 万部分 ≤30% / 500-1000 万 ≤25% / >1000 万 ≤20%
- **限项**: 在研重点研发/重大专项/农业核心技术 ≤2 项;同年同人不重复申请
- **不堆形容词**: "首次提出""填补空白""国际领先"一律不用,除非用户明确要
## 反模式
- 用户没给基金类型 / 课题方向就开始硬编正文 (一定要先 spec_lock)
- 一次性出全文 (1.5-3 万字,中途改向就全推翻)
- **基于"通用模板"自行套基金类型** —— 重大专项任务书与国自然申请书结构完全不同,**先去 `fund_types.md` 查清楚**再写
- **自己造数据/指标/单位/经费** —— 不知道就在 spec_lock 里写 `<TODO 待用户提供>`,不要硬编一个
- 引文里写 "[Smith et al., 2023]" 但其实没这篇文献
- 未 spec_lock 就开始硬编正文
- 一次性出全文 (中途改向就全推翻)
- 跳过"列要点"直接写正文 —— 即使只有一章也要先列要点过一遍
- 关键章节 (立项依据 / 研究方案 / 技术路线 / 考核指标) 整章一次出 —— 必须段段卡
- **基于"通用模板"自行套基金类型** —— 重大专项任务书与国自然申请书结构完全不同,**先查 `fund_types.md`**
- **自己造数据/指标/单位/经费** —— 不知道就 `<TODO 待用户提供>`,不要硬编
- 引文写"[Smith et al., 2023]" 但其实没这篇文献
- 不跑 `quality_check.py` 就交付
- 文件名 `output.docx` / `申报书.docx` —— 务必按主题给具体名
- 文件名 `output.docx` / `申报书.docx` —— 按主题命
## 输出
@ -118,5 +131,4 @@ python skills/proposal/scripts/render_docx.py <task_dir>/sections/ --fund-type k
- 文件路径
- 各章节字数 vs 预算
- 与指南考核指标的逐项对齐表
- 引文清单 (明确哪些是用户提供、哪些待补)
- 仍需用户填写的 `<TODO>` 项清单
- `<TODO>` 待补项清单

View File

@ -1,172 +1,104 @@
# 经费预算规则
来自《国务院办公厅关于改革完善中央财政科研经费管理等若干意见》(国办发202132 号)、国家科技重大专项资金管理办法、NSFC 资金管理办法。
---
来自国办发202132 号、国家科技重大专项资金管理办法、NSFC 资金管理办法。
## 1. 经费结构
```
总预算
├── 中央财政专项资金 (国拨)
├── 中央财政专项资金
│ ├── 直接费用
│ │ ├── 设备费 (购置 / 试制)
│ │ ├── 业务费 (材料/测试加工/燃料动力/差旅/会议/国际合作/出版/咨询/印刷/专家咨询)
│ │ └── 劳务费 (临时聘用人员、研究生、博士后)
│ │ ├── 业务费 (材料/测试/燃料动力/差旅/会议/国际合作/出版/咨询/印刷/专家咨询)
│ │ └── 劳务费 (临时聘用 / 研究生 / 博士后)
│ └── 间接费用 (含绩效支出)
└── 其他来源资金
├── 地方财政资金
├── 单位自筹资金
└── 其他渠道获得资金
└── 其他来源资金 (地方财政 / 单位自筹 / 其他渠道)
```
---
## 2. 间接费用比例 (硬上限)
按"分段超额累退"计算,**重大专项 / 重点研发**适用:
按"分段超额累退",**重点研发 / 重大专项**适用:
| 直接费用扣除设备购置费后金额 | 间接费用上限比例 |
| 直接费用扣除设备购置费后金额 | 间接费用上限 |
|----|----|
| ≤ 500 万元部分 | 不超过 **30%** |
| > 500 万元 ~ 1000 万元部分 | 不超过 **25%** |
| > 1000 万元部分 | 不超过 **20%** |
| ≤ 500 万元部分 | 30% |
| > 500 - 1000 万元部分 | 25% |
| > 1000 万元部分 | 20% |
**绩效支出** (在间接费用中) **无比例限制**, 与科研贡献挂钩。
绩效支出 (在间接费用中) 无比例限制,但与科研贡献挂钩。NSFC 项目按管理办法另定 (通常 30%)。
NSFC 项目按各类项目管理办法另定 (面上 / 重点 / 重大 / 联合基金,通常 30%)。
### 计算示例
直接费用 1500 万元, 其中设备购置费 300 万元 → 计算基数 = 1500 - 300 = 1200 万元
间接费用上限 = 500×30% + 500×25% + 200×20% = 150 + 125 + 40 = **315 万元**
---
**示例**: 直接费用 1500 万,设备购置 300 万 → 计算基数 1200 万。间接上限 = 500×30% + 500×25% + 200×20% = 315 万。
## 3. 设备费
### 购置 vs 试制
- **购置**: 50 万以上的现成设备, 必须填 B3 表明细 (设备名称 / 分类 / 功能技术指标 / 单价 / 数量 / 金额 / 购置或试制单位 / 安置单位 / 通用or专用 / 主要厂家及国别 / 规格型号 / 拟开放共享范围)
- **试制**: 自研设备, B3 表 (9)(10)(11)(12) 列免填
- 购置 / 试制 两类。50 万以上的购置必须填 B3 表 (型号/功能/技术指标/厂家/共享范围)
- 试制设备 B3 表 (9)(10)(11)(12) 列免填
- 通用类 (服务器/PC/打印机) **不允许**用项目经费购置 (单位日常经费)
- 大型科研设备**必须开放共享**
- 占比建议: 应用示范 30-50%, 基础研究 15-30%, 超 60% 评审会质疑
### 红线
- 单价 50 万以下的设备**不需要**单独明细
- 同种设备多台合并为一行
- 通用类设备 (服务器/PC/打印机) **不允许**用项目经费购置 (这是日常办公经费,各单位自理)
- 大型科研设备 **必须开放共享** (拟开放共享范围栏要写"本单位 / 行业 / 全国")
## 4. 业务费子科目
### 占比建议
- 应用示范类: 设备费占比 30-50% 合理
- 基础研究类: 设备费占比 15-30% 合理
- 设备费占比 > 60% — 评审会质疑研究成分,补强其他费用必要性说明
材料 / 测试化验加工 / 燃料动力 / 差旅会议国际合作 / 出版文献版面知识产权 / 专家咨询 / 其他。
---
## 4. 业务费
### 子科目
- **材料费**: 试剂、耗材、低值易耗品
- **测试化验加工费**: 第三方测试、样品加工
- **燃料动力费**: 电、气、特殊试验场地能耗
- **差旅/会议/国际合作交流费**: 项目相关出差与国内外学术交流
- **出版/文献/信息传播/知识产权事务费**: 论文发表、专利申请、文献检索、版面费、专著出版
- **专家咨询费**: 评审专家、技术咨询;**不得**支付给参与本项目的人员
- **其他**: 上述都不属的合理支出
### 红线
- 专家咨询费支付**临时邀请的外部专家**,不能给项目组成员
- 国际合作交流费需配套出访计划
- 单笔大额会议费 (>50 万) 需说明会议名称、规模、人次
---
红线: 专家咨询费**不能**给项目组成员;招待费严禁;单笔大额会议 (>50 万) 需说明规模人次。
## 5. 劳务费
### 谁能拿
- **临时聘用人员** (不是本单位编制内职工)
- **在读研究生** (硕士、博士)
- **博士后**
- 项目承担单位**编制外**的研究助理
谁能拿: 临时聘用 / 在读研究生 / 博士后 / 编制外研究助理。
谁不能拿: 编制内人员 (走绩效支出) / 项目负责人本人。
### 谁不能拿
- 编制内的高级职称 / 中级职称研究人员 (他们的工资由单位编制内经费保障, 个人激励走绩效支出)
- 项目负责人本人
标准: 当地人均可支配收入 1-3 倍 (北京硕士 4-7k/月, 博士 6-10k/月)。单人单月超 1.5 万会被质疑。
### 标准
- 每月按当地人均可支配收入 1-3 倍 (例: 北京硕士生 4000-7000/月, 博士生 6000-10000/月)
- 总额无硬上限, 但单人单月超过 1.5 万会被质疑
## 6. 自筹 / 配套
---
- 自筹必须有出资单位**承诺函**(公章 + 法人签字)
- 配套比例: 重大专项 / 重点研发应用示范类要求企业配套 ≥ 1:1 ; NSFC 一般无;省基金部分要求 1:0.5
## 6. 自筹资金 / 配套
## 7. 预算说明 (1000 字以内) 三性必涵盖
- 自筹必须有**出资单位承诺函** (公章 + 法人签字)
- 自筹来源分: 地方财政资金 / 单位自筹资金 / 其他渠道
- 配套比例: 不同基金不同
- 重大专项 / 重点研发应用示范类: **要求企业配套 ≥ 1:1**
- NSFC 一般无配套要求
- 部分省基金要求 **1:0.5**
- 配套资金主要用于: 工程建设、设备购置、试点示范
---
## 7. 经费预算说明 (1000 字以内)
必须涵盖**三性**:
- **任务相关性**: 每笔大额支出对应哪项研究任务
- **政策相符性**: 符合资金管理办法 (例: 间接费用比例正确, 不挪用)
- **经济合理性**: 不虚高、不超出市场价
- **政策相符性**: 间接费用比例正确, 不挪用
- **经济合理性**: 不虚高, 不超市场价
模板:
```
一、中央财政资金
本课题中央财政专项资金合计 XXX 万元, 其中:
(一) 直接费用 XXX 万元
1. 设备费 XX 万元
购置 XX 万元: 用于购置 [具体设备 1] (XX 万元) [具体设备 2] (XX 万元) 等, 支撑 XX 研究任务。
试制 XX 万元: 用于试制 [具体装置], 支撑 XX 应用示范。
2. 业务费 XX 万元
按子科目进一步说明。
3. 劳务费 XX 万元
预计聘用研究助理 X 名 + 博士生 X 名 + 硕士生 X 名,合计 XX 人月。
购置 XX 万元: [设备 1] (XX 万) + [设备 2] (XX 万),支撑 XX 任务。
试制 XX 万元: 试制 [装置],支撑 XX 应用示范。
2. 业务费 XX 万元: <按子科目>
3. 劳务费 XX 万元: 研究助理 X 名 + 博士生 X + 硕士生 X,合计 XX 人月。
(二) 间接费用 XX 万元
按 (一) 直接费用扣除设备购置费后 XX 万元的台阶比例计算:
500×30% + ... = XX 万元。
其中绩效支出 XX 万元, 用于激励课题骨干。
按 (一) 扣除设备购置费后 XX 万元的台阶比例: 500×30% + ... = XX 万元。
绩效支出 XX 万元 用于激励课题骨干。
二、其他来源资金 XXX 万元
单位自筹 XX 万元, 用于 [设备购置 / 试点示范工程], 出资承诺函见附件 X。
单位自筹 XX 万元,用于 [设备购置 / 试点示范],承诺函见附件 X。
```
---
## 8. 各档基金的经费量级 (参考)
## 8. 各档基金量级
| 基金 | 单项资助 | 周期 | 备注 |
|----|----|----|------|
| NSFC 青年科学基金 (C) | 30 万 | 3 年 | 无配套 |
| NSFC 面上项目 | 50-60 万 | 4 年 | 无配套 |
| NSFC 重点项目 | 280-330 万 | 5 年 | 无配套 |
| NSFC 联合基金重点支持 | 200-260 万 | 4 年 | 无配套 |
| 重点研发计划重点专项 | 1000-5000 万 | 3-5 年 | 应用示范类要求企业配套 ≥1:1 |
| 国家科技重大专项课题 | 800-3000 万 | 3-5 年 | 通常要求配套 |
| NSFC 青年 (C) | 30 万 | 3 年 | 无配套 |
| NSFC 面上 | 50-60 万 | 4 年 | 无配套 |
| NSFC 重点 | 280-330 万 | 5 年 | 无配套 |
| NSFC 联合基金重点 | 200-260 万 | 4 年 | 无配套 |
| 重点研发重点专项 | 1000-5000 万 | 3-5 年 | 应用示范类 ≥1:1 配套 |
| 重大专项课题 | 800-3000 万 | 3-5 年 | 通常要求配套 |
| 省自然科学基金 | 5-30 万 | 3 年 | 多数无配套 |
| 省重点研发计划 | 50-300 万 | 2-3 年 | 部分要求配套 |
| 横向合同 | 看甲方需求 | 看合同 | 不算资助,算合同 |
| 省重点研发 | 50-300 万 | 2-3 年 | 部分要求配套 |
---
## 9. 常见预算错误
## 9. 常见错误
| 错误 | 后果 |
|----|----|
| 间接费用按总直接费用算,没扣设备购置费 | 超比例,退回修改 |
| 间接费用按总直接费用算,没扣设备购置费 | 超比例,退回 |
| 50 万以上设备没在 B3 明细 | 形式审查不过 |
| 劳务费支付给项目骨干 | 违规 |
| 业务费写"招待费" | 财政严禁,直接退回 |
| 总预算与指南要求量级不匹配 | 评审质疑 |
| 自筹资金没承诺函 | 视为无配套 |
| 劳务费给项目骨干 | 违规 |
| 业务费写"招待费" | 财政严禁 |
| 总预算与指南资助量级不匹配 | 评审质疑 |
| 自筹承诺函 | 视为无配套 |
| B2/B3/B4 表数字对不上 | 形式审查不过 |
| 预算说明只有数字, 没有"任务相关性" 说明 | 退回补充 |
| 预算说明缺三性论证 | 退回补充 |

View File

@ -1,129 +1,68 @@
# 文献规范 (GB/T 7714-2015 顺序编码制)
科研申报书统一用**顺序编码制**: 文中按出现顺序 [1][2][3]...,文末参考文献按编号顺序排列。
科研申报书统一用顺序编码制: 文中按出现顺序 [1][2][3]...,文末参考文献按编号顺序排列。
## 真实性铁律
- ❌ **不可编造**作者、年份、期刊、卷期、页码、DOI
- ❌ **不可凭印象**写"Smith 2020 提到过 ..." — 凭印象大概率错
- ✅ 需要引用,**先告诉用户**:"立项依据这一段需要 5 篇关于 XX 的文献,请提供清单或我先用占位符 [REF-XX] 标注"
- ✅ 如果用户提供文献清单 (BibTeX/EndNote/纯文本均可),按下文模板**只做排版**
- ❌ **不可编造**作者 / 年份 / 期刊 / 卷期 / 页码 / DOI
- ❌ **不可凭印象**写"Smith 2020 提到过 ..." — 大概率错
- ✅ 需要引用先告知用户:"立项依据这一段需要 5 篇关于 XX 的文献,请提供清单或我先用占位符 [REF-XX] 标注"
- ✅ 用户给 BibTeX / EndNote / 纯文本均可,你只**排版**
## 引文格式 (文中)
放在**句末标点之前**,上标或方括号:
```
碳市场带来更高的透明度、可访问性、流动性和标准化 [1]。
碳市场带来更高的透明度和标准化 [1]。
Hu 等 [2] 提出了基于账户分片的高性能跨分片共识。
(Hu, 2022) ❌ 不要用 APA — 国内基金统一 GB/T 7714
```
多篇引用合并:
❌ 不要 APA: `(Smith, 2020)`
多篇:
```
[1-3] 连续: 1, 2, 3
[1-3] 连续
[1, 3, 5] 非连续
```
## 参考文献格式 (文末)
### 期刊论文 (J)
```
[1] 沈哲鑫. 基于区块链的碳抵消研究综述与展望[J]. 中国商论, 2022(04): 112-115.
[2] Huang H, Peng X, Zhan J, et al. BrokerChain: A Cross-Shard Blockchain Protocol[J]. IEEE Transactions on Parallel and Distributed Systems, 2024, 35(2): 287-302.
```
字段顺序: 作者. 题名[类型代码]. 出版信息. 中文用全角符号,英文用半角;3 位以上作者列前 3 位 + ", et al." (英文) 或 ", 等." (中文);期刊名用**全称**。
字段顺序: 作者. 题名[J]. 刊名, 年(期): 起止页码.
- 3 位以上作者只列前 3 位 + ", et al." (英文) 或 ", 等." (中文)
- 中文用全角符号,英文用半角
- 期刊名用**全称** (不要缩写)
| 类型 | 格式 |
|-----|------|
| 期刊 J | `[1] 沈哲鑫. 基于区块链的碳抵消研究综述与展望[J]. 中国商论, 2022(04): 112-115.` |
| 会议 C | `[3] Wang J, Wang H. Monoxide: Scale Out Blockchains[C]//Proc. of NSDI 2019. Boston: USENIX, 2019: 95-112.` |
| 学位 D | `[4] 俞光华. 面向蜂窝物联网的低成本大规模接入设计[D]. 杭州: 浙江大学, 2020.` |
| 专著 M | `[5] 陈志祥. 电力企业碳资产管理[M]. 北京: 中国电力出版社, 2020: 45-67.` |
| 专利 P | `[6] 朱绍康, 等. 基于区块链的碳交易数据处理方法及系统: CN202110123456.7[P]. 2021-08-15.` |
| 标准 S | `[7] 国家能源局. 发电企业碳排放权交易技术指南: GB/T XXXXX—2024[S]. 北京: 中国标准出版社, 2024.` |
| 网络 EB/OL | `[8] NSFC. 关于 2026 年度...[EB/OL]. (2025-12-15)[2026-01-20]. https://www.nsfc.gov.cn/...` |
### 会议论文 (C)
```
[3] Wang J, Wang H. Monoxide: Scale Out Blockchains with Asynchronous Consensus Zones[C]//Proc. of NSDI 2019. Boston: USENIX, 2019: 95-112.
```
### 学位论文 (D)
```
[4] 俞光华. 面向蜂窝物联网的低成本大规模接入设计[D]. 杭州: 浙江大学, 2020.
```
### 专著 (M)
```
[5] 陈志祥. 电力企业碳资产管理[M]. 北京: 中国电力出版社, 2020: 45-67.
```
### 专利 (P)
```
[6] 朱绍康, 汤鹏, 王志祥. 基于区块链的碳交易数据处理方法及系统: CN202110123456.7[P]. 2021-08-15.
```
### 标准 (S)
```
[7] 国家能源局. 发电企业碳排放权交易技术指南: GB/T XXXXX—2024[S]. 北京: 中国标准出版社, 2024.
```
### 网络资源 (EB/OL)
```
[8] 国家自然科学基金委员会. 关于 2026 年度国家自然科学基金项目申请与结题等有关事项的通告[EB/OL]. (2025-12-15)[2026-01-20]. https://www.nsfc.gov.cn/p1/3381/2824/99667.html.
```
### 数据集 (DS)
```
[9] National Centers for Environmental Information. Global Surface Temperature Anomalies[DS/OL]. NOAA, 2024. https://www.ncei.noaa.gov/...
```
## 参考文献文献类型代码 (常用)
| 代码 | 类型 |
|----|------|
| J | 期刊 |
| M | 专著 |
| C | 会议论文集 |
| D | 学位论文 |
| R | 报告 |
| P | 专利 |
| S | 标准 |
| EB | 电子公告 |
| DS | 数据集 |
| OL | 联机网络 |
类型代码: J 期刊 / M 专著 / C 会议 / D 学位 / R 报告 / P 专利 / S 标准 / EB 电子公告 / DS 数据集 / OL 联机网络。
## 写作流程
1. 先写正文,引用处放占位符 `[REF-NN]` 或具体作者名 `[Hu et al. 2024]`
2. 写完后整理参考文献清单,问用户索取真实文献
3. 用户给 BibTeX / EndNote / 纯文本均可
4. 替换占位符为 `[1][2][3]...` (按文中**首次出现顺序**编号,不是按字母顺序)
5. 按 GB/T 7714 重排参考文献清单
1. 写正文,引用处放占位符 `[REF-NN]` 或具体作者名 `[Hu et al. 2024]`
2. 写完后整理引用清单,问用户索取真实文献
3. 替换占位符为 `[1][2][3]...` (按文中**首次出现顺序**编号)
4. 按 GB/T 7714 重排参考文献清单
## 引文密度建议
## 引文密度
| 章节 | 推荐引文数 |
| 章节 | 推荐数 |
|----|---------|
| 立项依据 / 国内外现状 | 10-30 |
| 研究内容 / 方法 | 5-10 (引用关键算法/方法的原始文献) |
| 创新点 | 3-5 (对比 SOTA) |
| 其他章节 | 0-3 |
| 研究内容 / 方法 | 5-10 |
| 创新点 (对比 SOTA) | 3-5 |
| 其他 | 0-3 |
引文密度过低 → 文献调研不足
引文密度过高 → 综述化, 削弱创新性
## 国内外平衡
立项依据"国内外现状"部分,国外文献和国内文献**比例 6:4 ~ 4:6**,不能一边倒:
- 全英文 → 中国学者贡献被忽视
- 全中文 → 国际视野不够
立项依据国外文献 / 国内文献 **比例 6:4 ~ 4:6**,不能一边倒。
## 常见错误
| 错误 | 改正 |
|----|------|
| `(Smith, 2020)` APA 风格 | `[1]` 顺序编码制 |
| 期刊名缩写 `Nat. Energy` | 全称 `Nature Energy` |
| 缺页码 | 必须有 (期刊 / 专著章节) |
| 缺出版地 | 专著、会议论文集必须有 |
| 中英作者格式混用 | 中文用全角 `,`,英文用半角 `,` |
| 中文文献引述方式: `张三在文献[1]中提出` | 应改为 `张三 [1] 提出 ...` |
| `[Smith et al., 2023]` 文中 + 文末没有 Smith 2023 | 必须严格对应 |
- APA `(Smith, 2020)` → GB/T 7714 `[1]`
- 期刊名缩写 `Nat. Energy` → 全称 `Nature Energy`
- 缺页码 / 缺出版地
- 中英作者格式混用 (中文全角逗号, 英文半角)
- "张三在文献[1]中提出" → "张三 [1] 提出..."
- 文中引用了 [Smith 2023] 但文末参考文献没有这条

View File

@ -1,209 +1,120 @@
# 基金类型 cheat sheet
每种基金的章节、字数、表格、特殊要求都不同。**写之前必须先确定类型**,然后照抄本文档对应小节的章节大纲到 `spec_lock.md`
> 字数预算来自三份真实模板 (重大专项任务书 2025、NSFC 联合基金 2026 版、国家重点研发"区块链"专项申报书),少量来自管理办法与近年指南。指南每年微调,以**当年指南文件**为准——本表是骨架,不是法律条文。
每种基金的章节、字数、表格、特殊要求都不同。**写之前必须先确认类型**,然后照抄本文档对应小节的章节大纲到 `spec_lock.md`。字数预算来自 3 份真实模板 (重大专项任务书 2025 / NSFC 联合基金 2026 / 重点研发"区块链") + 当年指南文件 — 指南每年微调,**以当年指南为准**。
---
## 1. 国家重点研发计划 (`key_rd`)
**典型场景**: 重点专项、青年科学家项目、应急攻关、揭榜挂帅。
**正文字数**: 约 1.8-2.5 万字 (不含附件、人员表、预算表)。
### 必备结构 (8 个部分)
适用: 重点专项 / 青年科学家 / 应急攻关 / 揭榜挂帅。**正文 1.8-2.5 万字**。
```
项目基本信息表
申报项目简介 ── 限 1500 字
一、研究背景
二、研究目标
三、研究内容
四、技术路线
五、创新点
六、研究基础和团队
七、预期成果和效益
申报项目简介 ── 1500
一~七、研究背景/目标/内容/技术路线/创新点/团队/预期成果 (申报项目简介展开)
第一部分 国内外现状及趋势分析 ── 限 2000 字
+ 国外代表性 5 家机构表 + 国内代表性 5 家机构表 + 项目相关 5 项代表成果/专利/标准表
第一部分 国内外现状及趋势分析 ── 2000 + 国外/国内 5 家机构表 + 5 项代表成果表
第二部分 研究目标及内容
一、项目目标及考核指标
(一) 申报项目所属指南方向的关联关系 ── 1500
(二) 项目目标及考核指标、考核方式/方法 ── 2000 (不含表)
(三) 项目预期成果的呈现形式及描述 ── 限 1000 字
二、项目研究内容、研究方法及技术路线
(一) 项目的主要研究内容 ── 3000
(二) 项目拟采取的研究方法 ── 2000
(三) 项目的技术路线 ── 2000
(一) 与指南方向的关联关系 ── 1500
(二) 项目目标及考核指标、考核方式 ── 2000 (不含表)
(三) 预期成果的呈现形式 ── 1000
二、研究内容、研究方法及技术路线
(一) 主要研究内容 ── 3000
(二) 研究方法 ── 2000
(三) 技术路线 ── 2000
三、课题分解方案
(一) 课题分解情况 ── 2000
(二) 各课题内容 ── 每课题 ≤ 3000
四、主要创新点 ── 每条 ≤ 500
五、预期经济社会效益 ── 1500
(一) 课题分解情况 ── 2000
(二) 各课题内容 ── 每课题 ≤3000
四、主要创新点 ── 每条 ≤500
五、预期经济社会效益 ── 1500
第三部分 申报单位及参与单位研究基础
第三部分 研究基础
一、申报单位的已有工作基础
(一) 牵头单位前期任务承担及综合绩效评价 ── 限 1000 字
(二) 项目及课题负责人科研水平及主要成果 ── 限 2000 字
(三) 牵头单位科研条件支撑 ── 1000
(四) 牵头企业运行状况 (如是企业)
二、参与单位团队的选择原因及优势 ── 1000
三、相关的国际合作与交流 ── 1000
(一) 牵头单位前期任务承担及绩效 ── 1000
(二) 项目及课题负责人科研水平 ── 2000
(三) 牵头单位科研条件支撑 ── 1000
(四) 牵头企业运行状况
二、参与单位团队的选择原因及优势 ── 1000
三、相关的国际合作与交流 ── 1000
第四部分 进度安排 ── 限 2000 字 (鼓励甘特图)
第五部分 项目组织实施、保障措施及风险分析
一、项目组织实施机制 (项目总体组 + 课题技术组 + 项目管理队伍)
二、保障措施
三、知识产权对策、成果管理及合作权益分配
四、风险分析及对策
第六部分 研究团队 (人员表)
第七部分 经费预算 (预算表)
第四部分 进度安排 ── 2000 (鼓励甘特图)
第五部分 组织实施、保障措施及风险分析
第六部分 研究团队 (人员表)
第七部分 经费预算 (预算表)
第八部分 指南所要求的附件
```
### 创新分类 (打勾)
□ 基础研究 □ 技术开发 □ 应用示范 □ 其他类型
**勾选项**:
- 创新分类: □基础研究 □技术开发 □应用示范 □其他
- 实施模式: □青年科学家 □揭榜挂帅 □首席科学家 □滚动支持 □应急攻关 □常规模式
### 项目实施模式 (打勾)
□ 青年科学家 □ 揭榜挂帅 □ 首席科学家 □ 滚动支持 □ 应急攻关 □ 常规模式
### 关键硬约束
- **不得降低**指南考核指标; 研究内容**不得自行调整**,只能进一步细化
- 项目名称应清晰、准确,**不宜宽泛**
- 第一次出现的缩略词,须注明全称
- 每个课题的考核指标必须**逐条覆盖**指南要求,且**写到指标值**(数量+性能)
- 进度安排必须给出**中期目标**和**里程碑节点**
**硬约束**: 不得降低指南考核指标;不得自行调整主要研究内容,可进一步细化;项目名称不宜宽泛;缩略词第一次出现注全称;每个课题考核指标必须**逐条覆盖**指南且**写到指标值**(数量 + 性能);进度安排必须给出**中期目标**和**里程碑节点**。
---
## 2. 国家科技重大专项 — 课题任务书 (`major_project`)
**典型场景**: 项目立项后的课题任务书 (不是申报书阶段);专项编号形式 `2025ZD0XXXXXX`
**正文字数**: 约 1.0-1.5 万字 (相对短,因为大量信息进表格)。
### 必备结构
立项后的**课题任务书**(不是申报书),专项编号 `2025ZD0XXXXXX`。**正文 1.0-1.5 万字** (大量信息进表)。
```
课题基本信息表 (38 行表格) 填编号、密级、单位信息、技术就绪度等
(技术就绪度 9 级:基本原理→技术方案→方案验证→单元验证→分系统验证→
原型验证→现实环境应用验证→用户认可→推广应用)
一、课题目标及考核指标、评测方式/方法
课题目标 (500 字以内/项)
课题目标、成果与考核指标表 (成果名称 / 成果简述 / 成果类型 / 考核指标 / 立项时已有指标值 /
立项时重点国别指标值 / 里程碑节点指标值 / 完成时指标值 / 考核方式)
科技报告考核指标表
课题基本信息表 (38 行表) 技术就绪度 9 级 / 单位信息 / 经费预算
一、课题目标及考核指标、评测方式 目标≤500 + 课题目标成果与考核指标表 + 科技报告考核指标表
二、课题研究内容、研究方法及技术路线
(一) 课题的主要研究内容 ── 3000
(二) 课题采取的研究方法 ── 4000
(一) 主要研究内容 ── 3000
(二) 研究方法 ── 4000
(三) 技术路线 (图)
三、主要创新点 (可选填) 每条 ≤ 500 字
四、预期经济社会效益 ── 限 1000 字
五、课题年度计划
按 6 个月分阶段,每阶段填:任务 / 考核指标 / 成果形式
关键节点、里程碑事件和关键指标 (时间点 / 里程碑事件 / 关键指标 / 考核方式 / 交付物)
六、课题组织实施机制及保障措施
1. 内部组织管理方式、协调机制 ── 限 1000 字
2. 实施相关政策、基础、保障条件 ── 限 1000 字
3. 对项目总目标的支撑作用、与项目内其他课题协同 ── 限 500 字
七、知识产权对策、成果管理及合作权益分配 ── 限 500 字
八、需要约定的其他内容 (条款式,12 条左右)
定型条款: 项目过程管理 / 资金管理责任 / 安全责任 / 学术诚信 / 完全覆盖指南指标 等
三、主要创新点 (可选) ── 每条 ≤500
四、预期经济社会效益 ── 1000
五、课题年度计划 按 6 个月分阶段;关键节点+里程碑事件+关键指标+考核方式+交付物
六、课题组织实施机制及保障措施 (1000+1000+500)
七、知识产权对策 ── 500
八、需要约定的其他内容 12 条款 (前 11 条定型,第 12 条自定)
九、课题参加人员基本情况表
十、经费预算
B1 课题承担单位基本情况表
B2 课题预算表 (中央财政 + 直接费用 [设备/业务/劳务] + 间接费用 + 其他来源 + 合计)
B3 设备费 — 购置/试制设备预算明细表 (单价 50 万以上必填)
B4 课题单位经费预算明细表
预算说明
其他来源资金承诺书
十一、相关附件
1. 乙方与参加单位有关协议 (签章 + 公章)
2. 申报指南规定的其他附件
十、经费预算 B1 单位情况 + B2 预算总表 + B3 设备明细 (50万+) + B4 单位明细
十一、相关附件 乙方与参加单位协议 (盖章扫描)
任务书签署
```
### 成果类型 (17 选)
□新理论 □新原理 □新产品 □新技术 □新方法 □关键部件 □数据库 □软件 □平台
□应用解决方案 □实验装置/系统 □临床指南/规范 □工程工艺 □标准 □论文 □发明专利 □其他
**成果类型 17 选**: 新理论 / 新原理 / 新产品 / 新技术 / 新方法 / 关键部件 / 数据库 / 软件 / 平台 / 应用解决方案 / 实验装置/系统 / 临床指南/规范 / 工程工艺 / 标准 / 论文 / 发明专利 / 其他
### 公开类别及时限
- 公开 / 延期公开
- 论文需延期 → ≤2 年
- 专利/专著需延期 → ≤3 年
- 技术诀窍需延期 → ≤5 年
**公开类别**: 公开 / 延期公开 (论文≤2 年, 专利/专著≤3 年, 技术诀窍≤5 年)
### 关键硬约束
- 中文**宋体小四**,英文/数字**Times New Roman 小四**
- 不填的栏目用"无"标注,**不能空白**
- 课题内容必须**完全覆盖**指南、申报书、立项批复;**不得降低考核指标,不得自行对主要研究内容作大的调整**
- 任务书一式十份,需要乙方与参加单位签盖公章
**TRL 9 级**: 1.基本原理 / 2.技术方案 / 3.方案验证 / 4.单元验证 / 5.分系统验证 / 6.原型验证 / 7.现实环境应用验证 / 8.用户验证认可 / 9.推广应用
**硬约束**: 不填的栏目用"无"标注;课题内容必须**完全覆盖**指南/申报书/立项批复;不得降低考核指标;不得对主要研究内容作大调整;一式十份;乙方与参加单位均需签盖公章。
---
## 3. NSFC 联合基金重点支持项目 (`nsfc_joint_fund`)
**典型场景**: NSFC-区域创新联合 / NSFC-企业创新联合 / NSFC-行业部门联合等。重点支持项目通常 200-300 万,4 年。
**正文字数**: 立项依据与研究内容 5000-10000 字 (NSFC 2026 版硬约束)。
### 必备结构 (3 大段)
NSFC-区域创新 / NSFC-企业创新 / NSFC-行业部门联合等。重点支持通常 200-300 万 / 4 年。**立项依据与研究内容 5000-10000 字**。
```
报告正文 (2026 版)
参照以下提纲撰写,标题与括号文字不得删除或改动。
提纲标题与括号文字 不得删除或改动。
(一) 立项依据与研究内容 ── 建议 5000-10000 字
1. 本项目申请的项目指南研究方向名称 (严格按指南填写)
2. 项目的立项依据
- 研究意义、国内外研究现状及发展动态分析
- 结合科研发展趋势论述科学意义
- 或结合国民经济和社会发展中亟需解决的关键科技问题论述应用前景
- 附主要参考文献目录
3. 项目的研究内容、研究目标,以及拟解决的关键科学问题 ──【重点】
4. 拟采取的研究方案及可行性分析
(研究方法、技术路线、实验手段、关键技术等)
(一) 立项依据与研究内容 ── 5000-10000
1. 项目指南研究方向名称 (严格按指南填)
2. 立项依据 (研究意义/国内外现状/发展动态/附主要参考文献)
3. 研究内容、研究目标、拟解决的关键科学问题 ← 重点
4. 拟采取的研究方案及可行性分析 (方法/技术路线/实验手段/关键技术)
5. 本项目的特色与创新之处
6. 年度研究计划及预期研究结果
(含拟组织的重要学术交流活动、国际合作与交流计划)
6. 年度研究计划及预期研究结果 (含国际合作)
(二) 研究基础与工作条件
1. 研究基础 (与本项目相关的工作积累和已取得成绩)
2. 工作条件 (实验条件、缺少条件及解决途径、依托国重/全重/部重的计划)
3. 正在承担的与本项目相关的科研项目情况
(资助机构、项目类别、批准号、项目名称、获资助金额、起止年月、与本项目关系、负责内容)
4. 完成国家自然科学基金项目情况
(已资助期满项目的完成情况、后续研究进展、与本申请关系
+ 该项目研究工作总结摘要 限 500 字
+ 相关成果详细目录)
1. 研究基础
2. 工作条件 (实验条件/缺少条件及解决途径/依托国重等)
3. 正在承担的与本项目相关的科研项目情况 (机构/类别/批准号/金额/起止/关系)
4. 完成 NSFC 项目情况 (前一已资助期满项目 + 总结摘要 ≤500 字 + 成果目录)
(三) 其他需要说明的情况
1. 同年申请不同类型 NSFC 项目情况 (列项目类型与名称、说明区别与联系)
2. 高级职称申请人/参与者同年申请其他 NSFC 项目时单位不一致的情况
3. 高级职称申请人/参与者与正在承担 NSFC 项目单位不一致的情况
4. 申请人和主要参与者同年以不同专业技术职务申请的情况
其他
1. 同年申请不同类型 NSFC 项目情况
2-4. 高级职称申请人 / 主要参与者 单位不一致 / 不同职称申请等说明
```
### 关键硬约束
- 提纲标题与括号文字 **不得删除或改动**
- 立项依据必须**附主要参考文献目录** (GB/T 7714 顺序编码制)
- 关键科学问题与研究内容是**重点**,占大头
- 申请人和主要参与者**如实填写有效聘用职称**;严禁虚假职称
- 同年禁止重复申请 (面上 + 重点不能同时申)
**硬约束**: 提纲标题与括号文字**不得改动**;立项依据必须附主要参考文献;关键科学问题与研究内容是**重点**;申请人和主要参与者**如实填写有效聘用职称**;同年禁止重复申请。
---
@ -213,50 +124,33 @@
| 项 | 面上 | 青年 (C 类) |
|---|------|-----|
| 资助强度 | 50-60 万 / 4 年 | 30 万 / 3 年 |
| 字数 | 立项依据与研究内容 5000-8000 字 | 立项依据与研究内容 5000-8000 字 |
| 申请人年龄 | 不限 | 男 ≤35 / 女 ≤40 |
| 评审重点 | 创新性 + 可行性 + 团队基础 | 创新性 + 可行性 + 培养价值;团队基础门槛低 |
| 指南方向 | 不强制对齐(自由选题为主) | 不强制对齐 |
| 资助 | 50-60 万 / 4 年 | 30 万 / 3 年 |
| 字数 | 立项依据与研究内容 5000-8000 | 同左 |
| 年龄 | 不限 | 男 ≤35 / 女 ≤40 |
| 评审重点 | 创新性 + 可行性 + 团队基础 | 创新性 + 可行性 + 培养价值 |
**2026 版变化**: 面上和青年 C 类申请书结构框架已调整,务必从 ISIS 系统下载**最新版**填写;不要套老模板。
**2026 版变化**: 面上和青年 C 类申请书结构已调整 → 务必从 ISIS 系统下载**最新版**填写,不要套老模板。
---
## 5. 省/部基金 (`provincial`)
骨架按各省指南,通常是国自然的简化版。共性:
- 立项依据 + 研究内容 + 研究基础 + 经费预算
- 字数预算约为国自然的 70%
- 大多要求**省内单位为主**,**优先支持成果转化**
- 经费间接费用比例与国家级一致
---
国自然简化版。共性: 立项依据 + 研究内容 + 研究基础 + 经费预算。字数预算约为国自然 70%。多数要求**省内单位为主**,**优先支持成果转化**。
## 6. 横向 / 企业委托 (`enterprise`)
不是基金,而是合同。结构:
- 项目名称、双方信息、合作背景
- 技术目标与考核指标 (甲方需求驱动,**不写学术问题**)
- 技术方案
- 进度与交付物 (节点付款挂钩)
- 经费 (含税总额、付款节点)
- 知识产权归属 (重点条款,默认按双方约定)
- 验收方式
- 保密、违约、争议解决
字数 3000-8000,远短于纵向。
合同,不是基金。结构: 项目名称 + 双方信息 + 技术目标(甲方需求驱动,**不写学术问题**) + 技术方案 + 进度交付物(节点付款) + 经费(含税总额) + 知识产权归属 + 验收 + 保密违约。**3000-8000 字**。
---
## 选择决策树
```
有指南文件? ── 是 ──> 看指南封面属于哪一档
"国家重点研发计划" → key_rd
"国家科技重大专项" → major_project (注意申报阶段是申报书,立项后是任务书)
"国家自然科学基金" → nsfc_general / nsfc_youth / nsfc_joint_fund
"XX 省自然科学基金" → provincial
无 ──> 是企业出钱? ── 是 ──> enterprise
否 ──> 跟用户确认基金来源,不要猜
有指南文件? — 是 → 看指南封面属于哪一档
"国家重点研发计划" → key_rd
"国家科技重大专项" → major_project (申报阶段是申报书,立项后是任务书)
"国家自然科学基金" → nsfc_general / nsfc_youth / nsfc_joint_fund
"XX 省自然科学基金" → provincial
否 → 是企业出钱? — 是 → enterprise
否 → 跟用户确认基金来源, 不要猜
```

View File

@ -1,167 +1,98 @@
# 评审雷区清单
评审专家最常拍死的几类问题。**写完每章对照过一遍**,中一条就重写。
---
每章写完对照过一遍。中一条就重写。
## 1. 与指南脱靶 (一票否决)
- 项目名称、指南方向、创新分类与指南文件**不一致** (一个字都不能改)
- 研究内容不能映射回指南的研究任务清单
- 考核指标缺项 — 指南要求 5 项,你只写了 4 项
- 指南要求"研发 X 套软件",你写"研究 X 软件理论" — 类型对不上
- 自行扩大或缩小指南范围 — 指南限定 A,你做 A+B
- 重点研发应用示范类项目没有示范单位/示范点 — 类型错位
- 项目名称 / 指南方向 / 创新分类与指南文件**不一致** (一字不能改)
- 研究内容不能映射回指南任务清单
- 考核指标缺项 (指南要 5 项,你写 4 项)
- 类型对不上 (指南要"研发软件",你写"研究理论")
- 自行扩大或缩小指南范围
- 应用示范类项目没有示范单位 / 示范点
**自查**: 把指南文本逐条贴进 spec_lock,每写完一节回去标"已覆盖"。
---
## 2. 假大空 (低分)
## 2. 假大空话术 (低分项)
直接 ban: 国际领先 / 国际一流 / 填补空白 / 首次提出 / 重大突破 / 立足国际前沿 / 聚焦关键核心 / 深远影响 / 重要意义 / 划时代 / 世界一流。
直接 ban 的词组:
- "国际领先" / "国际一流" / "填补空白" — 除非有第三方测试报告
- "首次提出" — 除非确实没人做过且能给文献证明
- "重大突破" / "重要意义" / "深远影响" — 缺信息量
- "立足国际前沿,聚焦关键核心" — 万能开场, 评审看疲了
- "建设具有 XX 特色的世界一流 YY" — 喊口号
替换原则:
- 用**指标+对比**替代形容词: "实现 10000 TPS,比现有方案 (Hyperledger Fabric 3000 TPS) 提升 3.3 倍"
- 用**机制+创新点**替代"突破": "通过 XX 解耦 + YY 流水线,降低共识延迟到 100 ms"
---
替换为**指标 + 对比**:"实现 10000 TPS,比 Hyperledger Fabric 3000 TPS 提升 3.3 倍"。
## 3. 指标无法考核 (致命)
不可考核的写法:
- "显著提升性能" — 显著 = 多少?
- "支持大规模交易" — 大规模 = 多少 TPS?
- "提升用户体验" — 怎么测?
- "优化算法效率" — 优化几个百分点?
不可考核词: 显著提升 / 大幅 / 明显改善 / 性能优异 / 体验优良 / 极大 / 大大 / 若干 / 大量 / 多种 / 等。
可考核的写法:
- "TPS ≥ 10000, 端到端延时 < 100 ms ( Caliper 工具测试,提供 CNAS/CMA 报告)"
- "示范园区 ≥ 4 个, 区块链节点 ≥ 50 个, 交易量 ≥ 50 万吨"
- "发明专利 ≥ 5 项 (已获受理通知书)"
每个指标必须能回答: **怎么测? 谁来测? 验收时拿什么证明?**
---
每个指标必须能回答: **怎么测? 谁来测? 验收时拿什么证明?** (CNAS/CMA 第三方测试 / 测试大纲 + 专家评审 / 应用示范报告)
## 4. 经费不合理 (扣分)
| 雷区 | 后果 |
|----|----|
| 间接费用超比例 (≤500 万部分 >30% / 500-1000 万 >25% / >1000 万 >20%) | 财务退回 |
| 设备费占比过高 (>40%) | 评审质疑必要性 |
| 劳务费支付给本单位编制内人员 | 违规 (劳务费仅给临时聘用) |
| 预算说明不写**任务相关性 + 政策相符性 + 经济合理性** | 退回补充 |
| 50 万以上设备没在 B3 表明细 | 必须明细到型号、功能、技术指标、生产厂家 |
| 自筹资金没出资单位承诺函 | 视为无配套 |
| 预算总额与指南资助额度不匹配 | 直接形式审查不过 |
详见 `budget_rules.md`
---
- 间接费用超台阶比例 (≤500 万 ≤30% / 500-1000 万 ≤25% / >1000 万 ≤20%)
- 设备费占比 >40% — 评审质疑必要性
- 劳务费支付给本单位编制内人员 (违规)
- 50 万以上设备没在 B3 表明细
- 自筹资金没出资单位承诺函
- 预算总额与指南资助额度不匹配
- 预算说明缺**任务相关性 + 政策相符性 + 经济合理性**
## 5. 限项违规 (一票否决)
- 项目负责人在研重点研发/重大专项/农业关键核心技术 **>2 项** — 直接退回
- 同一指南方向同一单位申报 **>1 项** — 学校层面就会被砍掉
- 同年同人不同基金多头申请 NSFC — 不予受理
- 主要参与人单位与所在单位**不一致**且未说明原因 — 退回补充
- 项目负责人在退休/出站等状态变动 — 须重新审查资格
- 项目负责人在研重点研发/重大专项/农业核心技术 >2 项
- 同一指南方向同一单位申报 >1 项
- 同年同人不同基金多头申请 NSFC
- 主要参与人单位与所在单位不一致且未说明
**写之前先跟用户确认**: 你是不是已经在执行其他重点研发/重大专项? 团队成员有没有重叠?
写之前先问用户: 在执行其他重点研发/重大专项? 团队成员有重叠?
---
## 6. 章节边界混淆 (低分)
## 6. 研究内容/方法/路线混淆 (低分)
最常见: 研究内容里写方法 / 研究方法里写目标 / 技术路线里写背景。
最常见的混乱:
- 研究内容里写了方法 (HOW)
- 研究方法里写了目标 (WHAT)
- 技术路线里写了背景 (WHY)
正确的边界:
| 章节 | 回答的问题 | 写什么 |
|-----|----------|------|
| 立项依据 | WHY | 现状 → 痛点 → 我们切入 |
| 研究目标 | WHAT (终态) | 量化指标、预期成果 |
| 研究内容 | WHAT (任务) | 技术 1, 技术 2, ... 8 项关键技术 |
| 研究方法 | HOW (原理) | 用什么算法/模型/原理来做 |
| 技术路线 | HOW (流程) | 输入 → 处理 → 输出, 5 个阶段如何串起来 |
写完检查: 把每章第一段拿出来读,能否准确回答上面"回答的问题"?
---
| 章节 | 回答的问题 |
|-----|----------|
| 立项依据 | WHY (背景 + 痛点) |
| 研究目标 | WHAT 终态 (量化指标) |
| 研究内容 | WHAT 任务 (技术清单) |
| 研究方法 | HOW 原理 (算法 / 模型) |
| 技术路线 | HOW 流程 (输入→处理→输出) |
## 7. 团队介绍踩雷
- ❌ 只列 title 不挂钩本项目: "XX 教授, 长江学者, 主持过 N 个项目" — So what?
- ❌ 团队规模虚胖: 写 50 人但项目只需要 15 人 — 会被问每人投入多少人月
- ❌ 单位 ≥ 8 家, 分工不清 — 容易被砍掉冗余
- ❌ 关键单位的关键资质没体现: 比如做碳交易的项目,中碳登的"生态环境部唯一授权"是核心,不要漏写
- ❌ 项目负责人没主持过同级别项目 (国自然青年→面上 OK, 没承担过任何项目→评审打问号)
- 只列 title 不挂钩本项目 ("XX 教授, 长江学者, 主持过 N 项目" — So what?)
- 团队规模虚胖 (写 50 人但只需 15)
- 关键资质漏写 (碳交易项目里中碳登的"生态环境部唯一授权")
- 项目负责人没主持过同级别项目
正确写法每人 200-400 字:
```
姓名 + 现职 + 学位
学术兼职 (1-2 个最相关的)
研究方向 (1 句, 与本项目对齐)
代表成果 (3-5 项, 论文/专利/项目)
**在本项目中承担 X 任务,提供 Y 支持** ← 必有
```
每人 200-400 字: title + 学术兼职 + 研究方向 + 代表成果 + **在本项目中承担 X 任务** ← 必有。
---
## 8. 文献雷区 (诚信)
## 8. 文献雷区 (诚信问题)
- 编造作者 / 期刊 / 年份 / DOI — 学术不端
- 文献全 5 年前 — 现状分析不可信
- 引文密度不均 (立项依据 30 篇, 其他 0)
- 全中文或全英文 — 现状分析做得不全
- 顺序乱 (顺序编码制按出现顺序编号)
- ❌ 编造文献作者/期刊/年份/DOI — 学术不端,可能撤项
- ❌ 文献全是 5 年前的 — 现状分析不可信
- ❌ 引文密度不均: 立项依据 30 篇, 其他章节 0 — 立项依据没读够
- ❌ 全是中文文献或全是英文文献 — 国内外现状分析做得不全
- ❌ 引用顺序乱 (顺序编码制要求按出现顺序编号)
让用户提供**真实文献清单**,你只排版。
正确做法: 让用户提供**真实文献清单**,你只负责按 GB/T 7714 排版。详见 `citation_gbt7714.md`
## 9. 进度 / 里程碑
---
- 进度表只写"完成 XX 研究" (看不出节点和交付物)
- 中期目标和最终目标完全一样 (中期应是 50% 完成度)
- 关键里程碑都堆在最后 6 个月
## 9. 进度/里程碑踩雷
每个里程碑必须有: 时间点 + 事件 + 关键指标 + 考核方式 + 交付物。
- ❌ 进度表只写"完成 XX 研究" — 看不出节点和交付物
- ❌ 中期目标和最终目标完全一样 — 中期指标必须是 50% 完成度
- ❌ 里程碑没有可验证的交付物 — 评审无法判断进度
- ❌ 关键里程碑都堆在最后 6 个月 — 风险过高
## 10. 形式审查 (递交前最后一遍)
正确做法: 每个里程碑必须有
- 时间点 (绝对日期)
- 事件 (做了什么)
- 关键指标 (达到什么状态)
- 考核方式 (怎么验)
- 交付物 (具体的报告/软件/原型)
---
## 10. 组织/保障踩雷
- ❌ 复制粘贴 — 8 个课题写一样的"建立总体组+课题组" — 评审一眼看出
- ❌ 没说明协调机制具体频率 — "定期组织交流"不够,要写"每月 1 次进展通报 + 每季度交流"
- ❌ 风险分析全是套话 — "本项目可能存在技术风险" — 没用,要具体化
---
## 11. 形式审查清单 (递交前最后一遍)
- [ ] 项目名称与指南、申报书、立项批复一致
- [ ] 字体: 标题黑体四号 / 正文宋体小四 / 英文 Times New Roman / 行距 1.5 倍
- [ ] 不填的栏目用"无"标注,**没有空白**
- [ ] 缩略词第一次出现注明全称 + 英文原文
- [ ] 项目名称与指南/申报书/立项批复一致
- [ ] 字体: 标题黑体四号 / 正文宋体小四 / 英文 Times New Roman / 行距 1.5
- [ ] 不填的栏目用"无", 没有空白
- [ ] 缩略词第一次出现注全称 + 英文原文
- [ ] 单位名称与公章一致
- [ ] 必要附件齐全 (合作协议盖章扫描、推荐函、伦理审查等)
- [ ] 总字数各章节字数符合预算
- [ ] 必要附件齐全 (合作协议盖章扫描 / 推荐函 / 伦理审查 / 保密承诺)
- [ ] 总字数 + 各章节字数符合预算
- [ ] 引文按 GB/T 7714 顺序编码,文中 [N] 与文末参考文献对应
- [ ] 表格编号、图编号、公式编号连续无遗漏
- [ ] 经费表三个层级 (B1/B2/B3/B4) 数字对得上
- [ ] 表格 / 图 / 公式编号连续无遗漏
- [ ] 经费表 (B1/B2/B3/B4) 数字对得上
- [ ] 课题任务书附 PDF 扫描签章件

View File

@ -1,267 +0,0 @@
# 章节写作骨架
写每一章前先来这里看骨架。**只给结构,不给套话** —— 套话会被评审一眼看穿。
---
## 1. 项目简介 (重点研发 1500 字 / 国自然 800 字)
七要素,每个 1-2 句,合计严格控字:
1. **背景**: 一句话政策/产业/科学动因 (避免"党的 XX 报告提出"开篇,除非确属国家重大战略类)
2. **研究目标**: 量化、可考核、与指南指标对齐
3. **研究内容**: 围绕 N 个关键问题,突破 M 项关键技术 (写出关键问题数量与技术数量)
4. **技术路线**: 一句话指导思想 + N 个研究模块
5. **创新点**: 3 条以内,每条一句概括
6. **基础与团队**: 牵头单位 + N 家参与单位 + 关键资质
7. **预期成果**: 软件/平台/专利/标准/示范 各 N
> 反例:"本项目立足国际前沿,聚焦关键核心,致力于打造国际一流水平。" — 没有信息量,直接砍。
---
## 2. 立项依据 / 研究背景 (5000-8000 字)
**三段式**:
### 段 1 — 现状 (40%)
- 国际格局: 列**最近 3-5 年**国外代表性团队 (机构 + 代表人物 + 关键产出),给文献 [1][2][3]
- 国内格局: 同样列**最近 3-5 年**国内团队
- **不要写"近年来 XXX 取得了长足进展"**,直接给数字/产出
- 结尾一句话归纳"虽然 XXX,但 YYY 仍未解决"
### 段 2 — 痛点 (30%)
- 把研究方向拆成 3-5 个子方向,每个子方向写:
- 国内外做到了什么
- 还差什么 (具体到指标差距,不是泛泛"性能不足")
- 为什么这是个真问题 (链到产业/科学需求)
- 每段结尾用"综上所述,亟需研究 X 关键技术"过渡
### 段 3 — 切入点 (30%)
- 本项目的逻辑链: 问题 X → 关键科学问题 Y → 研究内容 Z → 预期突破 W
- 为什么我们行: 团队 + 前期成果 + 资源 (1-2 句, 详细放研究基础章节)
- **不写**"国际领先""填补空白";写"我们将首次实现 X TPS 下的 Y 性能"
### 立项依据 vs 研究内容 vs 研究目标
最容易混的三个,记住:
- **立项依据**: 为什么做 (背景 + 痛点)
- **研究目标**: 做完是什么样 (终态指标)
- **研究内容**: 怎么做 (任务分解)
---
## 3. 研究目标与考核指标
### 研究目标
**三层结构**:
- **总目标**: 1 段, 紧扣指南方向, 给"3060""新基建"等国家战略一句话挂钩 (重点研发/重大专项常见, 国自然不需要)
- **拆解 2-3 个分目标**: 每个分目标对应一个关键问题
- **预期成果**: 软件 N 个 / 平台 N 个 / 专利 N 项 / 标准 N 项 / 论文 N 篇 / 示范点 N 个
### 考核指标矩阵 (重点研发/重大专项必备表)
| 序号 | 指南考核指标 (字面对齐) | 对应研究任务指标 (本项目, 量化超出) | 立项时已有指标值 | 完成时指标值 | 考核方式 |
|------|----------------------|------------------------------|-------------|-------------|---------|
| 1 | 提出 1 套 XX 体系架构方案 | 输出 1 套 XX 模型 + 1 套组件,实现 10000 TPS,秒级响应 | 无 | 测试报告达标 | CNAS/CMA 第三方测试 |
要点:
- 指南那栏**字面抄**指南文本,一字不改
- 自己那栏可以**超出**(数量 + 性能更高),不能低
- 量化、可测、有验收方式
- 考核方式分:CNAS/CMA 第三方测试 / 测试大纲 + 专家评审 / 应用示范报告
---
## 4. 研究内容
**总分结构**:
```
本项目围绕 N 个关键问题,开展 M 项关键技术研究,主要研究内容与关键问题的对应关系如图 X-X。
[图: 关键技术关系架构图]
技术 1: <技术名>
针对 <具体需求/痛点>,提出 <方法名>,突破 <子技术 a><子技术 b><子技术 c> 等技术,
支持 <最终能达到什么>
技术 2: <技术名>
针对 ...
(每项技术 200-300 字, 共 8-10 项凑到 3000 字)
```
要点:
- 每项技术名 = "针对 X 的 Y 技术",不要泛泛
- 每项必须有子技术列表 (3-5 个),证明你想清楚了
- 关键问题与技术的对应必须清晰 (画图最好)
---
## 5. 研究方法 (2000-4000 字)
**两层结构**:
### 总体方法
- 一句话指导思想 (例:"需求牵引、应用驱动、承前启后、典型示范")
- 总体研究路径 (自顶向下 / 由表及里)
- 给 1 张总体研究方法图
### 各模块方法
每个研究内容/课题给一段方法说明:
- 凝练业务需求
- 围绕 X 个技术难点
- 采用 <算法/模型/原理>
- 配 1 张技术思路图 + 1 张技术路线图
---
## 6. 技术路线 (重点研发独立成章 2000 字)
**两类图**:
- 技术总体路线图: 输入 → 关键技术模块 → 输出, 层次清楚
- 各课题技术路线图: 研究内容 → 关键技术 → 软件成果
文字部分:
- 按"需求分析-体系设计-技术突破-系统研发-应用示范"5 阶段叙述
- 每阶段说明 30-50 字, 关键节点对齐里程碑
---
## 7. 创新点 (每条 ≤500 字)
**三特征公式** (来自重大专项要求):
1. 该项创新的**基本形态**: 是新方法/新模型/新理论/新机制中的哪一种
2. **前沿性、时效性**: 与 SOTA 比有什么突破
3. **方法/理论/知识产权特征**: 体现在专利申请、论文、标准草案上
模板:
```
创新点 N: <一句标题>
针对 <场景与痛点>,提出 <方法/模型/机制名>,突破 <关键子技术>,
形成 <可知识产权化形态> (例:发明专利 X 项 / 行业标准草案 1 项)。
相比 <现有 SOTA / 国内外团队>,在 <可比维度> 上提升 X%/达到 Y 指标。
```
3 条上限,**多了反而稀释**。每条都要有"小而尖"的爆点。
---
## 8. 研究基础与团队
### 牵头单位
- 单位定位 (国家队 / 主力军 / 行业唯一资质 等具体定位)
- 与本项目相关的资质 / 平台 / 数据 (国重/省重/产业平台等)
- 前期承担的相关项目 (项目名称 + 资助类型 + 自评)
- 在本项目中承担的角色
### 各参与单位
每家 150-300 字, 内容:
- 单位定位
- 在该方向的差异化优势 (你不可替代)
- 在本项目中承担的具体任务
### 项目/课题负责人简介 (限 2000 字)
每位 200-400 字,内容固定:
- 现职 + 学位
- 学术兼职 (CCF 高级会员 / IEEE Fellow / 学会职务等)
- 研究方向
- 主要成果: 论文 N 篇 + 专利 N 项 + 项目主持/参与 N 项 + 获奖
- **与本项目的相关性**: 一句话挂钩
---
## 9. 进度安排 / 年度计划
### 重点研发 (限 2000 字, 鼓励甘特图)
按 36 个月项目周期, 分 4 个阶段:
- 0-6 月: 需求调研 + 方案设计
- 7-18 月: 关键技术突破
- 19-30 月: 系统集成 + 中期测试
- 31-36 月: 示范应用 + 综合验收
每阶段写: 任务 + 阶段成果 + 中期目标 (12 个月或 18 个月节点)
### 重大专项任务书 (按 6 个月)
更细, 每 6 个月一档, 每档写:
- 任务
- 考核指标
- 成果形式
里程碑节点: 每 6-12 个月一个, 时间点 + 事件 + 关键指标 + 考核方式 + 交付物
---
## 10. 组织实施与保障
**三层管理**:
- **项目总体组**: 项目负责人任组长 + 各课题负责人 + 核心研究人员; 制定总体方案、按节点检查、协调课题协同
- **课题技术组**: 课题负责人任组长 + 参与单位负责人; 管理本课题进度/成果/经费; 与其他课题协作
- **项目管理队伍**: 专门管理团队; 实施变更管理; 经费专款专用; 项目末做整体评估
**协调机制**: 每月通报 + 每季度交流 + 每半年总结 + 不定期技术研讨
**保障措施**: 制定《项目管理办法》,聘请科技主管 + 财务专家 + 技术专家联合制定。
---
## 11. 知识产权与风险分析
### 知识产权对策 (限 500 字)
4 块:
1. 知识产权归属 (各方在本项目前各自所有, 项目内独立完成的归各方独有, 共同完成的共有)
2. 知识产权使用 (审查与监督机制 + 协议管理)
3. 成果管理 (科研成果管理条例 + 评价鉴定 + 推广应用 + 成果档案)
4. 合作权益分配 (按项目任务分工 + 共享经济收益)
### 风险分析 (重点研发表 5-1)
风险表 4 列: 风险类型 / 严重程度 / 触发条件 / 应对措施
风险类型至少覆盖:
- 技术风险 (关键技术攻关难度)
- 进度风险 (依赖外部资源)
- 团队风险 (核心成员变动)
- 应用风险 (示范单位配合度)
---
## 12. 经费预算
详见 `budget_rules.md`。模板表:
```
表 X-X 课题预算表 (单位: 万元)
序号 预算科目 金额
1 一、中央财政专项资金 XXX
2 (一) 直接费用 XXX
3 1. 设备费 XX ← 50 万以上单台设备需在 B3 表明细
4 其中: 购置设备费 X
5 2. 业务费 XX ← 含会议/差旅/出版/咨询/材料等
6 3. 劳务费 XX ← 给临时聘用人员/学生
7 (二) 间接费用 XX ← 看 budget_rules.md 比例上限
8 二、其他来源资金 XXX
9 三、合计 XXX
```
预算说明 (1000 字以内): 任务相关性 + 政策相符性 + 经济合理性。
---
## 13. 附件清单
不同基金不同, 共性:
- 单位营业执照/法人证书
- 主要参与单位合作协议 (盖公章 + 法人签字)
- 项目负责人身份证 + 学历证
- 推荐单位推荐函 (重点研发)
- 知情同意书 / 伦理审查 (涉医)
- 保密承诺 (涉密)
- 配套资金承诺函 (有自筹的)
---
## 反模式速查 (写每章前在脑子里过一遍)
- ❌ 用形容词代替数字: "性能优异" → ✅ "10000 TPS / 秒级响应"
- ❌ 主语模糊: "本项目将研究 ..." → ✅ "课题 2 由 X 单位牵头, 研究 ..."
- ❌ 时态混乱: 研究目标用过去时 → ✅ 全文未来时 (将 / 拟 / 预期)
- ❌ 章节字数不均: 立项依据 1500 字 / 研究内容 8000 字 → ✅ 按 `fund_types.md` 字数预算
- ❌ 创新点写一长段不分项 → ✅ 三条以内, 每条标题 + 200-400 字
- ❌ 团队介绍只列 title 不挂钩本项目 → ✅ 每人最后一句"在本项目中承担 X 任务"

View File

@ -1,174 +0,0 @@
# 字体 / 页面 / 表格 排版硬规则
来自三份真实模板 (重大专项任务书、NSFC 联合基金 2026、国家重点研发"区块链"申报书) 的填表说明,以及科技部公共服务平台模板。
**违反 = 形式审查扣分**。
---
## 1. 字体
| 元素 | 字体 (中文) | 字体 (英文/数字) | 字号 |
|----|----|----|----|
| 一级标题 | 黑体 | Times New Roman | 四号 (14 pt) |
| 二级标题 | 黑体 | Times New Roman | 小四 (12 pt) 加粗 |
| 三级标题 | 宋体 | Times New Roman | 小四 加粗 |
| 正文 | **宋体** | **Times New Roman** | **小四 (12 pt)** |
| 表格内文字 | 宋体 | Times New Roman | 五号 (10.5 pt) 或小四 |
| 图表标题 | 黑体 | Times New Roman | 五号 |
| 脚注 | 宋体 | Times New Roman | 小五 (9 pt) |
**强制中英文混排**: 中文字符用宋体,英文字母和阿拉伯数字用 Times New Roman。在 Word 里用"中文字体"+"西文字体"分别设置,**不要全设宋体**(会让英文也变全角)。
---
## 2. 段落
- **行距**: 1.5 倍 (重点研发硬性要求, 其他基金统一)
- **段前段后**: 0
- **首行缩进**: 2 字符 (中文标准)
- **段落间距**: 标题段后 0.5 行;正文段间无空行
- **对齐**: 两端对齐 (中文)
---
## 3. 页面
- **纸张**: A4 (210×297 mm)
- **页边距**: 上 2.5 / 下 2.5 / 左 3.0 / 右 2.0 cm
- **页眉**: 项目名称或留空
- **页脚**: 居中页码 (第 X 页 共 Y 页)
- **打印**: 双面打印 (装订送审版本)
---
## 4. 表格
- 表格三线 / 普通线均可,**优先三线表**
- 表头**加粗**,可加底纹 (浅灰)
- 表格内文字字号比正文小一号 (五号)
- **表格上方**写表号 + 表名:`表 2-3 项目目标、预期成果与考核指标表` (居中, 黑体五号)
- **图下方**写图号 + 图名:`图 2-1 碳达峰碳中和执行路线图` (居中, 黑体五号)
- 表号 / 图号编排: `<章号>-<序号>` (例:第 2 章第 3 个表 = 表 2-3)
- 跨页表格:在续页顶部加"表 X-Y (续)"标注,重复表头
---
## 5. 图
- 图统一用矢量 (svg/emf) 或 ≥150 DPI 位图
- 配色克制, 黑白打印能看清的优先 (申报书评审常黑白打印)
- 图内文字与正文字号相近 (五号 / 10 pt 左右)
- 流程图、架构图: 推荐 mermaid / draw.io 导出 svg
---
## 6. 标点
- 中文用全角:`,。:;""''《》`
- 英文用半角:`, . : ; " ( )`
- 中英混排时, 数字与英文用半角, 中文用全角
- 段中夹有英文短语时, 该短语用半角标点
---
## 7. 数字
- ≥4 位数字用千分位空格 (中文用法) 或千分位逗号 (英文用法), **同一篇内统一**
- 中文: `10 000 TPS``10000 TPS`
- 英文: `10,000 TPS`
- 百分比一律 `XX%` (不要 `XX 个百分点` 除非确指变动)
- 量纲与数字之间空 1 格: `100 ms` `5 万吨` (中文可不加空格,但全文一致)
---
## 8. 缩略词
第一次出现写**全称 + 括号缩略词**:
```
全国统一碳排放权交易市场 (国家统一碳市场)
区块链即服务 (Blockchain as a Service, BaaS)
中央认证授权 (CA)
```
之后可只用缩略词。**外来语**要同时给原文和中文。
---
## 9. 列表 / 编号
- 章: 一、二、三、...
- 节: (一) (二) (三) ...
- 小节: 1. 2. 3. ...
- 子项: (1) (2) (3) ...
- 再下一级: ① ② ③ ...
---
## 10. python-docx 起手代码
```python
from docx import Document
from docx.shared import Pt, Cm, Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_LINE_SPACING
from docx.oxml.ns import qn
doc = Document()
# 页面
section = doc.sections[0]
section.page_height = Cm(29.7)
section.page_width = Cm(21)
section.top_margin = Cm(2.5)
section.bottom_margin = Cm(2.5)
section.left_margin = Cm(3.0)
section.right_margin = Cm(2.0)
# 默认样式 — 正文
style = doc.styles['Normal']
style.font.name = 'Times New Roman'
style.font.size = Pt(12) # 小四
style.element.rPr.rFonts.set(qn('w:eastAsia'), '宋体') # 中文宋体
pf = style.paragraph_format
pf.line_spacing = 1.5
pf.first_line_indent = Pt(24) # 首行缩进 2 字符 (12pt × 2)
pf.alignment = WD_ALIGN_PARAGRAPH.JUSTIFY
# 一级标题样式 — 黑体四号
h1 = doc.styles['Heading 1']
h1.font.name = 'Times New Roman'
h1.font.size = Pt(14)
h1.font.bold = False # 黑体本身就显得粗,不用再加粗
h1.element.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
# 二级标题 — 黑体小四 加粗
h2 = doc.styles['Heading 2']
h2.font.name = 'Times New Roman'
h2.font.size = Pt(12)
h2.font.bold = True
h2.element.rPr.rFonts.set(qn('w:eastAsia'), '黑体')
# 三级标题 — 宋体小四 加粗
h3 = doc.styles['Heading 3']
h3.font.name = 'Times New Roman'
h3.font.size = Pt(12)
h3.font.bold = True
h3.element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
```
---
## 11. 自查清单
打印前过一遍:
- [ ] 中文宋体 / 英文 Times New Roman 双字体设置
- [ ] 行距 1.5 倍
- [ ] 首行缩进 2 字符
- [ ] 章节标题字体字号正确
- [ ] 图表都有编号 + 名称, 居中
- [ ] 缩略词第一次出现注明全称
- [ ] 中文全角标点, 英文半角标点
- [ ] 数字与量纲间空格统一
- [ ] 没有空白栏 (用"无"填充)
- [ ] 页码连续无遗漏

View File

@ -22,6 +22,7 @@ REQUIRED_SECTIONS: dict[str, list[str]] = {
"00_basic_info", "01_summary", "02_background", "03_objectives",
"04_content", "05_decomposition", "06_innovation", "07_benefit",
"08_basis", "09_schedule", "10_organization",
"11_team", "12_budget", "13_appendix",
],
"major_project": [
"00_basic_info", "01_objectives", "02_content", "03_innovation",
@ -87,10 +88,62 @@ def check_placeholders(text: str, file_label: str) -> list[str]:
return issues
def parse_spec_metrics(spec_path: Path) -> list[str]:
"""从 spec_lock.md 的"7. 考核指标矩阵"段抽出"指南考核指标"那列。
寻找形如 `| 1 | 指南指标 | ... |` 的表行(序号 = 数字),取第 2
返回每条指南指标的关键短语列表 (用于在 sections 中模糊匹配)
"""
if not spec_path.exists():
return []
txt = spec_path.read_text(encoding="utf-8")
# 截取 "考核指标矩阵" 段到下一节标题
m = re.search(r"考核指标矩阵.*?(?=\n##\s|\Z)", txt, re.DOTALL)
if not m:
return []
block = m.group(0)
out: list[str] = []
for line in block.splitlines():
if not line.strip().startswith("|"):
continue
cells = [c.strip() for c in line.strip().strip("|").split("|")]
if len(cells) < 3:
continue
# 表头行 / 分隔行 跳过
if not cells[0].isdigit():
continue
guide_metric = cells[1]
if guide_metric and not guide_metric.startswith("<TODO") and not guide_metric.startswith("`"):
out.append(guide_metric)
return out
def check_spec_coverage(sections_dir: Path, spec_path: Path) -> list[str]:
"""每条指南考核指标必须在某个章节里以**关键词**形式出现 (>=2 个核心词命中)。"""
metrics = parse_spec_metrics(spec_path)
if not metrics:
return []
# 把 sections 全文拼起来
full = "\n".join(f.read_text(encoding="utf-8") for f in sections_dir.glob("*.md"))
issues = []
for metric in metrics:
# 提关键词: 取长度 >=2 的中文片段 / 数字 / 字母组合
tokens = re.findall(r"[一-鿿]{2,}|[A-Za-z][\w]*|\d+\.?\d*", metric)
if not tokens:
continue
hits = sum(1 for t in tokens if t in full)
# 至少命中 2 个 token, 且至少 30% 的 token 出现
if hits < 2 or hits / len(tokens) < 0.3:
issues.append(f"指南指标可能未在正文覆盖: '{metric[:50]}...' (命中 {hits}/{len(tokens)} 关键词)")
return issues
def main() -> None:
ap = argparse.ArgumentParser(description="申报书质量检查")
ap.add_argument("sections_dir", type=Path)
ap.add_argument("--fund-type", required=True, choices=list(REQUIRED_SECTIONS.keys()))
ap.add_argument("--spec", type=Path, default=None,
help="spec_lock.md 路径; 提供后会做指南考核指标覆盖度检查")
ap.add_argument("--strict", action="store_true",
help="严格模式: 任何检查项失败均退出 1")
args = ap.parse_args()
@ -99,7 +152,7 @@ def main() -> None:
print(f"[ERR] {args.sections_dir} not a directory", file=sys.stderr)
sys.exit(2)
print(f"\n[质量检查]申报书质量检查 ({args.fund_type})\n")
print(f"\n[质量检查] fund_type={args.fund_type}\n")
all_issues: list[str] = []
@ -113,7 +166,7 @@ def main() -> None:
else:
print("[OK] 结构完整")
# 2-4. 内容
# 2-4. 内容 (假大空 / 不可考核词 / 占位符)
files = sorted(args.sections_dir.glob("*.md"))
print(f"\n{len(files)} 个章节, 逐章扫描...\n")
for f in files:
@ -128,13 +181,30 @@ def main() -> None:
print(f" -{s.split('] ', 1)[1]}")
all_issues.extend(sub_issues)
# 5. 指南覆盖度 (--spec 提供时)
if args.spec:
if not args.spec.exists():
print(f"\n[ERR] spec 文件不存在: {args.spec}")
all_issues.append("spec 文件不存在")
else:
print(f"\n[指南覆盖度] 对照 {args.spec.name}")
cov_issues = check_spec_coverage(args.sections_dir, args.spec)
if cov_issues:
print("[WARN] 部分指南指标可能在正文未充分覆盖:")
for s in cov_issues:
print(f" -{s}")
all_issues.extend(cov_issues)
else:
print("[OK] 指南考核指标在正文均有体现")
print("\n" + "=" * 60)
if all_issues:
print(f"[WARN] 共发现 {len(all_issues)} 个问题。")
print("\n建议:")
print(" - 假大空词组 → 换成具体数字 / 对比")
print(" - 不可考核词 → 量化指标 (TPS / 准确率 / 万元 / N 篇)")
print(" - 占位符未替换 → 找用户提供真实数据 / 替换 <TODO>")
print(" - 假大空词组 -> 换成具体数字 / 对比")
print(" - 不可考核词 -> 量化指标 (TPS / 准确率 / 万元 / N 篇)")
print(" - 占位符未替换 -> 找用户提供真实数据 / 替换 <TODO>")
print(" - 未覆盖指南指标 -> 在对应章节明确写出该指标的实现方式")
if args.strict:
sys.exit(1)
else:

View File

@ -1,6 +1,6 @@
"""把 sections/*.md 渲染成符合中国基金申报书排版规范的 .docx。
字体规范 (来自 typography.md):
字体规范:
- 标题黑体 (一二级) / 三级标题宋体 / 正文中文宋体 / 英文 Times New Roman
- 行距 1.5 / 首行缩进 2 字符
- A4 / 上下 2.5cm / 3.0cm / 2.0cm
@ -224,6 +224,7 @@ _HEADING_RE = re.compile(r"^(#{1,6})\s+(.+)$")
_TABLE_LINE_RE = re.compile(r"^\s*\|.*\|\s*$")
_BLOCKQUOTE_RE = re.compile(r"^\s*>\s?")
_HR_RE = re.compile(r"^\s*-{3,}\s*$|^\s*={3,}\s*$|^\s*_{3,}\s*$")
_FENCE_RE = re.compile(r"^\s*(`{3,}|~{3,})\s*(\S*)\s*$")
# 列表项 (各自独立成段, 不跟相邻行合并, 不缩进首行)
_LIST_PATTERNS = [
@ -259,6 +260,29 @@ def is_hr(line: str) -> bool:
return bool(_HR_RE.match(line))
# ───────────────────────── 代码块 / ASCII 图 ─────────────────────────
def add_code_block(doc: Document, lines: list[str], lang: str = "") -> None:
"""fenced ``` 块 / ASCII 流程图: 等宽字体 + 行距 1.0 + 不缩进 + 不解析内联 + 保留空格。
中文用"新宋体"(NSimSun, Windows 自带等宽宋体), 西文用 Consolas, 这样
` ` 这类 box drawing 字符与中文字符的视觉宽度更接近, ASCII 流程图不至于错位
"""
for ln in lines:
p = doc.add_paragraph()
pf = p.paragraph_format
pf.first_line_indent = None
pf.line_spacing = 1.0
pf.space_before = Pt(0)
pf.space_after = Pt(0)
run = p.add_run(ln if ln else " ") # 空行也占一行高
run.font.size = Pt(10.5) # 五号
_set_run_fonts(run, cn_font="新宋体", en_font="Consolas")
# docx 默认会压缩连续空格 -> 显式 xml:space=preserve, 否则 ASCII 对齐会被破坏
for t in run._element.iter(qn("w:t")):
t.set(qn("xml:space"), "preserve")
# ───────────────────────── 表格 ─────────────────────────
def _split_md_row(line: str) -> list[str]:
@ -322,6 +346,24 @@ def render_md_block(doc: Document, md_text: str) -> None:
i += 1
continue
# fenced 代码块 / ASCII 流程图 (```...``` 或 ~~~...~~~)
m_fence = _FENCE_RE.match(line)
if m_fence:
fence = m_fence.group(1)
lang = m_fence.group(2) or ""
code: list[str] = []
i += 1
while i < n:
m_close = _FENCE_RE.match(lines[i])
# 闭围栏: 同种符号 (` vs ~) 且长度 ≥ 开围栏
if m_close and m_close.group(1)[0] == fence[0] and len(m_close.group(1)) >= len(fence):
i += 1
break
code.append(lines[i]) # 不 rstrip, 保留原始空格
i += 1
add_code_block(doc, code, lang)
continue
# 表格 (连续若干行 | ... | 视为一张表)
if is_table_line(line):
block: list[str] = []

View File

@ -1,268 +1,124 @@
# 国家重点研发计划 申报书章节框架 (key_rd)
> 复制到 `<task_dir>/sections/` 下,**逐章填充**。每节顶部有字数预算和写作要点提示;不要把 `>` 提示删掉,完稿前去除 `<TODO>` 即可
复制对应小节到 `<task_dir>/sections/`,逐章填空。`<TODO>` 为占位符,完稿前清零
---
## 00_basic_info.md — 项目基本信息表
> 表格,按 spec_lock.md 第 1 项 (基金类型) 与第 6 项 (申报单位) 填。共 35 行左右。
字段清单 (照抄即可):
- 项目名称 / 所属专项 / 指南方向 (榜单任务) / 创新分类 / 项目遴选方式 / 项目实施模式 / 单位总数 / 课题数 / 经费预算 (总 + 中央财政 + 地方 + 自筹 + 其他) / 项目周期 (起始 / 结束 / 实施周期 / 预计中期时间点)
- 申报单位 (单位名称 / 性质 / 主管部门 / 隶属关系 / 所属地区 / 通信地址 / 邮政编码 / 单位法定代表人 / 组织机构代码)
按 spec_lock 第 1+6 项填,共 35 行左右。字段:
- 项目名称 / 所属专项 / 指南方向 (榜单任务) / 创新分类 / 项目遴选方式 / 项目实施模式
- 单位总数 / 课题数 / 经费预算 (总+中央+地方+自筹+其他) / 项目周期 (起始/结束/实施周期/中期时间点)
- 申报单位 (名称/性质/主管部门/隶属/所属地区/通信地址/邮编/法定代表人/组织机构代码)
- 推荐单位
- 项目负责人 (姓名 / 性别 / 出生日期 / 证件类型 / 证件号码 / 所在单位 / 最高学位 / 职称 / 职务 / 电子邮箱 / 移动电话)
- 项目联系人
- 项目财务负责人
- 项目负责人 (姓名/性别/出生/证件/单位/学位/职称/职务/邮箱/手机)
- 项目联系人 / 项目财务负责人
- 课题分解 / 其他参与单位
- 项目参加人数 (高/中/初/其他职称分布; 博/硕/学士/其他学位分布)
- 项目参加人数 (高/中/初/其他职称分布; 博/硕/学士/其他学位分布)
---
## 01_summary.md — 申报项目简介
## 01_summary.md — 申报项目简介 (限 1500 字)
> 限 1500 字。七要素结构,见 `references/section_templates.md` § 1。
```
一、研究背景
<TODO 国家政策 / 产业需求 / 科学问题 一句话>
二、研究目标
瞄准 <一句战略目标>, 拟解决 <N 个关键问题>, 突破 <M 项关键技术>, 超额完成指南考核指标:
开发 X 个软件工具、Y 个 ...; 区块链节点 N 个、交易量 N 万吨、...
三、研究内容 (包括拟解决的重大科学问题或关键技术问题)
围绕 <2 个关键问题>, 重点研究 <技术 1><技术 2>、... <技术 8> 等主要内容。
四、技术路线
按照 "<指导思想>" 指导思想, 采用 <自顶向下/由表及里> 研究方法, 围绕 <两大痛点>,
合理划分研究内容, 设置 N 个课题开展研究工作, 逐项落实考核指标。
五、创新点
预期在 <创新 1><创新 2><创新 3> 等方面取得原始创新。
六、研究基础和团队
<牵头单位><定位>, 拥有 <资质>
<参与单位 1><定位>
... (按重要性 5-8 家)
七、预期成果和效益
申请国拨 XX 万, 自筹 XX 万, 研发 X 种软件系统, 搭建 N 个平台,
提出国际/国家/行业标准草案 N 项, 申请专利 N 项。
```
七要素 (每个 1-2 句):
1. **背景**: 一句话政策/产业/科学动因
2. **研究目标**: 量化、与指南指标对齐
3. **研究内容**: 围绕 N 个关键问题, 突破 M 项关键技术
4. **技术路线**: 一句话指导思想 + N 个研究模块
5. **创新点**: 3 条以内,每条一句概括
6. **基础与团队**: 牵头单位 + N 家参与单位 + 关键资质
7. **预期成果**: 软件/平台/专利/标准/示范点 各 N
---
## 02_background.md — 第一部分 国内外现状及趋势分析
## 02_background.md — 第一部分 国内外现状及趋势分析 (限 2000 字)
> 限 2000 字 + 国外/国内代表性 5 家机构表 + 项目相关 5 项代表成果/专利/标准表。立项依据三段式见 `section_templates.md` § 2。
### 国内外现状
(分 3-5 个子方向, 每个子方向 300-400 字)
#### <子方向 1: ,区块链体系架构>
国外: <Huawei Huang [2] 等提出 BrokerChain... Wang [3] 提出 Monoxide...>
国内: <Hyperledger Fabric 联盟链支持多链...>
综上所述,尽管 ... 已具备 ..., 但针对 <具体问题>, **亟需研究** <关键技术 X><关键技术 Y>
#### <子方向 2: ...>
#### <子方向 3: ...>
### 表 1-1 国外从事相关研究的主要机构 (不超过 5 家)
| 序号 | 机构名称 | 相关研究内容 | 相关研究成果 | 成果应用情况 | 自评价 |
| 1 | <TODO> | <TODO> | <TODO> | <TODO> | □领跑 □并跑 □跟跑 |
| 2 | ... |
### 表 1-2 国内从事相关研究的主要机构 (不超过 5 家)
(同表 1-1 但不需要自评价列)
### 表 1-3 项目研发相关的主要文献、专利、标准 (不超过 5 项)
| 序号 | 类型 | 名称 | 机构 | 作者 |
| 1 | 文献 | <TODO> | <TODO> | <TODO> |
| 2 | 专利 | ... |
| 3 | 标准 | ... |
立项依据三段式 (现状 40% / 痛点 30% / 切入点 30%)。需附:
- 表 1-1 国外代表性 5 家机构 (序号/名称/研究内容/成果/应用情况/自评价 领跑并跑跟跑)
- 表 1-2 国内代表性 5 家机构 (无自评价列)
- 表 1-3 项目相关 5 项代表成果/专利/标准 (序号/类型/名称/机构/作者)
---
## 03_objectives.md — 第二部分 研究目标及内容 / 一、项目目标及考核指标
## 03_objectives.md — 第二部分 / 一、项目目标及考核指标
### (一) 申报项目所属指南方向的关联关系
### (一) 与指南方向的关联关系 (限 1500 字)
> 限 1500 字。证明你的项目和指南完全对齐。
4 段证明对齐:
1. 拟解决的科学问题 → 覆盖指南
2. 拟解决的关键技术 → 覆盖指南
3. 提出的研究内容 → 覆盖指南
4. 提出的研究指标 → 全面覆盖指南
+ 表 2-1 研究内容覆盖指南要求 (序号/指南方向/任务设置/子任务/相关性=完全相关 or 完全相关并超出)
+ 表 2-2 研究指标覆盖指南考核 (一对一映射, 可超出, 不可低于)
按以下结构 4 段式:
1. 拟解决的科学问题 → 覆盖指南要求的关键科学问题
2. 拟解决的关键技术 → 覆盖指南要求的核心关键技术
3. 提出的研究内容 → 覆盖指南要求的研究内容
4. 提出的研究指标 → 全面覆盖指南考核指标
### (二) 项目目标及考核指标、考核方式 (限 2000 字, 不含表)
#### 表 2-1 研究内容覆盖指南要求的研究内容
| 序号 | 指南研究方向 | 研究任务设置 | 子任务 | 相关性 |
| 1 | <指南文本字面抄> | 课题 1. <课题名> | <子任务 a>;<子任务 b>;<子任务 c> | 完全相关 |
#### 表 2-2 研究指标全面覆盖指南的考核指标
(指南 vs 本项目, 一对一映射, 本项目可超出, 不可低于)
### (二) 项目目标及考核指标、考核方式/方法
> 限 2000 字 (不含表)。
1. **项目目标**: 紧扣 <战略>, 制定本项目目标 (一段)
2. 围绕 <N 大问题与 N 项关键技术>, 研制 <N 个平台>, 在 <N 个示范点> 开展应用示范。
3. **考核指标与评测方法/方式** (按指南章节顺序逐条):
1. 项目目标: 紧扣战略,一段
2. 拆分 N 大问题与 N 项关键技术,研制 N 个平台,N 个示范点
3. 考核指标与评测 (按指南顺序逐条):
- (1) 在 <指南方向 1> 方面
- 1) <子任务名> 考核指标: <量化指标>, 发明专利 N 项;评测方式: <CNAS/CMA 测试 / 应用示范报告>
- 2) ...
- 1) <子任务名> 考核指标: <量化>;评测方式: <CNAS/CMA / 测试大纲专家评审 / 应用示范报告>
#### 表 2-3 项目目标、预期成果与考核指标表
(主表,按 `section_templates.md` § 3 的格式)
+ 表 2-3 项目目标、预期成果与考核指标表 (主表)
### (三) 项目预期成果的呈现形式及描述
### (三) 预期成果的呈现形式 (限 1000 字)
> 限 1000 字。
按成果形态分:
1. **理论研究成果**以论文、著作、报告、实验模型方式呈现。
2. **核心技术研究成果**以专利和软件成果形式呈现。每项软件成果包括 <软件设计文档/手册/源代码/...>
3. **平台**以软件系统形式呈现, 含 <开发文档/使用文档/测试文档/源代码>
各平台介绍 (1-2 段一个平台, 描述其分系统组成与集成关系):
- 平台 1: <名称><分系统 A><分系统 B> 组成。
- 平台 2: ...
#### 表 2-4 成果列表
按形态分: 理论 (论文/著作/报告) / 核心技术 (专利+软件) / 平台 (软件系统) / 各平台分系统说明。
+ 表 2-4 成果列表
---
## 04_content.md — 二、项目研究内容、研究方法及技术路线
### (一) 项目的主要研究内容
> 限 3000 字。研究内容总分结构,见 `section_templates.md` § 4。
### (一) 主要研究内容 (限 3000 字)
```
拟解决的关键科学问题
本团队以 "<原则>" 为原则, 以 "<理念>" 为理念,
针对 <场景 1 痛点>, 亟需解决关键问题一 "<问题 1>";
针对 <场景 2 痛点>, 亟需解决关键问题二 "<问题 2>";
针对 <场景 1 痛点>,亟需解决问题一 "<问题 1>";
针对 <场景 2 痛点>,亟需解决问题二 "<问题 2>";
项目研究内容
本项目面向 <需求>, 围绕 N 个关键问题, 聚焦 <聚焦点>,
开展 N 项关键技术研究, 主要研究内容与关键问题的对应关系如图 2-2。
本项目围绕 N 个关键问题, 开展 M 项关键技术研究, 对应关系如图 2-2。
[图 2-2 关键技术关系架构]
技术 1: <技术名>
针对 <具体痛点>, 提出 <方法>, 突破 <子技术 a/b/c>, 支持 <能达到什么>
针对 <具体痛点>, 提出 <方法>, 突破 <子技术 a/b/c>, 支持 <最终能达到>
技术 2: ...
... (8 项技术合计 3000 字)
技术 2: ... (8 项 ≈ 3000 字)
```
### (二) 项目拟采取的研究方法
### (二) 项目拟采取的研究方法 (限 2000 字)
> 限 2000 字
总体方法 + 各课题研究方法 (按"需求分析 → 体系设计 → 技术突破 → 系统研发 → 应用示范"5 阶段)。配 4-6 张图
```
项目总体研究方法
按照 "<指导思想>", 面向 <应用场景>, 结合 <战略>, 对研究目标、研究内容及关系进行细化, 如图 2-3。
采用 <自顶向下> 方法, 围绕 <两大痛点>, 设置 N 个课题, 开展研究工作。
### (三) 项目的技术路线 (限 2000 字)
[图 2-3 研究方法]
[图 2-4 业务流程]
[图 2-5 体系架构]
[图 2-6 技术架构]
项目课题研究方法
各课题按照 "需求分析-体系设计-技术突破-系统研发-应用示范" 研究思路分别开展研究。
课题 1: <课题名>
凝练 <X 业务需求>, 围绕 <技术难点 a><技术难点 b><技术难点 c>, 采用图 X-X 的研究方法。
课题 2: ...
```
### (三) 项目的技术路线
> 限 2000 字。
```
[图 X-X 项目总体技术路线]
按 "需求分析-体系设计-技术突破-系统研发-应用示范" 5 阶段叙述项目总体路线。
各课题技术路线:
课题 1: <技术路线说明 + X-X>
课题 2: ...
```
总体路线图 + 各课题技术路线图。
---
## 05_decomposition.md — 三、课题分解方案
### (一) 课题分解情况
### (一) 课题分解情况 (限 2000 字)
> 限 2000 字。配 1 张课题关系图。
围绕项目目标,分解 N 个课题。课题间逻辑关系 (输入输出依赖)。配 1 张课题关系图。
围绕项目目标, 项目分解为 N 个课题:
- 课题 1 <课题名>: 解决 <子问题 a>, 由 <牵头单位> 负责
- 课题 2 ...
- 课题间逻辑关系: 课题 1 输出 X 给课题 N 作为输入, ...
### (二) 各课题内容 (每课题 ≤3000 字)
[图 3-1 课题分解关系图]
### (二) 各课题内容
> 每个课题 ≤3000 字。
每个课题包括:
1. 研究目标
2. 主要研究内容
3. 拟解决的重大科学问题或关键技术
4. **考核指标及评测手段、方法**
5. 参加单位任务分工
6. 经费预算
(按上述结构逐课题展开)
每课题: 研究目标 + 主要研究内容 + 拟解决的关键科学/技术问题 + **考核指标及评测手段** + 参加单位任务分工 + 经费预算。
---
## 06_innovation.md — 四、主要创新点
## 06_innovation.md — 四、主要创新点 (每条 ≤500 字, 通常 3-5 条)
> 每条 ≤500 字, 通常 3-5 条。三特征公式见 `section_templates.md` § 7。
```
1. 创新点 1: <一句标题>
<按三特征公式: 基本形态 + 前沿性时效性 + 知识产权特征>
2. 创新点 2: ...
3. 创新点 3: ...
```
每条按三特征公式: 基本形态 + 前沿性时效性 + 知识产权特征。
---
## 07_benefit.md — 五、预期经济社会效益
## 07_benefit.md — 五、预期经济社会效益 (限 1500 字)
> 限 1500 字。四个维度: 科学价值 / 技术价值 / 社会效益 / 经济价值。
```
1. 科学价值
<项目在哪些方向取得原始创新, 为什么有理论支撑意义>
2. 技术价值
<突破 N 项核心技术, 形成 X 项专利 + Y 项标准 + Z 个软件; 预期市场规模>
3. 社会效益
<政府监管效率 / 数据安全透明度 / 民生改善 / ... 至少 2 >
4. 经济价值
<实际应用价值: N 个示范点应用, 减少 X 万吨碳排放;
全国推广: 年节省成本 X 亿元 / 创造市场规模 X 亿元>
```
四个维度: 科学价值 / 技术价值 / 社会效益 / 经济价值。
---
@ -270,94 +126,46 @@
### 一、申报单位的已有工作基础
#### (一) 牵头单位前期任务承担及综合绩效评价情况
> 限 1000 字。
- (一) 牵头单位前期任务承担及绩效 (限 1000 字)
- (二) 项目及课题负责人科研水平 (限 2000 字, 每位 200-400 字)
- (三) 牵头单位科研条件 (限 1000 字, 国重 / 工程中心 / 大仪)
- (四) 牵头企业运行状况 (如是企业, 表 3-1 近 3 年营收/利润/研发投入)
#### (二) 项目及课题负责人科研水平及主要成果
> 限 2000 字。每位负责人 200-400 字, 见 `section_templates.md` § 8。
### 二、参与单位的选择原因及优势 (限 1000 字, 每家 100-200 字)
#### (三) 牵头单位科研条件支撑
> 限 1000 字。国重 / 国家工程中心 / 大型仪器等。
#### (四) 牵头企业运行状况 (如牵头单位是企业)
> 表 3-1 项目牵头企业运行状况 (近 3 年营收/利润/研发投入等)
### 二、参与单位、团队的选择原因及优势
> 限 1000 字。每家参与单位 100-200 字, 强调差异化。
### 三、相关的国际合作与交流
> 限 1000 字。
### 三、相关的国际合作与交流 (限 1000 字)
---
## 09_schedule.md — 第四部分 进度安排
## 09_schedule.md — 第四部分 进度安排 (限 2000 字)
> 限 2000 字, 鼓励甘特图。
按项目周期 (例 36 个月) 分 4 阶段:
- 0-6 月: 需求调研与方案设计
- 7-18 月: 关键技术突破
- 19-30 月: 系统集成与中期测试 (中期目标节点)
- 31-36 月: 应用示范与综合验收
每阶段写: 任务 / 阶段成果 / 中期目标。
[图 4-1 项目进度甘特图]
里程碑节点 (按 6-12 个月一个):
- 节点 1 (X 年 X 月): <事件> / <关键指标> / <考核方式> / <交付物>
- 节点 2 ...
按周期分 4 阶段 + 配甘特图 + 里程碑节点 (每 6-12 月一个: 时间 + 事件 + 关键指标 + 考核方式 + 交付物)。
---
## 10_organization.md — 第五部分 项目组织实施、保障措施及风险分析
## 10_organization.md — 第五部分 组织实施、保障措施及风险分析
### 一、项目组织实施机制
#### (一) 项目组织管理方式
1. **项目总体组**: <组成 + 职责>
2. **课题技术组**: ...
3. **项目管理队伍**: ...
#### (二) 项目协调机制
每月通报 + 每季度交流 + 每半年总结 + 不定期技术研讨。
### 二、保障措施
- 制定 《项目管理办法》
- 财务管理 / 进度管理 / 质量管理 / 风险管理 / 安全保密 等
### 三、知识产权对策、成果管理及合作权益分配
> 限 500 字。三块: 知识产权 + 成果管理 + 合作权益分配。
### 四、风险分析及对策
#### 表 5-1 项目执行的严重风险
| 风险类型 | 严重程度 | 触发条件 | 应对措施 |
| 技术风险 | 高 | <例: 关键技术攻关延期> | <方案 A 方案 B 备选> |
| 进度风险 | 中 | <例: 示范单位配合度不足> | <早期接洽 + 协议绑定> |
| 团队风险 | 低 | <例: 核心成员流动> | <建立梯队 + 知识库> |
- 一、组织实施机制 (项目总体组 + 课题技术组 + 项目管理队伍 + 协调机制)
- 二、保障措施 (《项目管理办法》)
- 三、知识产权对策 (限 500 字)
- 四、风险分析 (表 5-1: 风险类型 / 严重程度 / 触发条件 / 应对措施;至少覆盖技术/进度/团队/应用 4 类)
---
## 11_team.md — 第六部分 研究团队
(人员表格,通常通过申报系统在线填,正文里只放课题/单位的人员合计概况)
人员表通过申报系统在线填,正文只放课题/单位的人员合计概况。
---
## 12_budget.md — 第七部分 经费预算
详见 `references/budget_rules.md`。表格:
- 表 X-1 项目预算总表
- 表 X-2 各课题预算汇总
- 表 X-3 设备费明细 (50 万以上)
- 预算说明 (1000 字)
详见 `references/budget_rules.md`。表: 项目预算总表 / 各课题预算汇总 / 设备费明细 (50 万+) / 预算说明 (1000 字三性论证)。
---
## 13_appendix.md — 第八部分 指南所要求的附件
清单 (按指南要求勾选):
- [ ] 申报单位法人证书
- [ ] 主要参与单位合作协议 (盖章)
- [ ] 推荐单位推荐函

View File

@ -1,261 +1,184 @@
# 国家科技重大专项 课题任务书章节框架 (major_project)
> 申报立项后的**课题任务书**模板。复制到 `<task_dir>/sections/`,逐章填充。
> 与申报书阶段不同: 任务书 = 把申报书的承诺**落到具体的考核条款**, 一旦签字就是合同。
立项后的**课题任务书**(不是申报书)。复制对应小节到 `<task_dir>/sections/`。一旦签字就是合同。
---
## 00_basic_info.md — 课题基本信息表 (38 行表)
## 00_basic_info.md — 课题基本信息表
按下表逐行填:
- 课题名称 / 课题编号 (来自立项批复, 形如 2025ZD0XXXXXX) / 所属项目名称 / 项目编号
字段:
- 课题名称 / 课题编号 (来自立项批复 `2025ZD0XXXXXX`) / 所属项目名称 / 项目编号
- 所属重大专项 / 密级 (公开/秘密/机密)
- **课题成果技术就绪度** (TRL 9 级勾选):
- 1.发现基本原理 / 2.形成技术方案 / 3.方案通过验证
- 4.形成单元并验证 / 5.形成分系统并验证 / 6.形成原型并验证
- 7.现实环境的应用验证 / 8.用户验证认可 / 9.得到推广应用
- **TRL 9 级勾选**: 1 基本原理 / 2 技术方案 / 3 方案验证 / 4 单元验证 / 5 分系统验证 / 6 原型验证 / 7 现实环境应用验证 / 8 用户验证认可 / 9 推广应用
- 课题成果应用的主要国民经济行业
- 课题的社会经济目标 (一级 / 二级)
- 经费预算 (总预算 + 中央财政 + 地方财政 + 单位自筹 + 其他渠道)
- 课题周期节点 (起始 / 结束 / 实施周期 / 里程碑节点 1, 2, ...)
- 课题牵头单位 (单位名称 / 性质 / 主管部门 / 隶属关系 / 所属地区 / 通信地址 / / 法定代表人 / 组织机构代码 / 单位开户名称 / 开户银行 / 银行账号 / 银行机构代码 / 汇入地点)
- 课题负责人 / 联系人 / 财务负责人 (各自: 姓名/性别/出生日期/证件类型/号码/所在单位/最高学位/职称/职务/邮箱/电话)
- 经费预算 (总+中央财政+地方+自筹+其他)
- 课题周期节点 (起始 / 结束 / 实施周期 / 里程碑节点)
- 课题牵头单位 (单位名称/性质/主管部门/隶属/所属地区/通信地址/邮编/法定代表人/组织机构代码/单位开户名称/开户银行/银行账号/银行机构代码/汇入地点)
- 课题负责人 / 联系人 / 财务负责人 (姓名/性别/出生/证件/单位/学位/职称/职务/邮箱/电话)
- 其他参与单位
- 课题参加人数: 高级 X / 中级 X / 初级 X / 其他 X; 博士 X / 硕士 X / 学士 X / 其他 X
- 课题简介 (500 字以内)
- 课题简介 (500 字)
---
## 01_objectives.md — 一、课题目标及考核指标、评测方式/方法
## 01_objectives.md — 一、课题目标及考核指标、评测方式
### 课题目标
### 课题目标 (每项 ≤500 字, 主要成果 ≤5 项)
> 每项 500 字以内,从 5 方面明确描述:
> 1. 研发主要针对什么问题和需求
> 2. 将要解决哪些科学问题、突破哪些核心/共性/关键技术
> 3. 预期成果
> 4. 成果将以何种方式应用在哪些领域/行业/重大工程
> 5. 拟在科技、经济、社会、环境或国防安全等方面发挥何种作用和影响
```
课题目标 1: <一句标题>
本课题针对 <问题与需求>, 解决 <科学问题/关键技术>, 预期形成 <成果列表>
成果以 <应用方式> 应用在 <领域>, 在 <经济/社会/环境/国防> 等方面 <发挥作用>
课题目标 2: ...
课题目标 N: ... (主要成果原则上不超过 5 项)
```
5 方面明确描述:
1. 研发主要针对什么问题和需求
2. 解决哪些科学问题、突破哪些核心/共性/关键技术
3. 预期成果
4. 成果以何种方式应用在哪些领域/行业/重大工程
5. 拟在科技、经济、社会、环境或国防安全等方面发挥何种作用和影响
### 课题目标、成果与考核指标表 (核心表)
| 课题目标 (500字) | 成果名称 | 成果简述 | 成果类型 | 指标名称 | 立项时已有指标值/状态 | 立项时重点国别指标值/状态 | 里程碑节点 1 指标值/状态 | 完成时指标值/状态 | 考核方式 |
|---|---|---|---|---|---|---|---|---|---|
| 课题目标 1 | 1: <成果名> | <简述> | □软件 □平台 □... | 指标 1.1 | 无 | / | <中间值> | <终态值> | <CNAS/CMA 测试 / 测试大纲专家评审 / 应用示范报告> |
列: 课题目标 / 成果名称 / 成果简述 / 成果类型 / 指标名称 / 立项时已有指标值 / 立项时重点国别值 / 里程碑节点 1 值 / 完成时值 / 考核方式
成果类型 17 选 (打勾): 新理论 / 新原理 / 新产品 / 新技术 / 新方法 / 关键部件 / 数据库 / 软件 / 平台 / 应用解决方案 / 实验装置/系统 / 临床指南/规范 / 工程工艺 / 标准 / 论文 / 发明专利 / 其他
### 科技报告考核指标表
| 序号 | 报告类型 | 数量 | 提交时间 | 公开类别及时限 |
| 1 | 最终科技报告 | 1 | 综合绩效评价前 | 公开 / 延期 X 年 (论文≤2,专利≤3,技术诀窍≤5) |
| 2 | 年度技术进展报告 | N (研究期 ≥2 年的项目, 每年 1 份) | 每年底 | 公开 / 延期 |
| 1 | 最终科技报告 | 1 | 综合绩效评价前 | 公开 / 延期 |
| 2 | 年度技术进展报告 | N (期 ≥2 年, 每年 1 份) | 每年底 | 公开 / 延期 |
| 3 | 专题科技报告 | N | 课题中 | 公开 / 延期 |
延期时限: 论文≤2 年, 专利/专著≤3 年, 技术诀窍≤5 年。
---
## 02_content.md — 二、课题研究内容、研究方法及技术路线
### (一) 课题的主要研究内容
> 拟解决的关键科学问题、关键技术问题, 针对这些问题拟开展的主要研究内容,**限 3000 字以内**。
### (二) 课题采取的研究方法
> 针对课题研究拟解决的问题, 拟采用的方法、原理、机理、算法、模型等,**限 4000 字以内**。
### (三) 技术路线
(配图)
- (一) 主要研究内容 — 限 3000 字 (拟解决的关键科学/技术问题 + 主要研究内容)
- (二) 研究方法 — 限 4000 字 (方法/原理/机理/算法/模型)
- (三) 技术路线 — 配图
---
## 03_innovation.md — 三、主要创新点 (可选)
## 03_innovation.md — 三、主要创新点 (可选, 每条 ≤500 字)
> 围绕产品研发、应用验证、其他保障等层面,简述课题的主要创新点。每项创新点描述**限 500 字以内**。
```
1. 创新点 1: <名称>
<按三特征公式: 基本形态 (新方法/新模型/...) + 前沿性时效性 + 方法/理论/知识产权特征>
2. 创新点 2: ...
```
围绕产品研发 / 应用验证 / 其他保障层面。三特征公式: 基本形态 + 前沿性时效性 + 方法/理论/知识产权特征。
---
## 04_benefit.md — 四、预期经济社会效益
## 04_benefit.md — 四、预期经济社会效益 (限 1000 字)
> 课题的科学、技术、产业预期指标及科学价值、社会、经济、生态效益,**限 1000 字以内**
科学、技术、产业预期指标 + 科学价值、社会、经济、生态效益。
---
## 05_schedule.md — 五、课题年度计划
> 按每 6 个月制定形成课题计划进度,把考核指标分解到年度
按每 6 个月制定。每档写: 任务 / 考核指标 / 成果形式
```
1、年度: X 年 X 月 — X 年 X 月
任务: < 1 6 个月做什么>
考核指标: < 6 个月对应的指标值/状态>
成果形式: <文档/原型/测试报告>
2、年度: X 年 X 月 — X 年 X 月
...
任务: ...
考核指标: ...
成果形式: ...
```
### 关键节点、里程碑事件和关键指标
```
项目关键节点: X 年 X 月
里程碑事件: <事件描述>
关键指标: <这个节点必须达到的指标>
考核方式: <CNAS/CMA / 测试大纲专家评审 / 应用示范报告>
交付物: <报告 / 软件 / 原型>
```
时间点 / 事件 / 关键指标 / 考核方式 / 交付物。
---
## 06_organization.md — 六、课题组织实施机制及保障措施
## 06_organization.md — 六、组织实施机制及保障措施
> 三块, 分别字数限制:
```
1、课题的内部组织管理方式、协调机制等 (限 1000 字)
2、课题实施的相关政策、已有的组织、技术基础、支撑保障条件 (限 1000 字)
3、对实现项目总目标的支撑作用,及与项目内其他课题的协同机制 (限 500 字)
```
- 1、内部组织管理方式、协调机制 — 限 1000 字
- 2、实施政策、组织技术基础、保障条件 — 限 1000 字
- 3、对项目总目标的支撑作用、与其他课题协同 — 限 500 字
---
## 07_ip.md — 七、知识产权对策、成果管理及合作权益分配
## 07_ip.md — 七、知识产权对策、成果管理及合作权益分配 (限 500 字)
> **限 500 字以内**。三块:
> 1. 知识产权归属 / 使用 / 监督
> 2. 成果管理制度
> 3. 合作权益分配原则
3 块: 知识产权归属/使用/监督 + 成果管理制度 + 合作权益分配原则。
---
## 08_terms.md — 八、需要约定的其他内容 (条款式)
## 08_terms.md — 八、需要约定的其他内容
定型 12 条左右,**抄即可**,只在最后一条加自定义:
定型 11 条 (照抄) + 自定第 12 条:
```
第一条 乙方应积极配合项目管理专业机构对项目开展的监督、检查、评估评价等过程管理工作,
应每 12 个月向甲方报告项目执行情况及下 12 个月工作计划,项目实施关键节点的重大会议、
活动应邀请甲方和项目责任专家参加。
第二条 乙方与所有课题参与单位是课题的实施主体,对课题目标完成负全责。乙方应遵守甲方制定的
项目内部管理制度和实施工作计划。
第三条 乙方是课题资金管理使用的责任主体,负责课题资金的日常管理和监督。...
第四条 乙方是保障课题科研过程安全的责任主体, ...
第五条 乙方应建立健全本单位学术论文发表诚信承诺制度、科研过程可追溯制度、 ...
第六条 在项目实施过程中,乙方应加强对课题参与单位的科研诚信管理, ...
第七条 乙方课题任务书的项目目标、研究内容及考核指标等有关内容必须完全覆盖项目申报指南的
相应内容,且不得低于申报指南及项目申报书确定的内容。
第八条 ...
第九条 ...
第十条 ...
第十一条 ...
第十二条 (其他约定内容) <TODO 课题特有的约定>
第一条 乙方应配合项目管理专业机构开展监督、检查、评估评价等过程管理工作, 每 12 个月报告项目执行情况...
第二条 乙方与所有课题参与单位是课题的实施主体, 对课题目标完成负全责...
第三条 乙方是课题资金管理使用的责任主体, 负责日常管理和监督...
第四条 乙方是保障课题科研过程安全的责任主体, 应建立健全安全管理制度...
第五条 乙方应建立健全本单位学术论文发表诚信承诺制度、科研过程可追溯制度...
第六条 在项目实施过程中, 乙方应加强对课题参与单位的科研诚信管理...
第七条 乙方课题任务书的项目目标、研究内容及考核指标必须完全覆盖项目申报指南的相应内容,
且不得低于申报指南及项目申报书确定的内容。
第八条 ... (按管理办法增补)
第十二条 (其他约定内容) <TODO 课题特有>
```
---
## 09_personnel.md — 九、课题参加人员基本情况表
| 序号 | 姓名 | 性别 | 出生日期 | 证件类型 | 证件号码 | 专业技术职称 | 职务 | 最高学位 | 专业 | 投入本课题的全时工作时间 (人月) | 人员分类代码 | 在课题中分担的任务 | 是否有工资性收入 | 工作单位 |
列: 序号 / 姓名 / 性别 / 出生 / 证件 / 专业技术职称 (A 正高 / B 副高 / C 中级 / D 初级 / E 其他) / 职务 / 最高学位 / 专业 / 投入全时工作时间 (人月) / 人员分类代码 / 在课题中分担的任务 / 是否有工资性收入 / 工作单位
填表说明:
- 专业技术职称: A 正高级 / B 副高级 / C 中级 / D 初级 / E 其他
- 投入全时工作时间 = 课题实施期间总月度工作量
- 固定研究人员合计 / 流动或临时聘用人员合计 / 累计 三行汇总
汇总: 固定研究人员合计 / 流动或临时聘用合计 / 累计。
---
## 10_budget.md — 十、经费预算
### 表 B1 课题 (课题编号) 承担单位基本情况表
详见 `references/budget_rules.md`
(单位名称/性质/主管部门/法定代表人/组织机构代码/开户名称/开户银行/银行账号/汇入地点 等)
### B1 课题承担单位基本情况表
### B2 课题预算表 (单位: 万元)
### 表 B2 课题预算表 (单位: 万元)
| 序 | 预算科目 | 金额 |
| 1 | 一、中央财政专项资金 | |
| 2 | (一) 直接费用 | |
| 3 | 1. 设备费 | |
| 4 | 其中: 购置设备费 | |
| 5 | 2. 业务费 | |
| 6 | 3. 劳务费 | |
| 7 | (二) 间接费用 | |
| 8 | 二、其他来源资金 | |
| 9 | 三、合计 | |
| 序号 | 预算科目名称 | 金额 |
| 1 | 一、中央财政专项资金 | XXX |
| 2 | (一) 直接费用 | XXX |
| 3 | 1. 设备费 | XX |
| 4 | 其中: 购置设备费 | X |
| 5 | 2. 业务费 | XX |
| 6 | 3. 劳务费 | XX |
| 7 | (二) 间接费用 | XX |
| 8 | 二、其他来源资金 | XXX |
| 9 | 三、合计 | XXX |
注: 间接费用按直接费用扣除设备购置费后的台阶: ≤500 万部分 ≤30% / 500-1000 万 ≤25% / >1000 万 ≤20%。绩效支出无比例限制, 与贡献挂钩。
注:
1. 间接费用无需编制预算说明
2. 间接费用实行总额控制, 按直接费用扣除设备购置费后的台阶比例核定:
① ≤500 万部分 不超过 30%
② 500-1000 万部分 不超过 25%
③ >1000 万部分 不超过 20%
3. 绩效支出在间接费用中无比例限制, 与科研人员实际贡献挂钩
### B3 设备费 — 购置/试制设备预算明细表 (单价 50 万以上)
### 表 B3 设备费 — 购置/试制设备预算明细表 (单价 50 万以上)
序号 / 设备名称 / 设备分类 / 功能技术指标 / 单价(万元/台) / 数量 / 金额 / 购置或试制单位 / 安置单位 / 设备类型 (通用/专用) / 主要厂家及国别 / 规格型号 / 拟开放共享范围。
| 序号 | 设备名称 | 设备分类 | 功能和技术指标 | 单价 (万元/台套) | 数量 | 金额 | 购置或试制单位 | 安置单位 | 购置设备类型 | 主要厂家及国别 | 规格型号 | 拟开放共享范围 |
### B4 课题单位经费预算明细表
### 表 B4 课题单位经费预算明细表
序号 / 单位名称 / 组织机构代码 / 单位类型 / 任务分工 / 研究任务负责人 / 合计 / 中央财政 (小计 + 间接费用) / 其他来源资金。
| 序号 | 单位名称 | 组织机构代码/统一社会信用代码 | 单位类型 | 任务分工 | 研究任务负责人 | 合计 | 中央财政专项资金 (小计 + 间接费用) | 其他来源资金 |
### 预算说明
> 见 `references/budget_rules.md` § 7。**任务相关性 + 政策相符性 + 经济合理性**三性必涵盖。
### 预算说明 (1000 字, 三性: 任务相关性 + 政策相符性 + 经济合理性)
### 其他来源资金承诺书 (有自筹的)
```
(单位全称), 为 <课题名> 课题, 提供 XX 万元的资金,
资金来源为 (1.地方财政资金 / 2.单位自筹资金 / 3.其他渠道获得资金)。
(单位全称), 为 <课题名> 课题, 提供 XX 万元的资金, 资金来源为
(1.地方财政资金 / 2.单位自筹 / 3.其他渠道)。
资金主要用于: <用途>
特此证明!
出资单位 (公章):
年 月 日
出资单位 (公章): 年 月 日
```
---
## 11_appendix.md — 十一、相关附件
清单:
- [ ] 乙方与参加单位有关协议 (须加盖乙方与参加单位公章、法人签字签章; 协议文件须扫描上传)
- [ ] 乙方与参加单位有关协议 (公章 + 法人签字, 扫描上传)
- [ ] 申报指南规定的其他附件
任务书签署:
```
课题承担单位 (乙方)
法定代表人签字 (签章):
(公章)
年 月 日
课题负责人签字 (签章):
年 月 日
法定代表人签字 (签章): (公章)
课题负责人签字 (签章): 年 月 日
```

View File

@ -1,138 +1,76 @@
# NSFC 联合基金 / 面上 / 青年 申请书章节框架 (nsfc_joint_fund / nsfc_general / nsfc_youth)
# NSFC 联合基金 / 面上 / 青年 申请书章节框架
> 报告正文 (2026 版) — 三大段固定结构。**提纲标题与括号文字一字不改**。
> 联合基金重点支持项目: 立项依据与研究内容 5000-10000 字
> 面上 / 青年: 立项依据与研究内容 5000-8000 字
报告正文 (2026 版) — 三大段固定结构。**提纲标题与括号文字一字不改**。
| 类型 | 立项依据与研究内容 字数 |
|----|----|
| `nsfc_joint_fund` 联合基金重点支持 | 5000-10000 |
| `nsfc_general` 面上 / `nsfc_youth` 青年 (C) | 5000-8000 |
---
## 01_research_content.md — (一) 立项依据与研究内容
> 建议 5000-10000 字。下列 6 节按顺序写。
### 1. 本项目申请的项目指南研究方向名称
> **严格按照项目指南填写**。一字不改。
```
<指南方向名称, 直接抄指南文件>
```
(青年/面上无指南方向, 写成"研究方向: <自由选题方向>")
**严格按指南填写,一字不改**。青年/面上无指南方向,写"研究方向: <自由选题方向>"。
### 2. 项目的立项依据
> 研究意义、国内外研究现状及发展动态分析,需结合科学研究发展趋势来论述科学意义;
> 或结合国民经济和社会发展中迫切需要解决的关键科技问题来论述其应用前景。
> 附主要参考文献目录。
三段式 (见 `references/section_templates.md` § 2):
三段式 (现状 40% / 痛点 30% / 切入点 30%):
```
2.1 研究意义
<从科学价值 / 应用前景 / 国家战略需求三个维度论述, 1-2 >
2.2 国内外研究现状及发展动态
<按子方向分 3-5 >
2.1 研究意义 (1-2 段, 科学价值 / 应用前景 / 国家战略)
2.2 国内外研究现状及发展动态 (按子方向分 3-5 块)
(1) <子方向 1>
国外: <最近 3-5 年代表性团队 + 文献 [1][2]>
国内: <最近 3-5 年代表性团队 + 文献 [3][4]>
小结: 虽然 ... 但 ... 仍未解决 ...
(2) <子方向 2>
...
(2) <子方向 2> ...
2.3 发展动态与本项目切入点
<综上, 当前研究在 X 方面已取得进展, 但在 Y 方面仍存在 <具体差距>
本项目<切入点> 入手, 解决 <关键科学问题>, 取得 <预期突破>>
综上, 当前在 X 已取得进展, 但在 Y 仍存在 <具体差距>
本项目从 <切入点> 入手, 解决 <关键科学问题>, 取得 <预期突破>
主要参考文献
[1] 作者. 题名[J]. 刊名, 年(期): 页码.
[2] ...
```
### 3. 项目的研究内容、研究目标,以及拟解决的关键科学问题 ← 重点
### 3. 项目的研究内容、研究目标拟解决的关键科学问题 ← 重点
```
3.1 研究内容
本项目围绕 N 个关键科学问题, 开展 M 项研究内容:
研究内容 1: <名称>
<针对 X, 提出 Y 方法, 突破 Z 子问题, 200-300 >
研究内容 2: ...
... (共 4-6 项)
本项目围绕 N 个关键科学问题, 开展 M 项研究内容:
研究内容 1: <名称> — 针对 X, 提出 Y, 突破 Z。 (200-300 字)
研究内容 2: ...
3.2 研究目标
总目标: <一段, 紧扣关键科学问题>
子目标 1: ...
子目标 2: ...
预期成果: 论文 N 篇, 专利 N 项, ...
总目标: <一段, 紧扣关键科学问题>
子目标 1/2: ...
预期成果: 论文 N 篇, 专利 N 项, ...
3.3 拟解决的关键科学问题
关键科学问题 1: <提炼成 1 句话, 不要写成"研究 XXX 技术">
<为什么这是关键? 现有方法为什么不行? 突破点在哪?>
关键科学问题 2: ...
(NSFC 评审最看重这一节, 关键科学问题必须提炼到位 — 不是任务, 是科学问题)
关键科学问题 1: <提炼成 1 , 不要写成"研究 XXX 技术">
为什么是关键? 现有方法为什么不行? 突破点在哪?
关键科学问题 2: ...
```
NSFC 评审最看这一节,关键科学问题必须**提炼到位** — 不是任务,是问题。
### 4. 拟采取的研究方案及可行性分析
```
4.1 研究方法
<针对每个研究内容, 给出方法/原理/算法/模型>
4.2 技术路线
[图 X-X 项目总体技术路线]
<"方法 1 方法 2 方法 3 集成验证"流程描述>
4.3 实验手段
<实验平台 / 数据集 / 仿真工具>
4.4 关键技术
<列出 3-5 项关键技术, 每项简述>
4.5 可行性分析
- 理论可行性: <已有理论基础>
- 技术可行性: <团队前期成果 + 已有技术积累>
- 条件可行性: <实验条件 + 数据 + 平台>
```
研究方法 / 技术路线 (含图) / 实验手段 / 关键技术 / 可行性 (理论 + 技术 + 条件)。
### 5. 本项目的特色与创新之处
```
特色 1: <方法论上的特色>
特色 2: <场景上的特色>
创新点 1 (方法/理论): <具体创新>
创新点 2 (技术): <具体创新>
创新点 3 (应用): <具体创新>
```
特色 1-2 (方法 / 场景) + 创新点 1-3 (方法/理论 / 技术 / 应用)。
### 6. 年度研究计划及预期研究结果
> 包括拟组织的重要学术交流活动、国际合作与交流计划。
```
第 1 年 (X 年 X 月 - X 年 X 月):
研究内容: ...
预期成果: ...
交流计划: ...
第 2 年:
...
第 3 年:
...
第 4 年 (4 年期项目):
研究内容: 总结提炼, 形成完整理论体系
预期成果: 发表代表性论文 X 篇 (其中 SCI/EI 收录 Y 篇), 申请专利 Z 项, 学位论文 N 篇
总结: 课题验收, 资料归档
国际合作与交流:
<访问 X 学者 / 邀请 Y 学者 / 参加 Z 国际会议>
```
按年度展开 (3-4 年, 视基金类型),每年: 研究内容 + 预期成果 + 交流计划。
+ 国际合作与交流: 访问 / 邀请 / 国际会议。
---
@ -140,114 +78,28 @@
### 1. 研究基础
> 与本项目相关的研究工作积累和已取得的研究工作成绩。
```
申请人在 <方向> 方面有 <N > 研究积累, 主要工作:
- 工作 1: < X 期刊/会议上发表 Y 论文, 提出 Z 方法>
- 工作 2: ...
- 工作 3: ...
已取得成绩:
- 论文 N 篇 (SCI 收录 X 篇, 第一作者/通讯作者 Y 篇)
- 授权专利 N 项
- 主持/参与项目 N 项
- 获奖 N 项
```
申请人 N 年研究积累, 主要工作 (1, 2, 3) + 已取得成绩 (论文 / 专利 / 项目 / 获奖)。
### 2. 工作条件
> 已具备的实验条件,尚缺少的实验条件和拟解决的途径,包括利用国家实验室、全国重点实验室和部门重点实验室等研究基地的计划与落实情况。
```
已具备:
- 依托 <X 重点实验室>, 拥有 <Y 设备>
- 计算资源: <服务器/集群/GPU>
- 数据资源: <数据集/数据库>
- 软件平台: <已有软件>
尚缺少:
- <Z 设备>
拟解决途径:
- 通过本项目经费购置 / 与 <X 单位> 合作共享 / 利用国家重点实验室开放基金
```
已具备 (国重 / 实验设备 / 算力 / 数据 / 软件) + 尚缺少 + 解决途径 (经费购置 / 共享 / 开放基金)。
### 3. 正在承担的与本项目相关的科研项目情况
> 申请人和主要参与者正在承担的与本项目相关的科研项目情况, 包括 NSFC 的项目和国家其他科技计划项目, 要注明: 项目的资助机构、项目类别、批准号、项目名称、获资助金额、起止年月、与本项目的关系及负责的内容
每项: 项目名称 / 资助机构 / 项目类别 / 批准号 / 资助金额 / 起止年月 / **与本项目关系 (说明无重复)** / 负责内容。申请人 + 主要参与者均要列。
```
1. 申请人: 张三
(1) 项目名称: <项目名>
资助机构: 国家自然科学基金委
项目类别: 面上项目
批准号: 619XXXXX
获资助金额: 60 万元
起止年月: 2024.01 - 2027.12
与本项目关系: <在某子方向有衔接, 但研究目标和方法不同; 无重复>
负责内容: ...
### 4. 完成 NSFC 项目情况 (适用于结题过的)
(2) ...
2. 主要参与者: 李四
...
```
### 4. 完成国家自然科学基金项目情况
> 对申请人负责的前一个已资助期满的科学基金项目 (项目名称及批准号) 完成情况、后续研究进展及与本申请项目的关系加以详细说明。
> 另附该项目的研究工作总结摘要 (限 500 字) 和相关成果详细目录。
```
项目名称: <项目名>
批准号: 619XXXXX
完成情况: <按计划完成 / 提前完成 / 延期 X >
后续研究进展: <在结题后继续推进了 X 方向, 取得 Y 进展>
与本申请的关系: <本申请是该项目的延伸, Z 方向开拓>
工作总结摘要 (限 500 字):
<总结项目完成情况主要科学发现代表性成果, 严格控字>
成果详细目录:
论文:
[1] ...
[2] ...
专利:
[1] ...
项目验收等级: < / / 合格>
```
项目名称 / 批准号 / 完成情况 / 后续研究进展 / 与本申请的关系 + 工作总结摘要 (≤500 字) + 成果详细目录 + 验收等级。无则填"无"。
---
## 03_other.md — (三) 其他需要说明的情况
```
1. 申请人同年申请不同类型的国家自然科学基金项目情况
<若有, 列明同年申请的其他项目的项目类型项目名称信息, 并说明与本项目之间的区别与联系;
已收到自然科学基金委不予受理或不予资助决定的, 无需列出>
<若无, "">
2. 具有高级专业技术职务 (职称) 的申请人或者主要参与者是否存在同年申请或者参与申请国家自然科学基金项目的单位不一致的情况
<若有, 列明所涉及人员的姓名, 申请或参与申请的其他项目的项目类型项目名称单位名称上述人员在该项目中是申请人还是参与者, 并说明单位不一致原因>
3. 具有高级专业技术职务 (职称) 的申请人或者主要参与者是否存在与正在承担的国家自然科学基金项目的单位不一致的情况
<若有, 列明姓名批准号项目类型项目名称单位名称起止年月, 并说明单位不一致原因>
4. 申请人和主要参与者同年以不同专业技术职务 (职称) 申请或参与申请科学基金项目的情况
<详细说明原因>
其他:
<如有其他情况一并说明; 无则写"">
1. 同年申请不同类型 NSFC 项目情况: <若有,列项目类型与名称,说明区别与联系;否则"">
2. 高级职称申请人/参与者 同年申请其他 NSFC 项目时单位不一致情况: <说明>
3. 高级职称申请人/参与者 与正在承担 NSFC 项目单位不一致情况: <说明>
4. 申请人和主要参与者 同年以不同专业技术职务申请的情况: <说明>
其他: < / 其他要说明的>
```
---
## 字数自查
写完后用 `python skills/proposal/scripts/word_count.py <task_dir>/sections/ --fund-type nsfc_joint_fund` 核对:
| 章节 | 联合基金重点 | 面上 | 青年 |
|----|----|----|----|
| (一) 立项依据与研究内容 | 5000-10000 | 5000-8000 | 5000-8000 |
| (二) 研究基础与工作条件 | 1500-3000 | 1500-3000 | 1500-3000 |
| (三) 其他需要说明的情况 | 200-500 | 200-500 | 200-500 |

View File

@ -0,0 +1,94 @@
# 申报书 spec_lock
> 阶段一产物。**写定后不再改**,阶段二每章前都要 read。`<TODO>` 是占位符,需要用户明确填值;不要硬编。
## 1. 基金类型
`<TODO 基金类型代码>` (key_rd / major_project / nsfc_joint_fund / nsfc_general / nsfc_youth / provincial / enterprise)
对应资助强度: `<TODO>` 万元 / `<TODO>`
## 2. 指南方向
> **一字不改**抄指南文本。无指南 (青年/横向) 填研究方向。
```
<TODO 指南原文 项目名称 / 所属专项 / 指南方向 (榜单任务) / 创新分类>
```
## 3. 关键科学问题 / 关键技术问题
(1-2 个,与指南对齐;**问题 ≠ 任务**)
- 关键问题 1: `<TODO 一句话提炼,不是"研究 XXX 技术">`
- 关键问题 2: `<TODO ...>`
## 4. 创新点
(≤3 条,每条 ≤500 字。三特征公式: 基本形态 + 前沿性 + 知识产权特征)
- 创新点 1: `<TODO 标题 + 50 字摘要>`
- 创新点 2: `<TODO ...>`
- 创新点 3: `<TODO ...>`
## 5. 研究内容骨架 / 课题分解
| # | 名称 | 牵头单位 | 关键技术 | 经费占比 |
|---|---|---|---|---|
| 1 | `<TODO>` | `<TODO>` | `<TODO>` | XX% |
| 2 | `<TODO>` | `<TODO>` | `<TODO>` | XX% |
| ... |
(重点研发/重大专项必须分课题,通常 4-6 个;NSFC 面上/青年填 3-5 项研究内容即可)
## 6. 团队
### 牵头单位
`<TODO 单位名称>` —— `<TODO 一句话定位 / 关键资质>`
### 项目/课题负责人
`<TODO 姓名 + 职称 + 学位 + 研究方向>` —— 在本项目中承担 `<TODO 角色>`
### 主要参与单位 (按重要性)
- `<TODO 单位 1>` — 定位 + 在本项目中承担 X
- `<TODO 单位 2>` — ...
## 7. 考核指标矩阵 ← 阶段三 quality_check 会读这一节
> 一行一条指南指标。**指南那栏字面抄,不能改写**;本项目那栏可超出,不能低于。
| # | 指南考核指标 (字面抄) | 本项目考核指标 (量化) | 评测方式 | 验收交付物 |
|---|---|---|---|---|
| 1 | `<TODO 抄指南>` | `<TODO 量化, 等于或超出>` | CNAS/CMA / 测试大纲 / 应用示范报告 | `<TODO>` |
| 2 | `<TODO>` | `<TODO>` | `<TODO>` | `<TODO>` |
| ... |
## 8. 经费预算
| 科目 | 金额 (万元) | 备注 |
|---|---|---|
| 中央财政 | `<TODO>` | |
| 直接费用 - 设备费 | `<TODO>` | 50 万以上需 B3 表 |
| 直接费用 - 业务费 | `<TODO>` | |
| 直接费用 - 劳务费 | `<TODO>` | 仅给临时聘用 |
| 间接费用 | `<TODO>` | 台阶: ≤500 万≤30% / 500-1000≤25% / >1000≤20% |
| 自筹 / 其他 | `<TODO>` | 应用示范类常需 ≥1:1 配套 |
| **合计** | `<TODO>` | 与指南资助量级匹配 |
## 9. TODO 列表
> 阶段一过程中冒出来的"等用户提供"事项。阶段二每章开头扫一眼;阶段三 quality_check 会扫余留的 `<TODO>`
- [ ] `<TODO 比如:索取团队代表性论文清单>`
- [ ] `<TODO 比如:确认设备购置型号>`
- [ ] `<TODO ...>`
## 10. 引文清单 (用户提供)
> 编造文献是学术不端。引文必须用户给清单 — 这里粘 BibTeX/EndNote/纯文本均可,阶段三按 GB/T 7714 排版。
```
[1] <TODO 用户提供>
[2] <TODO>
...
```