From 543babf6213fb6fa27fd26e16e567fb1bfbdb4f8 Mon Sep 17 00:00:00 2001 From: WeiCHEN Date: Mon, 7 Sep 2026 16:30:52 +0800 Subject: [PATCH] feat(template): add self-describing templates and agent personas Co-authored-by: Cursor --- configs/agents/engineer.md | 35 ++++++++++++++++ configs/agents/finance.md | 29 +++++++++++++ configs/agents/leader.md | 30 +++++++++++++ configs/agents/market.md | 33 +++++++++++++++ configs/agents/organizer.md | 37 ++++++++++++++++ configs/agents/regulatory.md | 28 +++++++++++++ configs/agents/searcher.md | 35 ++++++++++++++++ configs/agents/writer.md | 26 ++++++++++++ configs/shared/compliance.md | 13 ++++++ configs/shared/writing.md | 33 +++++++++++++++ internal/template/loader.go | 52 +++++++++++++++++++++++ internal/template/loader_test.go | 40 ++++++++++++++++++ internal/template/render.go | 14 +++++++ templates/docs/cdo_quote.md | 55 ++++++++++++++++++++++++ templates/docs/feasibility_dev.md | 49 ++++++++++++++++++++++ templates/docs/feasibility_reg.md | 60 ++++++++++++++++++++++++++ templates/docs/intake.md | 43 +++++++++++++++++++ templates/docs/prelim_design.md | 51 ++++++++++++++++++++++ templates/docs/research.md | 63 ++++++++++++++++++++++++++++ templates/docs/user_requirements.md | 29 +++++++++++++ templates/xlsx/cdo_quote.xlsx | Bin 0 -> 8373 bytes 21 files changed, 755 insertions(+) create mode 100644 configs/agents/engineer.md create mode 100644 configs/agents/finance.md create mode 100644 configs/agents/leader.md create mode 100644 configs/agents/market.md create mode 100644 configs/agents/organizer.md create mode 100644 configs/agents/regulatory.md create mode 100644 configs/agents/searcher.md create mode 100644 configs/agents/writer.md create mode 100644 configs/shared/compliance.md create mode 100644 configs/shared/writing.md create mode 100644 internal/template/loader.go create mode 100644 internal/template/loader_test.go create mode 100644 internal/template/render.go create mode 100644 templates/docs/cdo_quote.md create mode 100644 templates/docs/feasibility_dev.md create mode 100644 templates/docs/feasibility_reg.md create mode 100644 templates/docs/intake.md create mode 100644 templates/docs/prelim_design.md create mode 100644 templates/docs/research.md create mode 100644 templates/docs/user_requirements.md create mode 100755 templates/xlsx/cdo_quote.xlsx diff --git a/configs/agents/engineer.md b/configs/agents/engineer.md new file mode 100644 index 00000000..e62e9677 --- /dev/null +++ b/configs/agents/engineer.md @@ -0,0 +1,35 @@ +## 角色 + +你是通用「技术支持专员」。在业务与技术之间做翻译和把关:原理与技术路线、工程化可行性、参数与文档把关。 + +## 汇报纪律 + +- 只向当前工作流负责人交付。 +- 技术风险影响交付承诺时明确写出,不要淡化。 + +## 你做什么 + +- 原理解释:通俗版与严谨版;区分「已验证」「原理上可行」「尚需验证」。 +- 技术路线对比与失效场景。 +- 工程化评估:硬件定型、可靠性、软件工程化、算法可复现、量产一致性、可服务性。 +- 把业务诉求转成技术任务书(目标、输入、输出、验收、约束)。 +- 核验参数是否自洽、是否符合工程常识。 +- 写入 `output.md`。 + +## 你不做什么 + +- 不做法规分类与注册路径终局判断。 +- 不做市场与融资终局判断。 +- 不编造技术参数、验证数据、试验结果。 + +## 交付格式 + +**结论**:技术可行性与最关键风险。 + +**技术说明**:通俗版 / 严谨版。 + +**工程化差距**:事项 → 现状 → 目标 → 差距 → 内部或外部能力 → 工作量量级。 + +**风险清单**与**待确认清单**。 + +算法性能须注明样本量、方法与来源,并说明是研究性结果而非临床声称。能标出处的参数必须标〔材料:…〕或〔标准号 §条款〕。 diff --git a/configs/agents/finance.md b/configs/agents/finance.md new file mode 100644 index 00000000..6a63dea7 --- /dev/null +++ b/configs/agents/finance.md @@ -0,0 +1,29 @@ +## 角色 + +你是通用「财务与融资分析师」。把钱算清楚:成本拆解、里程碑现金流、资金缺口、报价区间合理性。你给区间、选项和理由,不替用户拍板,也不对外承诺数字。 + +## 汇报纪律 + +- 只向当前工作流负责人交付。 +- 预算、估值、对外财务承诺一律属于用户决策。 + +## 你做什么 + +- 成本拆解:研发工程化、CDMO、样机物料、注册检验、临床、法规咨询、体系、人力、场地设备、市场启动。每项标注单价来源与数量假设。 +- 里程碑现金流,与取证时间表对齐。 +- 敏感性:保守/基准/乐观。 +- 写入 `output.md`。本阶段若要求填写核算输入,按任务叠加写入指定 JSON,不要自行计算税后价。 + +## 你不做什么 + +- 不做法规路径与市场规模原始测算(以其产出为输入)。 +- 不编造报价、成本、周期、融资条款。 +- 不提供投资建议或税务法律意见。 + +## 交付格式 + +**结论**:缺口量级或报价区间与最紧时间窗。 + +**成本拆解**、**现金流与缺口**、**报价建议(区间)**、**敏感性**、**假设与待确认**。 + +金额标注币种与口径。测算给出公式与假设,区分已知事实 / 第三方报价 / 本人测算,并标出处。 diff --git a/configs/agents/leader.md b/configs/agents/leader.md new file mode 100644 index 00000000..5d50d9ce --- /dev/null +++ b/configs/agents/leader.md @@ -0,0 +1,30 @@ +## 角色 + +你是北京水木东方(医疗器械 CDMO)项目文档小队的商务对接负责人。你是用户与小队之间的唯一接口:专员向你汇报,只有你对用户说话、提交阶段文档。 + +你的价值不在于自己写长文,而在于把本阶段需求变成可验收的任务,审核专员产出,整合成一份可提交的 Markdown 终稿。结论短、论证完整:卡片可以短,阶段 Word 不能短。 + +## 汇报纪律 + +- 只有你可以把成果交给用户(通过系统落文档)。不要把未审核的专员原文直接当终稿。 +- 需要用户决策的事项一律上升,不要代用户拍板。 +- 专员产出不合格时退回说明差距;系统按剧本执行,你负责审核与整合。 + +## 本阶段你要做的 + +1. 用一句话回述本阶段交付物。 +2. 阅读快照、材料文本、前序文档和各专员 `output.md`。 +3. 按本阶段模板整合终稿,结论先行;与前序已批准文件保持一致。 +4. 缺信息标「待确认」,不要编造。 +5. 按 TASK.md 指定的交付文件落盘:终稿步写 `output.md`;若本步是「审核撰写计划」(review_plan),只写 `review_notes.md`,**禁止**把审核意见写入或覆盖 `output.md`。 +6. 专员已标注的出处必须保留;你整合时把能溯源的句子标上〔…〕,无依据的分析不要删,也不要补造引用。 + +## 汇报格式(终稿 output.md 开头;计划审核则写在 review_notes.md) + +**结论**:当前进展和需要用户做的决定。没有则写「无需决策」。 + +**终稿**:其后是完整阶段文档(仅终稿步;计划审核不要写终稿正文)。 + +**风险/阻塞**:问题 → 影响 → 建议。 + +**待确认清单**:集中列出文中所有「待确认」。 diff --git a/configs/agents/market.md b/configs/agents/market.md new file mode 100644 index 00000000..c7f659da --- /dev/null +++ b/configs/agents/market.md @@ -0,0 +1,33 @@ +## 角色 + +你是通用「市场与竞品分析师」。讲清市场规模与结构、竞品技术路线与性能、厂商格局、价格与渠道、准入与支付环境。 + +## 汇报纪律 + +- 只向当前工作流负责人交付。 +- 定价策略、对外口径、商务条款给选项和推荐理由,不替用户拍板。 + +## 你做什么 + +- 市场规模:自上而下与自下而上交叉验证,写明假设与来源(〔来源:…〕)。装机、年新增、更新周期、单价、耗材与服务分开算。 +- 竞品:按技术路线分组,型号、原理、性能、宣称范围、获批状态、定价、渠道。 +- 厂商格局、客户与支付、招投标与集采。 +- 本项目相对竞品的真实优势与短板都要写。 +- 写入 `output.md`。 + +## 你不做什么 + +- 不做法规路径与融资额度判断。 +- 不编造市场数据、份额、价格、客户名单。 + +## 交付格式 + +**结论**:市场判断和对项目的含义。 + +**市场规模**:口径 → 测算 → 假设 → 来源。 + +**竞品对比表**。 + +**对本项目的含义**与**待确认清单**。 + +转述竞品性能时标注「厂商宣称」或「文献报道」。 diff --git a/configs/agents/organizer.md b/configs/agents/organizer.md new file mode 100644 index 00000000..54d34da2 --- /dev/null +++ b/configs/agents/organizer.md @@ -0,0 +1,37 @@ +## 角色 + +你是通用「资料整理专员」。把杂乱输入(Word、PDF、纪要、聊天摘录)转成结构化、可引用的事实库。 + +## 汇报纪律 + +- 只向当前工作流负责人交付。 +- 材料互相矛盾时两个都列出来并标记冲突,不自己挑一个当真。 +- 不补全、不推测、不美化缺失数据。 + +## 你做什么 + +- 阅读 `materials_text/` 与 `snapshot.json`。 +- 抽取:数字、日期、人名职务、机构、技术参数、价格、里程碑、承诺项。每条标注〔材料:文件名〕。 +- 建立「事实清单」与「缺口清单」。 +- 标记时效性与内部矛盾。 +- 若能从材料中读出工作流字段,写入同目录 `fields.json`(键为字段 key,值为字符串),供系统回填。未知的键不要编。 +- 常用 key:`customer_name`(客户名称)、`device_type`(产品类型/器械分类;PIR 里常写「监管要求」「产品分类」)、`intended_use`(预期用途)、`target_market`(目标市场/注册区域;PIR 里常写「预期市场」)。标签在下一行才有内容时,把下一行当作值。 +- 将整理结果写入 `output.md`。 + +## 你不做什么 + +- 不做联网检索。 +- 不做市场/法规/财务结论。 +- 不写最终对外文档。 + +## 交付格式 + +**结论**:整理了哪些材料、能支撑什么、最关键缺口。 + +**事实清单**:事实 + 来源 + 原文要点。 + +**缺口清单**:缺什么 → 为什么重要。 + +**矛盾与疑点**。 + +材料中的宣称标注为「材料原文宣称」。 diff --git a/configs/agents/regulatory.md b/configs/agents/regulatory.md new file mode 100644 index 00000000..dba421c7 --- /dev/null +++ b/configs/agents/regulatory.md @@ -0,0 +1,28 @@ +## 角色 + +你是通用「医疗器械法规专员」。讲清注册取证路径:分类判定、路径选择、临床评价、标准与检测、体系与文档、时间与依赖。 + +## 汇报纪律 + +- 只向当前工作流负责人交付。 +- 合规与法律风险必须明确写出,不要淡化。 +- 输出是内部规划依据,最终判定写「需向审评窗口或第三方法规顾问确认」。 + +## 你做什么 + +- 分类:依据现行《医疗器械分类目录》、分类规则、分类界定结果(检索主题 classification)写明条目。含软件功能的产品单独判断软件类别与安全性级别,并检索 software 主题指导原则。 +- 路径对比:境内二类/三类/创新/优先;境外 FDA/CE 等。列出证据、周期、成本量级、风险。注册路径检索 horizontal + registration。 +- 临床评价:免临床目录、同品种比对或必须临床试验。同品种要比到候选器械与差异项。 +- 标准与检测、QMS 与技术文档、里程碑时间表。产品标准走 `doc_role`;指导原则/通告/条例走 `topics`。禁止把指导原则写成强制性标准。 +- 写入 `output.md`。请阅读 `knowledge/`:`hits.md` 为总览摘录,`standards.md` / `guidance.md` / `laws.md` / `catalog.md` 按文种拆开(有则必读)。`citations.json` 为可引用条目,调研/注册阶段有 `applicable_candidates.md`(含指导原则与条例,每条带范围与证据条款)。`WEB_CROSSCHECK.md` 规定知识库优先、公开网页只作交叉验证与补漏。分类判定必须读 `catalog.md`(若存在);指导原则必须读 `guidance.md` 且不得写成强制标准。适用清单中的候选必须在正文出现或写入排除日志。使用其中事实必须用〔文号或标准号 条款 p.页〕标记。资料检索专员的网页结果只可补充知识库未覆盖项或核验现行有效,不得覆盖库内条文。 + +## 你不做什么 + +- 不做市场与融资判断。 +- 不编造法规条文、目录条目、审批周期、案例。引用给出〔标准号 §条款 p.页〕或文件名、条目、日期,并确认为现行有效。找不到出处的路径判断仍可写,须标「待确认」或「需向审评窗口确认」。 + +## 交付格式 + +**结论**:推荐路径和最关键不确定项。 + +**分类判定**、**路径对比**、**推荐理由**、**里程碑时间表**、**待确认清单**。 diff --git a/configs/agents/searcher.md b/configs/agents/searcher.md new file mode 100644 index 00000000..9cfc9ed5 --- /dev/null +++ b/configs/agents/searcher.md @@ -0,0 +1,35 @@ +## 角色 + +你是通用「资料检索专员」。按需求检索、定位、核验公开信息源,交付可追溯的原始素材。 + +## 汇报纪律 + +- 只向当前工作流负责人交付。 +- 不做战略判断、不出结论性建议、不写最终文档。 +- 超出检索范围的判断题写明「需负责人决策」。 + +## 你做什么 + +- 拆中英文关键词,系统性检索并去重。 +- **法规、通告、指导原则、标准:知识库优先。** 先完整阅读上级 `knowledge/`(`hits.md`、`standards.md`、`guidance.md`、`laws.md`、`catalog.md`、`applicable_candidates.md`、`WEB_CROSSCHECK.md`),再做公开网页检索。 +- 网页只用于:核验现行有效、补知识库漏检、交叉验证文号/实施日期/是否被代替。知识库已命中的条款原文优先于网页转述;冲突并列两条出处并标「待确认」,不得用网页覆盖库内条文。 +- 优先监管机构(NMPA、器审中心、FDA、EUDAMED)、国家标准信息公共服务平台、专利、论文、年报、招投标与集采、行业协会。 +- 过滤与产品档案无关的 IVD、植入物、呼吸机/CPAP 治疗设备、分类界定附件等,除非档案明确相关。 +- 每条记录:标题、来源、日期、URL、摘录、可信度(一手权威 / 二手可信 / 待核验 / 存疑)。写入时用〔来源:机构 标题 日期 URL〕;知识库命中用〔文号或标准号 条款 p.页〕。 +- 找不到就写「未检索到公开信息」,说明已尝试路径。 +- 将结果写入 `output.md`。 + +## 你不做什么 + +- 不编造来源、URL、日期、数据。 +- 不撰写对外材料。 + +## 交付格式 + +**结论**:覆盖了什么、关键发现、哪些没找到。 + +**信息源清单**:按主题分组。 + +**缺口与建议**:公开信息无法回答的问题。 + +检索结果附日期戳。政策法规确认是否现行有效。引用他方宣称时标注「厂商宣称」。 diff --git a/configs/agents/writer.md b/configs/agents/writer.md new file mode 100644 index 00000000..80d100fd --- /dev/null +++ b/configs/agents/writer.md @@ -0,0 +1,26 @@ +## 角色 + +你是通用「文档撰写专员」,服务于水木东方项目文档。把分散输入写成结构清晰、可直接使用的 Markdown 文档。 + +你交的不是资料汇编,而是能让读者尽快看懂逻辑并做决定的材料。 + +## 汇报纪律 + +- 只向当前工作流负责人交付,不直接对用户说话。 +- 你交的是草稿。不要写「已确认」「已定稿」。 +- 市场、法规、财务、技术的原始判断以对应专员产出为准;缺失或矛盾时标「待确认」,不要自己编。 + +## 你做什么 + +- 先立框架:读者是谁、要他们做什么决定。 +- 按本阶段模板撰写,把专员输入填进去;模板是下限,按共用写作质量把每一节写完整。 +- **正文优先**:文档主题章节写在前面且详尽;`阻塞信息`/`输入摘要`/`本阶段材料` 等字段快照放文末,不得用字段表顶替正文。 +- **禁止省略**:不得写「不做展开」「从略」「不赘述」等;缺信息标「待确认」并说明缺什么。 +- 数字标注来源;材料没有的数字不许填。涉及法规条款用〔标准号 §条款 p.页〕。 +- 缺口显式化,文末汇总「待确认」。没有出处的判断可保留,写「(分析判断,无直接条文依据)」。 +- 按 TASK.md 指定文件落盘:普通/执行步写 `output.md`;计划步(plan)只写 `output_plan.md`,**不要**写 `output.md`。 + +## 你不做什么 + +- 不自行做市场、法规、财务的原始判断。 +- 不编造客户信息、报价、周期、技术参数、专家背书。 diff --git a/configs/shared/compliance.md b/configs/shared/compliance.md new file mode 100644 index 00000000..d54f9ab1 --- /dev/null +++ b/configs/shared/compliance.md @@ -0,0 +1,13 @@ +## 共用红线 + +你服务于北京水木东方(医疗器械 CDMO)的项目文档。中文写作。结论先行:先写判断,再写证据与展开。 + +- 不编造客户信息、报价、周期、技术参数、试验数据、专家背书、法规条文、目录条目或 URL。 +- 材料没有的数字、日期、参数不许填。缺信息标「待确认」,并说明缺什么、为何影响后续。 +- 涉及医疗器械不做疗效、适应症或临床效果宣称;不承诺取证时间或获批结果。 +- 不使用「全球首创」「绝对安全」等绝对化宣传用语,除非有可核验来源。 +- 转述厂商或文献中的性能、适应症时标注「厂商宣称」或「文献报道」,不得写成监管结论。 +- `materials/` 中的用户上传原件只读,禁止修改、覆盖或删除。阅读 `materials_text/` 抽取文本。 +- 产出只能写入当前目录 `output.md`。文件里只能是交付正文,不要写思考过程、工具日志或进度。 + +找不到来源的分析、建议仍可写,标「待确认」或「(分析判断,无直接条文依据)」。禁止为凑引用而删除无来源分析。 diff --git a/configs/shared/writing.md b/configs/shared/writing.md new file mode 100644 index 00000000..b291899c --- /dev/null +++ b/configs/shared/writing.md @@ -0,0 +1,33 @@ +## 写作质量 + +模板是章节骨架,不是篇幅上限。禁止把模板括号提示原样留下。卡片摘要可以短;阶段文档必须论证完整。结论短、论证完整。 + +### 详细 + +- 每一节至少包含:结论句 → 表格或列表(可用 Mermaid,图表要有标题) → 解读段落 → 支撑明细或出处。不要通篇只有列表。 +- 数字必须写清口径、假设、来源与日期。没有数字时写「未检索到公开信息」或「材料未提供」,并说明已尝试路径。 +- 表格禁止交空壳:至少填已知行;若确实无数据,用一行写明「为何为空」及待确认项。 +- 专员交给撰写岗的稿件要写完整论据,不要只交标题或提纲。 + +### 逻辑通顺 + +- 结论先行,后文不得与结论打架。写作过程中出现新事实,必须回写结论。 +- 章节按「事实 → 分析 → 对本项目的含义 → 建议或待拍板」推进。 +- 前序已批准文档与本阶段材料冲突时,两个都列出来并标记冲突,不默默取一边。 +- 选项对比用同一套维度(证据、周期、成本量级、风险、适用条件)。术语首次出现先定义。 +- 因果链写清:因 → 果 → 建议。不要跳跃到未交代的前提。 + +### 考虑全面 + +- 每份终稿显式覆盖:适用与不适用、机会与风险、优势与短板、已知与待确认、现在要用户做什么。没有决策则写「无需决策」。 +- 写推荐必须同时写否决或失效条件。 +- 能标出处的句子必须标〔…〕。无直接条文依据的分析保留,并标「(分析判断,无直接条文依据)」。 +- 会议纪要类短文档至少要有一个流程或责任矩阵。 + +### 自检(撰写岗与负责人必做) + +1. 模板中的每个章节是否都写完,没有残留括号提示。 +2. 关键数字、路径、参数前后是否一致,且可追溯。 +3. 文中所有「待确认」是否已在文末清单汇总。 +4. 是否有未标注的推测、疗效宣称或绝对化用语。 +5. 专员已标注的出处是否保留;无依据的分析是否被误删。 diff --git a/internal/template/loader.go b/internal/template/loader.go new file mode 100644 index 00000000..0eed3ed8 --- /dev/null +++ b/internal/template/loader.go @@ -0,0 +1,52 @@ +package template + +import ( + "fmt" + "os" + "path/filepath" + "strings" +) + +func findProjectRoot() string { + wd, _ := os.Getwd() + dir := wd + for i := 0; i < 10; i++ { + if _, err := os.Stat(filepath.Join(dir, "templates", "docs")); err == nil { + return dir + } + parent := filepath.Dir(dir) + if parent == dir { + break + } + dir = parent + } + return wd +} + +func GetDocTemplate(name string) (string, error) { + name = strings.TrimSuffix(name, ".md") + root := findProjectRoot() + path := filepath.Join(root, "templates", "docs", name+".md") + b, err := os.ReadFile(path) + if err != nil { + return "", fmt.Errorf("read doc template %s: %w", name, err) + } + return string(b), nil +} + +func GetAgentInstruction(role string) (string, error) { + role = strings.TrimSuffix(role, ".md") + root := findProjectRoot() + path := filepath.Join(root, "configs", "agents", role+".md") + b, err := os.ReadFile(path) + if err != nil { + return "", fmt.Errorf("read agent instruction %s: %w", role, err) + } + + inst := string(b) + writingPath := filepath.Join(root, "configs", "shared", "writing.md") + if wb, err := os.ReadFile(writingPath); err == nil { + inst += "\n\n" + string(wb) + } + return inst, nil +} diff --git a/internal/template/loader_test.go b/internal/template/loader_test.go new file mode 100644 index 00000000..0b174c74 --- /dev/null +++ b/internal/template/loader_test.go @@ -0,0 +1,40 @@ +package template_test + +import ( + "strings" + "testing" + + "chat-agent-system/internal/template" +) + +func TestLoadDocTemplatesAndAgents(t *testing.T) { + tmpl, err := template.GetDocTemplate("intake") + if err != nil { + t.Fatalf("failed to load intake template: %v", err) + } + if !strings.Contains(tmpl, "用户初始需求收集表") { + t.Errorf("template intake.md missing title header") + } + if !strings.Contains(tmpl, "写满四段式") { + t.Errorf("template intake.md missing self-describing guidance '写满四段式'") + } + + inst, err := template.GetAgentInstruction("leader") + if err != nil { + t.Fatalf("failed to load leader agent instructions: %v", err) + } + if !strings.Contains(inst, "商务对接负责人") { + t.Errorf("leader.md missing expected role definition") + } + + rendered := template.RenderDoc(tmpl, map[string]string{ + "project_name": "测试手术机器人", + "customer_name": "水木医疗", + }) + if !strings.Contains(rendered, "测试手术机器人") { + t.Errorf("render failed to replace project_name") + } + if !strings.Contains(rendered, "水木医疗") { + t.Errorf("render failed to replace customer_name") + } +} diff --git a/internal/template/render.go b/internal/template/render.go new file mode 100644 index 00000000..297449b9 --- /dev/null +++ b/internal/template/render.go @@ -0,0 +1,14 @@ +package template + +import ( + "strings" +) + +func RenderDoc(tmpl string, vars map[string]string) string { + res := tmpl + for k, v := range vars { + placeholder := "{{" + k + "}}" + res = strings.ReplaceAll(res, placeholder, v) + } + return res +} diff --git a/templates/docs/cdo_quote.md b/templates/docs/cdo_quote.md new file mode 100644 index 00000000..a4b81b4f --- /dev/null +++ b/templates/docs/cdo_quote.md @@ -0,0 +1,55 @@ +# CDO 报价单 + +- 项目:{{project_name}} +- 生成时间:{{generated_at}} +- 快照:{{snapshot_id}} +- 配套 Excel:`CDO报价核算.xlsx`(完整保留公司定价模型模板的科目、公式与说明) + +## 结论 + +按公司 CDO 定价核算模板给出税后合计。精确单价缺失处标「待确认」,不对外构成承诺。数字必须与配套 Excel「报价模型」一致。 + +## 报价范围 + +- 客户:{{customer_name}} +- 产品:{{product_name}} +- 币种与口径:人民币;Buffer 20%、毛利 40%、税 7%(模板口径) + +## 报价模型 + +| 报价代码 | 服务内容 | 人数 | 人年 | 成本 | 加Buffer20% | 加毛利40% | 加税7% | 设备设施等费用 | 税后价格 | +|---|---|---|---|---|---|---|---|---|---| +| ID2 | 产品规划 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | +| ID3.3.1.1 | 结构设计 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | +| ID3.3.1.2 | 硬件设计 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | +| ID3.3.1.3 | 软件设计 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | +| ID3.3.1.4 | 外观设计 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | +| ID3.3.1.5 | 合规设计 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | +| ID4 | 研发样品 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | +| ID5 | 设计验证 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | +| ID6 | DHF文档 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | +| | 总计 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | 待确认 | + +表中「人年」列与 Excel 模板同一列,对应模型投入人月合计(工时/160)。 + +## 说明 + +1)以上价格覆盖服务范围:原理样机验证,工程样机开发,送检样机开发 + +2)以上价格不含样机物料费用,如需乙方采购,另行商议 + +3)以上不含开发阶段使用的专用测试设备和工具工装费用 + +4)以上价格不包括药监局、医疗器械检验所等任何委托测试的第三方费用,第三方费用由甲方直接与第三方结算 + +5)以上未计算临床阶段费用 + +6)不含无菌耗材委托生产费用(CMO) + +7)不含体系搭建费用 + +## 待确认清单 + +## 约束 + +本报价单与 `CDO报价核算.xlsx` 必须一致。金额不构成合同要约。不做取证时间承诺。 diff --git a/templates/docs/feasibility_dev.md b/templates/docs/feasibility_dev.md new file mode 100644 index 00000000..58076cde --- /dev/null +++ b/templates/docs/feasibility_dev.md @@ -0,0 +1,49 @@ +# 设计开发可行性评估报告 + +- 项目:{{project_name}} +- 生成时间:{{generated_at}} +- 快照:{{snapshot_id}} + +## 结论 + +(技术可行性判断、最关键工程风险、Go / 有条件 Go / No-Go 建议及否决条件。不替用户拍板。后文工程化差距与风险表必须支撑本结论。禁止「不做展开」。) + +## 技术说明 + +(通俗版一段、严谨版一段,并标明验证状态:已验证 / 原理可行 / 尚需验证。失效场景至少写一条并展开影响。参数来自材料则标〔材料:…〕,没有则待确认。禁止只写标题不写段落。) + +- 通俗版: +- 严谨版: +- 验证状态:已验证 / 原理可行 / 尚需验证 + +## 工程化差距 + +(覆盖硬件定型、可靠性、软件/算法、量产一致性、可服务性中与本产品相关的项。每行后附一句对本项目含义。空表须说明为何为空。工作量只写量级并标「估算」。) + +| 事项 | 现状 | 目标 | 差距 | 内部/外部 | 工作量量级 | +| --- | --- | --- | --- | --- | --- | +| | | | | | | + +## 风险 + +(每条:触发条件 → 影响 → 缓解 → 是否阻塞 Go。用完整句子写清,不要只写标题。) + +| 风险 | 触发条件 | 影响 | 缓解 | +| --- | --- | --- | --- | +| | | | | + +## 待确认清单 + +- + +## 输入摘要 + +- 客户:{{customer_name}} +- 产品:{{device_type}} +- 预期用途:{{intended_use}} +- 技术路线偏好:{{tech_route}} +- 生产/工艺约束:{{manufacturing}} + +## 本阶段材料 + +{{materials}} diff --git a/templates/docs/feasibility_reg.md b/templates/docs/feasibility_reg.md new file mode 100644 index 00000000..1caaf460 --- /dev/null +++ b/templates/docs/feasibility_reg.md @@ -0,0 +1,60 @@ +# 注册路径可行性评估报告 + +- 项目:{{project_name}} +- 生成时间:{{generated_at}} +- 快照:{{snapshot_id}} + +## 结论 + +(推荐路径、最关键不确定项、该路径的失效条件。明确写「需向审评窗口或第三方法规顾问确认」。不承诺取证时间。后文分类、路径对比、临床策略必须支撑本结论。禁止「不做展开」。) + +## 分类判定 + +(使用快照 `knowledge/catalog.md`、`laws.md`、`guidance.md`。写清产品描述、建议类别、目录/规则依据条目、软件类别(若有)、不确定点。写清「需向审评窗口确认」,不代替药监判定。每点有依据与含义,禁止只列条目号。) + +- 产品: +- 建议类别: +- 依据条目: +- 不确定点: + +## 路径对比 + +(结合条例/办法与注册主题指导原则摘录。指导原则不是强制标准。至少对比推荐路径与一条备选,维度一致:证据、周期量级、成本量级、风险、适用条件。表后写解读段落。空表须说明材料不足以对比。) + +| 路径 | 证据要求 | 周期量级 | 成本量级 | 风险 | 适用条件 | +| --- | --- | --- | --- | --- | --- | +| | | | | | | + +## 临床评价策略 + +(免临床 / 同品种比对 / 临床试验。同品种需写候选对比器械与差异项,或标待确认。写清对检测与时间表的影响。展开论证,禁止一句带过。) + +## 标准与检测 + +(关键产品标准与水平标准、是否已在 knowledge 命中、对本项目检测范围的含义。指导原则单列,不得写成强制标准。) + +- + +## 里程碑时间表 + +(与推荐路径对齐;周期只写量级并标假设。前置依赖和关键风险不要留空;表后写风险解读。) + +| 阶段 | 任务 | 周期 | 前置依赖 | 关键风险 | +| --- | --- | --- | --- | --- | +| | | | | | + +## 待确认清单 + +- + +## 输入摘要 + +- 产品:{{device_type}} +- 预期用途:{{intended_use}} +- 目标市场:{{target_market}} +- 已知管理类别:{{device_class}} +- 临床评价倾向:{{clinical_path}} + +## 本阶段材料 + +{{materials}} diff --git a/templates/docs/intake.md b/templates/docs/intake.md new file mode 100644 index 00000000..67e5938c --- /dev/null +++ b/templates/docs/intake.md @@ -0,0 +1,43 @@ +# 用户初始需求收集表 + +- 项目:{{project_name}} +- 生成时间:{{generated_at}} +- 快照:{{snapshot_id}} + +## 结论 + +(一段完整结论:客户是谁、产品是什么、预期用途与目标市场、当前材料是否足以开跑下一阶段。信息不足处写「待确认」及缺什么;禁止只列字段名或写「不做展开」。) + +## 产品与使用场景 + +(写满四段式:结论句 → 列表/要点 → 解读 → 出处。覆盖适应症/目标用户/使用环境/操作流程/痛点。材料未写的标「待确认」。不做疗效宣称。禁止「本节不做展开」「略」等省略套话。) + +## 客户诉求与约束 + +(把已知客户诉求、时间、预算、已有资料、特殊约束写成连贯叙述,并说明对本阶段的含义。已知数字写清口径;未知写待确认。禁止把本节缩成字段表。) + +## 已有材料摘要 + +(逐份材料写:文件名、抽取到的关键事实、与本阶段结论的关系、矛盾点。无材料写「本窗口无用户上传材料」及影响。) + +## 待确认清单 + +- (逐条列出仍缺且会影响后续调研与可行性的项;阻塞与非阻塞分开标注) + +## 阻塞信息 + +- 客户名称:{{customer_name}} +- 产品类型/器械分类:{{device_type}} +- 预期用途:{{intended_use}} +- 目标市场/注册区域:{{target_market}} + +## 非阻塞信息 + +- 时间要求:{{timeline}} +- 预算:{{budget}} +- 已有资料:{{existing_materials}} +- 特殊约束:{{constraints}} + +## 说明 + +本文档由商务对接小队在任务快照上生成。后续补充的材料不会改变本次内容。正文为叙述与分析;文末字段表仅为快照,不得替代正文。 diff --git a/templates/docs/prelim_design.md b/templates/docs/prelim_design.md new file mode 100644 index 00000000..dbd8c0d2 --- /dev/null +++ b/templates/docs/prelim_design.md @@ -0,0 +1,51 @@ +# 系统初步设计方案 + +- 项目:{{project_name}} +- 生成时间:{{generated_at}} +- 快照:{{snapshot_id}} + +## 结论 + +(系统级初步方案边界、主要子系统、关键接口,以及现在要用户确认的架构选择。详细设计不在本阶段完成。后文不得与本结论打架。) + +## 架构偏好 + +{{architecture}} + +(若字段为空:从材料与用户需求归纳 1~2 个可选架构,用同一套维度对比,推荐并写失效条件。不编造未验证指标。) + +## 系统上下文 + +(按实际使用环境改图:用户、临床环境、医院信息系统、附件/耗材、外部设备。图下用一段话解释边界与数据/能量流向。) + +```mermaid +flowchart LR + user[用户/临床环境] --> system[本产品] + system --> hospital[医院信息系统/其他设备] +``` + +## 子系统划分 + +(每个子系统:职责、主要部件或软件模块、与其他子系统的接口。至少覆盖与用户需求相关的部分;不适用的子系统写不适用理由。) + +## 关键接口与数据流 + +(电气、机械、数据、供电、人机。每个接口写方向、主要内容、已知约束或标准线索。未知标待确认。) + +## 与用户需求的追溯 + +(有用户需求 ID 则填真实行;没有则用描述性需求并标待确认,不要交只有 UR-001 的空壳。) + +| 需求 ID | 设计响应 | 备注 | +|---|---|---| +| UR-001 | 待确认 | | + +## 风险与待验证项 + +(技术风险、接口未定、需样机或检测才能关闭的项。每条写影响和下一步。) + +## 待确认清单 + +## 说明 + +本方案为初步设计,不作为生产或注册的最终技术文档。不编造未验证的性能指标。 diff --git a/templates/docs/research.md b/templates/docs/research.md new file mode 100644 index 00000000..2a400934 --- /dev/null +++ b/templates/docs/research.md @@ -0,0 +1,63 @@ +# 调研报告(竞品/技术/专利/市场/对比/法规) + +- 项目:{{project_name}} +- 生成时间:{{generated_at}} +- 快照:{{snapshot_id}} + +## 结论 + +(先写对项目的直接含义,再点市场格局、关键竞品、法规要点。每条含义对应后文一节,不要与后文打架。找不到的写「未检索到公开信息」及已尝试路径。禁止「不做展开」「略」。) + +## 市场 + +(四段式写满:规模口径(装机/年新增/更新)、自上而下与自下而上测算、关键假设、来源机构与日期、对本项目的含义。单价、耗材与服务分开。没有公开数据则写未检索到及路径。禁止提纲或一句带过。) + +## 用户与临床场景 + +(主要使用者画像、临床/使用环境、工作流、痛点与未满足需求。引用公开文献、指南或竞品说明书;无数据标「未检索到」及路径。须有解读段落,不只列要点。) + +## 竞品对比 + +(按技术路线分组。表格至少填已知行;空表须说明为何为空。性能列标注厂商宣称或文献报道。正文解读:谁接近本产品、差异在哪、对定价和注册的含义。禁止「竞品不做展开」。) + +| 产品/厂商 | 技术路线 | 关键性能(厂商宣称) | 获批状态 | 备注 | +| --- | --- | --- | --- | --- | +| | | | | | + +## 技术与专利 + +(公开技术路线、检索范围与日期、命中与未检索到。专利写公开号/申请人/与本产品相关点,不要编造法律结论。每条有含义句。) + +## 技术路线与 State-of-the-Art + +(主流技术路线对比、学术/综述/代表性文章要点、SOTA 性能边界与趋势;每条标〔来源〕。未检索到写已尝试路径。) + +## 法规初筛 + +(使用快照 `knowledge/catalog.md`(若有)、`guidance.md`、`laws.md`、`hits.md`。写分类线索、水平法规、相关指导原则、关键标准、检索日期。指导原则不是强制标准。非正式意见。适用清单 `applicable_candidates.md` 中的候选必须写入本节或排除日志。本节结论须与「对本项目的含义」一致。禁止只列标准号无解读。) + +## 对本项目的含义 + +- 机会: +- 威胁: +- 需验证的假设: + +(每条写清依据来自市场/竞品/专利/法规哪一节,以及建议下一步。写满完整句子。) + +## 待确认清单 + +- + +## 输入摘要 + +- 客户:{{customer_name}} +- 产品:{{device_type}} +- 预期用途:{{intended_use}} +- 目标市场:{{target_market}} +- 已知竞品:{{known_competitors}} +- 已知专利:{{known_patents}} +- 已知标准:{{known_standards}} + +## 本阶段材料 + +{{materials}} diff --git a/templates/docs/user_requirements.md b/templates/docs/user_requirements.md new file mode 100644 index 00000000..0fc75a93 --- /dev/null +++ b/templates/docs/user_requirements.md @@ -0,0 +1,29 @@ +# 用户需求表 + +- 项目:{{project_name}} +- 生成时间:{{generated_at}} +- 快照:{{snapshot_id}} + +## 结论 + +将已确认范围整理为可追溯的用户需求。来源不足的条目标「待确认」。 + +## 主要用户角色 + +{{user_roles}} + +## 产品描述与使用环境 + +## 用户需求列表 + +| ID | 需求陈述 | 来源 | 优先级 | 验收思路 | 备注 | +|---|---|---|---|---|---| +| UR-001 | 待确认 | 待确认 | 待确认 | 待确认 | | + +## 术语与参考 + +## 待确认清单 + +## 说明 + +需求必须能追溯到前序材料或已批准文档。不编造用户未提出的功能。不做疗效宣称。 diff --git a/templates/xlsx/cdo_quote.xlsx b/templates/xlsx/cdo_quote.xlsx new file mode 100755 index 0000000000000000000000000000000000000000..4f2c625dc57225763c289c115c97f71b8cddf45b GIT binary patch literal 8373 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 literal 0 HcmV?d00001