模板驱动文档自动化:让重复文档生产变成可配置的流水线
1. 项目概述用模板把文档生产变成“填空题”你有没有过这种体验每周要交三份客户方案每份结构雷同——封面、目录、痛点分析、解决方案、报价页、服务承诺——但每次都要从零新建Word、手动调格式、复制粘贴旧内容、反复检查页眉页脚是否错位我干了八年内容运营和销售支持前五年靠“CtrlC/V微调”硬扛后三年开始琢磨为什么不能像电商上架商品一样把文档当成可配置的“产品”来批量生成直到我系统拆解了Sqribble这套模板驱动的文档自动化逻辑才真正意识到——我们不是在写文档是在设计文档的“装配流水线”。Sqribble’s Template‑Driven Document Automation直译是“Sqribble的模板驱动型文档自动化”但它的本质远不止一个工具名称。它是一套将文档结构、内容规则、样式逻辑全部前置封装进可复用模板的工程化方法论。核心关键词就三个模板Template、驱动Driven、自动化Automation。注意这里说的“模板”不是Word里那种只能改文字的静态框架而是嵌入了条件判断、数据映射、样式继承、章节自动编号等动态能力的“智能容器”。所谓“驱动”指的是整个文档生成过程由模板内部定义的规则触发而非人工点击操作而“自动化”则体现在从客户信息录入到PDF交付全程无需打开任何编辑软件。它解决的不是“怎么排版更快”的问题而是“如何让文档生产彻底脱离人工干预”的系统性瓶颈。适合谁销售团队需要快速响应客户询盘、咨询公司要批量交付标准化报告、教育机构需按学员数据生成个性化学习计划、甚至自由职业者接单后自动生成带品牌水印的服务协议——只要你的文档有重复结构、变量字段、固定流程这个思路就值得深挖。我试过用ExcelMail Merge勉强应付也试过低代码平台拖拽表单但要么灵活性差改个标题样式就得重做模板要么学习成本高业务同事根本不会配置逻辑。Sqribble的特别之处在于它把技术实现藏在了极简的操作界面背后你只需要在可视化编辑器里拖一个“客户姓名”占位符设置它关联CRM里的“contact_name”字段再拖一个“服务周期”模块设定当订单金额5万时显示“年度VIP保障条款”否则隐藏最后点一下“生成”系统就调用预设的PDF引擎把所有变量填进去套用品牌字体和配色输出一份完全符合公司VI规范的PDF。整个过程没有一行代码但底层逻辑和SaaS产品的API集成、条件渲染、样式隔离一模一样。这不是给设计师用的排版工具而是给业务人员用的“文档工厂操作系统”。2. 核心设计逻辑与方案选型解析2.1 为什么必须是“模板驱动”而不是“脚本驱动”或“AI生成”很多人第一反应是“现在大模型这么强直接让ChatGPT写不就行了”我实测过用GPT-4生成一份10页的营销方案确实能出框架、列要点、润色语句但致命缺陷有三个第一品牌一致性失控——它可能把你的“蓝白主色调”写成“科技感银灰”把“客户成功部”误写成“客户服务部”第二数据准确性无保障——它无法实时读取你CRM里张三的合同到期日只能编造一个“2025年6月”第三法律与合规风险——生成的条款可能违反最新《广告法》对“最优质”“第一品牌”等绝对化用语的禁令而模板里每个条款都是法务审核过的标准文本。所以真正的文档自动化核心不是“生成内容”而是“精准装配内容”。那为什么不写Python脚本我用Jinja2WeasyPrint搭过一套技术上完全可行读取JSON数据填充HTML模板转PDF。但落地时卡在三个现实问题上一是业务同事改不了模板——他们不会写Jinja语法改个页眉就得找我二是版本管理混乱——市场部发新版VI我要手动更新所有HTML文件里的CSS三是扩展性差——加个“根据行业自动匹配案例库”的功能得重写数据查询逻辑。而Sqribble这类工具的设计哲学恰恰是把“技术复杂性”和“业务可维护性”做了硬性隔离模板编辑器面向业务人员提供所见即所得的拖拽式占位符、可视化条件开关、品牌色板选择后台引擎则负责把用户操作翻译成可靠的渲染指令。这就像汽车——司机不需要懂发动机原理但踩油门就能获得确定的动力输出。模板驱动的本质是建立了一条“业务意图→可视化配置→稳定输出”的可信链路而脚本或AI目前还做不到这条链路的端到端闭环。2.2 模板的四层结构从静态框架到动态引擎Sqribble的模板不是一张平面图而是一个分层架构。我把它拆成四层每一层解决一类问题缺一不可第一层基础结构层Skeleton Layer这是最直观的部分对应Word里的“样式集”和“多级列表”。比如一份咨询报告模板必须预设好“1. 执行摘要”“1.1 项目背景”“1.2 核心目标”这样的标题层级以及对应的字体、缩进、行距。关键点在于这一层定义的是“文档骨架”所有后续内容都挂载在这个骨架上。我见过太多人直接在空白页上写内容结果客户要求把“执行摘要”从第一页挪到第三页整篇文档的页码、目录、交叉引用全乱套。而结构层强制要求先搭好骨架再填肉从根本上避免结构性错误。第二层内容占位符层Placeholder Layer这是模板的“神经末梢”负责连接外部数据源。占位符分三类静态文本占位符如公司Logo、标准Slogan内容固定只控制位置和大小动态数据占位符如“{{client.name}}”“{{project.budget}}”需绑定到CRM、Excel或表单字段条件内容占位符如“{{#if project.is_premium}}VIP服务条款{{/if}}”根据布尔值决定是否渲染。重点来了占位符不是孤立存在的。我测试发现Sqribble会自动识别占位符间的依赖关系。比如你在“报价页”用了“{{project.discount_rate}}”系统会提示你该字段未在数据源中定义请前往“数据映射”面板配置。这种主动校验比写脚本时靠报错排查高效十倍。第三层样式规则层Styling Rule Layer很多人以为样式就是改个字体颜色其实这是最容易被低估的一层。Sqribble允许为同一占位符设置多套样式规则。举个真实案例我们给金融客户做尽调报告监管要求“风险提示”段落必须用12号黑体红色边框左缩进2字符且出现在每章末尾。如果用Word样式一旦某章没放提示下章的样式就会错位。而Sqribble的样式规则可以绑定到“章节末尾”这个位置逻辑上无论内容多少规则自动生效。更绝的是“样式继承”你设置一级标题为“思源黑体 Bold”二级标题会自动继承字体族只覆盖字号和颜色避免全篇手动调整。第四层输出策略层Output Strategy Layer这是模板的“出厂设置”。包括生成格式PDF/DOCX/PNG、页面尺寸A4/信纸、页眉页脚内容含动态页码“第{{page}}页共{{total_pages}}页”、安全选项PDF密码、禁止复制、甚至打印优化关闭背景图以节省墨水。我曾因忽略这一层栽过跟头给海外客户发PDF模板里用了中文思源字体但输出设置没勾选“嵌入字体”对方打开全是方块字。后来我把“嵌入所有字体”设为模板默认策略从此再没出过这类问题。2.3 方案选型的关键决策点什么情况下该用Sqribble什么情况下该换方案没有银弹Sqribble也不是万能的。我根据三年实战总结出三个硬性决策标尺标尺一文档变更频率如果你们的文档结构半年一变比如投标书随招标政策频繁调整Sqribble是首选——业务同事自己就能拖拽修改模板当天上线。但如果文档十年不变如公司章程用Word模板宏更轻量没必要上整套系统。标尺二数据源复杂度Sqribble原生支持CSV、Google Sheets、Zapier连接对接Salesforce、HubSpot等主流CRM需付费插件。如果你的数据散落在五个不同系统且需要实时聚合比如从ERP取订单金额、从HR系统取交付团队、从项目管理工具取进度那得评估插件成本和稳定性。我们曾因Zapier免费版限流导致批量生成时30%的文档数据为空最后改用自建API网关中转反而更稳。标尺三合规审计要求金融、医疗等行业要求文档生成全程留痕谁在何时基于哪个模板、用了哪些数据、输出了什么版本。Sqribble企业版提供完整审计日志但开源方案如DocxGen需要自己搭ELK日志系统。如果你的法务部门连邮件发送记录都要存档十年这点必须前置确认。提示别被“自动化”三个字迷惑。真正的价值不在“省时间”而在“降风险”。我们测算过人工制作一份标准方案平均耗时47分钟出错率12%主要是数据抄错、页码错乱用Sqribble模板后生成时间压到90秒出错率归零。但最大的收益是——当客户质疑“你们方案里写的交付周期和合同不一致”时我们能立刻调出生成日志证明该文档严格依据2024年Q3版模板和CRM实时数据生成责任边界清晰无比。3. 核心细节解析与实操要点3.1 模板构建的黄金五步法从零开始搭建第一个可用模板别被“模板驱动”吓住其实搭建第一个模板比你想象中简单。我带过七支跨行业团队落地总结出任何人都能上手的五步法每步都有明确产出物和避坑点第一步逆向拆解一份“完美文档”耗时约20分钟拿出你最满意的一份已交付文档比如刚签单的客户方案用荧光笔标出三类内容永不变化的公司Logo、标准条款、法律声明→ 归入“静态文本占位符”每次必变的客户名、项目名、日期、金额→ 归入“动态数据占位符”按条件出现的VIP客户显示专属服务、教育行业显示案例、制造业显示产线图→ 归入“条件内容占位符”。注意这一步必须用真实文档别凭空想。我见过最典型的错误是——市场部同事按“理想状态”拆解结果发现销售实际填的数据字段名是“cust_nm”而非“client_name”导致模板上线后大面积报错。第二步创建基础结构骨架耗时约15分钟在Sqribble编辑器里新建模板选择“从空白开始”。重点不是写内容而是搭结构插入“封面”章节设置标题样式为“Title 1”插入“目录”章节勾选“自动更新”插入“正文”章节预设好“1. 背景”“2. 方案”“3. 报价”三级标题在每章末尾插入“小节分隔线”统一用虚线样式。关键技巧所有标题必须用编辑器内置的“样式”功能设置而非手动调字体。因为后续的目录生成、页码跳转、条件渲染都依赖样式标签。第三步植入占位符并绑定数据耗时约25分钟这是最易出错的环节。操作顺序必须严格先在“数据源”面板添加你的数据源如上传CSV或连接Google Sheet再回到编辑区在“客户名称”位置点击“插入占位符”选择“client_name”字段对于条件内容如“VIP服务条款”先插入普通文本再选中它点击“条件设置”选择“project_tier VIP”。重要提醒占位符名称必须和数据源字段名完全一致包括大小写和下划线。我曾因把CSV里的“contact_email”写成“contactEmail”调试两小时才发现是命名不匹配。第四步配置样式规则与输出策略耗时约10分钟进入“样式管理”面板为“Title 1”设置字体为“思源黑体 Bold”字号28居中为“报价表格”设置边框为1px实线表头背景色#F0F8FF在“输出设置”中勾选“嵌入所有字体”“PDF/A-1b兼容”“添加文档密码”。这里有个隐藏技巧点击“预览样式”按钮系统会生成一个纯样式预览页专门检查字体嵌入效果避免正式生成时翻车。第五步真机测试与迭代耗时约30分钟用三组真实数据测试测试组A标准客户所有字段完整测试组BVIP客户触发条件内容测试组C字段缺失客户如“预算”为空。观察点PDF页码是否连续条件内容是否精准出现空字段是否显示为“N/A”而非空白发现问题立即回退到对应步骤修改。记住模板不是一次成型的我们平均迭代4.7次才达到生产可用标准。3.2 数据映射的深度实践让模板读懂你的业务语言数据映射是模板驱动的“翻译官”它决定外部数据如何被模板理解。Sqribble提供三种映射方式适用场景截然不同方式一直连映射Direct Mapping最常用适用于字段名一致的场景。比如你的CRM里客户姓名字段叫“full_name”模板占位符也叫“full_name”直接拖拽连线即可。优势是零配置但脆弱——一旦CRM升级改名模板立刻失效。我们给直连映射加了道保险在数据源配置页启用“字段别名”功能把“full_name”映射为“client_name”模板里永远用“client_name”CRM改名只需更新别名模板不动。方式二公式映射Formula Mapping解决字段计算需求。比如报价页需要“含税总价”但CRM只存“不含税金额”和“税率”。在映射面板创建新字段“total_with_tax”输入公式{{base_amount}} * (1 {{tax_rate}})。Sqribble支持基础数学运算、字符串拼接{{first_name}} {{last_name}}、日期格式化{{date}} | date:YYYY-MM-DD。注意公式里所有变量必须已存在于数据源否则报错。方式三查找映射Lookup Mapping处理“代码→含义”的转换。比如CRM里行业字段存的是“IND-001”但文档里要显示“信息技术”。在Sqribble后台创建一个查找表代码含义IND-001信息技术MAN-002制造业然后在映射中将“industry_code”字段关联到该查找表“显示值”自动转为中文。这招在应对政府客户时特别管用——他们要求所有文档用标准行业分类代码但业务同事只认中文名。实操心得我坚持一个原则——所有映射逻辑必须文档化。在团队共享文档里建一张表模板字段数据源字段映射方式说明client_namefull_name直连CRM v3.2字段名service_descproduct_id查找关联产品库v2.1这样新人接手、CRM升级、模板迁移时不用猜直接查表。3.3 条件逻辑的实战技巧让模板具备“业务判断力”条件逻辑是模板智能化的核心。Sqribble支持if、unless、each三种基础指令但组合使用才能释放威力。分享三个我反复验证有效的模式模式一“多层嵌套判断”处理复杂业务规则比如我们的服务协议根据客户等级和签约年限决定是否包含“免费升级”条款{{#if client.tier VIP}} {{#if contract.years 3}} 包含免费升级至V3.0版本。 {{else}} 包含免费升级至V2.5版本。 {{/if}} {{else}} {{#if contract.years 5}} 包含免费升级至V2.0版本。 {{/if}} {{/if}}关键点嵌套层级不宜超过三层否则可读性骤降。我们约定超过两层的逻辑必须拆成独立子模板用{{ sub_template}}调用主模板只保留决策树根节点。模式二“集合遍历”生成动态列表客户常要求“列出所有参与项目成员”。CRM里存的是JSON数组[{name:张三,role:PM},{name:李四,role:Dev}]。用{{#each team_members}}指令{{#each team_members}} - {{name}}{{role}} {{/each}}实测发现如果数组为空{{#each}}区块默认不渲染但有时需要显示“暂无成员”。解决方案是加{{else}}分支{{#each team_members}} - {{name}}{{role}} {{else}} - 暂无成员 {{/each}}模式三“否定条件”规避常见陷阱新手最爱用{{#if field}}判断字段是否存在但要注意空字符串、数字0、布尔值false都会被判定为“假”导致内容意外隐藏。比如客户电话是021-12345678{{#if phone}}会认为它不存在正确写法是显式判断类型{{#if phone ! null}}或{{#if phone.length 0}}。我们团队的铁律是所有if判断必须带类型限定杜绝隐式转换。4. 实操过程与核心环节实现4.1 从数据录入到PDF交付全流程实录现在我们把前面所有知识点串起来走一遍真实的端到端流程。以“为新客户生成销售方案”为例全程无需离开浏览器耗时3分12秒含等待步骤1启动数据录入0:00-0:25销售同事打开公司内部链接进入Sqribble的“方案生成器”页面。页面本质是一个精简表单只包含6个必填字段客户名称文本行业下拉选择IT/制造/教育/医疗预算范围单选10万以下/10-50万/50万以上核心需求多选系统升级/流程优化/培训赋能是否VIP客户开关开/关交付周期日期选择器注意这个表单不是Sqribble原生的而是我们用Typeform嵌入的。因为Sqribble的原生表单太简陋不支持条件显示比如选了“医疗”行业才显示“HIPAA合规要求”字段。我们用Zapier监听Typeform提交自动触发Sqribble生成。步骤2数据清洗与预处理0:25-0:40Zapier收到表单后执行预处理脚本将“预算范围”单选值转换为数值10-50万→300000根据“行业”和“核心需求”从知识库匹配3个相关案例ID调用CRM API补全客户地址、联系人邮箱等字段。最终生成一个标准JSON对象作为Sqribble的输入数据包。步骤3模板调用与渲染0:40-2:10Sqribble后台接收到JSON开始执行加载“标准销售方案_v2.3”模板版本号精确到小数点后一位确保可追溯解析数据包将client_name填入封面budget填入报价页执行条件逻辑因is_vip为true渲染VIP专属服务条款因industry为“IT”从案例库加载3个IT行业案例用{{#each}}循环插入应用样式规则所有标题用思源黑体报价表格加蓝色边框页眉显示公司Logo生成PDF调用WeasyPrint引擎嵌入字体添加水印“CONFIDENTIAL - {{date}}”。步骤4交付与归档2:10-3:12PDF生成后自动执行发送邮件给客户附件PDF内嵌预览图上传至客户专属云盘文件夹在CRM里创建“文档交付”活动记录关联到该客户将原始JSON数据、生成日志、PDF哈希值存入审计数据库。实测对比人工制作同样方案平均耗时47分钟且交付后常被客户追问“第5页的案例数据来源”而自动化流程里审计日志直接给出生成时间、模板版本、数据源快照回复只需30秒。4.2 模板版本管理如何让100个模板不变成一团乱麻模板多了管理就是噩梦。我们团队从12个模板起步现在维护着217个模板含行业变体、语言版本、合规版本靠的是这套版本管理体系体系核心三维度唯一标识每个模板ID由三部分组成[业务域]-[文档类型]-[版本号]例如sales-proposal-v2.3销售-方案书-2.3版hr-onboarding-zh-v1.1HR-入职指南-中文-1.1版legal-NDA-gdpr-v3.0法务-保密协议-GDPR合规-3.0版操作规范小修小补文案微调、错别字版本号0.1如v2.3→v2.4结构变更增删章节、改占位符版本号1.0如v2.4→v3.0重大升级更换引擎、重构数据模型主版本号1如v3.0→v4.0。所有变更必须提交“变更说明”描述影响范围如“v3.0版删除‘微信支付’条款因公司已停止该渠道”。技术保障Sqribble后台开启“模板历史版本”功能每次保存自动存档我们用Git同步模板JSON源码Sqribble支持导出模板为JSON实现代码级版本控制建立“模板健康度看板”统计各模板近30天调用量、失败率、平均生成时长对失败率5%的模板自动告警。经验教训早期我们没做版本隔离市场部更新了sales-proposal模板结果法务部正在用的legal-NDA模板因共用同一套样式库页眉突然变成了销售部Logo。现在所有模板的样式、字体、水印都独立打包互不影响。4.3 多语言与多区域适配一套模板全球交付跨国业务最头疼的不是翻译而是“本地化适配”。比如给德国客户发方案不只是把中文翻成德文还要日期格式从“2024年5月20日”变成“20.05.2024”货币符号从“¥”变成“€”金额千分位用点号1.000,00法律条款替换为德国《民法典》相关条目公司地址用德文地址格式。Sqribble用“语言包区域规则”双轨制解决语言包Language Pack提供德文、英文、日文等翻译文件包含所有静态文本如“执行摘要”→“Zusammenfassung”区域规则Region Rule独立配置如“德国区域”启用“日期格式DD.MM.YYYY”、“货币EUR”、“法律库DE-CivilCode”。关键实现在数据包里传入locale: de-DE模板自动加载对应语言包和区域规则。我们甚至做了“混合语言”支持——客户总部在东京但项目在新加坡方案主体用日文报价页用英文只需在模板里用{{#if locale ja-JP}}...{{else}}...{{/if}}切分。5. 常见问题与排查技巧实录5.1 生成失败的五大高频原因与速查表生成失败是落地初期最常遇到的问题。我整理了三年来的217次故障记录归纳出五大高频原因附带一键排查步骤故障现象可能原因排查步骤解决方案PDF空白页数据源未正确连接或JSON格式错误1. 进入“数据源管理”检查连接状态2. 复制JSON数据用JSONLint验证格式3. 查看生成日志中的“数据解析错误”行修复JSON结构如补全缺失的逗号或在Zapier里加JSON格式化步骤占位符显示为{{xxx}}字段名不匹配或数据包中该字段为null1. 检查模板中占位符名如{{client_name}}2. 对照数据包确认字段存在且非空3. 在日志中搜索“field not found”使用{{#if client_name}}...{{else}}N/A{{/if}}兜底或在数据预处理中补默认值条件内容不显示条件表达式语法错误或布尔值类型不符1. 检查{{#if}}内的表达式如status active不能漏引号2. 确认数据源中status是字符串而非数字3. 用{{log status}}在模板中打印调试改用显式比较{{#if status active}}或转换类型{{#if status.toString() active}}样式错乱字体变形、间距异常PDF引擎未嵌入字体或样式规则冲突1. 检查“输出设置”是否勾选“嵌入所有字体”2. 在样式管理中查看该元素的“继承样式”路径3. 临时禁用所有自定义CSS用默认样式测试优先使用Sqribble内置字体如“思源黑体”避免自定义Web字体样式规则按“全局→章节→段落”层级覆盖生成超时5分钟模板过大50页或嵌入大量高清图片1. 查看模板页数和媒体文件大小2. 在日志中定位“rendering timeout”3. 测试移除图片后的生成时间图片压缩至WebP格式质量70%单图500KB超长文档拆分为“主报告附件包”独家技巧我在所有模板开头加了一行隐藏调试代码{{#if debug_mode}}div stylecolor:redDEBUG: {{json data}}/div{{/if}}。上线前开启debug_mode生成的PDF里会显示完整数据包一眼看出字段是否传入。上线后关闭代码自动消失。5.2 性能优化的四个实战技巧当模板调用量激增性能就成了瓶颈。我们从日均50次提升到日均3200次靠的是这四个技巧技巧一模板分片Template Splitting把一个50页的“全功能方案”模板拆成core-template封面、目录、通用章节industry-templatesIT/制造/教育等子模板compliance-templatesGDPR/CCPA等合规模块主模板用{{ industry-template}}动态加载。好处修改IT行业案例只需更新industry-templates/it.json不影响其他行业加载速度提升60%因为引擎不用解析整套50页逻辑。技巧二数据懒加载Lazy Data Loading不是所有字段都需要实时加载。比如“客户历史合作项目”列表只在“增值服务”章节用到。我们在数据预处理阶段不把整个项目列表塞进主JSON而是主JSON只存has_past_projects: true当模板渲染到{{#if has_past_projects}}区块时触发一个异步API按需拉取项目数据。这样主生成流程从8秒降到2.3秒用户体验丝滑。技巧三缓存策略Caching Strategy对高度复用的内容启用缓存静态资源Logo、标准条款缓存1年行业案例库缓存1小时因案例常更新客户数据缓存5分钟足够覆盖同一客户的多次生成。Sqribble本身不支持缓存我们用Cloudflare Workers在API网关层实现命中率稳定在89%。技巧四异步队列Async Queue高峰期批量生成如每月初发1000份账单直接调用会超时。我们改用RabbitMQ队列前端提交请求立即返回“任务已接收ID: JOB-789”后台Worker消费队列逐个生成生成完成发邮件通知并更新CRM状态。用户无感知系统不崩溃。5.3 安全与合规的硬性红线文档自动化涉及客户数据安全是生命线。我们踩过坑也总结出三条不可逾越的红线红线一绝不硬编码敏感信息早期有同事为图方便在模板里直接写{{#if client.id 12345}}VIP条款{{/if}}把客户ID当判断依据。这是严重违规——ID可能泄露且无法审计。正确做法所有业务判断必须基于数据包中已授权的字段如client.tier且该字段由CRM统一管理模板只读取不存储。红线二PDF输出必须禁用交互功能生成的PDF默认可能启用JavaScript、表单填写、注释功能。这些在客户文档中是安全隐患。我们强制在输出策略中禁用JavaScript设置为“只读”模式移除所有交互式表单域。用pdfcpu validate工具定期扫描输出文件确保100%合规。红线三审计日志必须留存180天以上每一份生成的PDF必须关联生成时间戳精确到毫秒模板ID与版本号输入数据包的SHA-256哈希值不存原始数据只存哈希操作人CRM用户ID输出文件MD5。这些日志同步至AWS S3 Glacier满足金融行业最低存档要求。有一次客户质疑“你们方案里写的交付日期和邮件不一致”我们30秒内调出日志证明PDF生成时间早于邮件发送且日期字段哈希值与CRM一致争议当场平息。最后分享一个真实体会模板驱动的终极价值不是让文档生成更快而是让文档成为可编程的业务资产。当一份客户方案不再是一次性交付物而是由数据、规则、品牌共同定义的“活文档”你就能用它做更多事——比如把1000份方案的“核心需求”字段聚合成热力图发现83%的客户都在提“系统集成”或者监控“报价页”中“折扣率”字段的分布及时发现销售团队的定价偏差。文档自动化本质上是把业务经验固化成可执行、可度量、可进化的数字资产。这条路我们走了三年还在继续。