ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AI智能体Office套件实战:从架构设计到核心智能体实现

AI智能体Office套件实战:从架构设计到核心智能体实现 1. 项目缘起与整体架构设计1.1 为什么想到做一套AI智能体Office套件这个项目的起点其实很朴素我在日常工作中需要频繁处理文档、表格和演示文稿但市面上的办公软件虽然功能强大操作路径却越来越长。写一份周报要手动整理数据、调整格式、生成图表做一份项目汇报PPT要反复复制粘贴、对齐排版。这些重复劳动占据了我大量时间而真正需要思考的部分反而被压缩了。AI智能体技术的成熟让我看到了另一种可能——如果办公软件不再是被动等待我点击的工具而是能主动理解意图、自动执行任务的协作伙伴工作效率会发生质的变化。于是我开始构思一套以AI智能体为核心的Office套件它不是简单地在传统办公软件上叠加一个聊天窗口而是从底层重新设计人机协作流程让智能体成为文档处理的中枢。这套套件的目标用户很明确需要频繁处理办公文档的知识工作者、中小团队的项目负责人、以及希望用自动化手段提升效率的个人开发者。它解决的核心问题是——把“人操作软件”变成“人描述需求智能体完成操作”从而大幅降低办公场景中的机械性劳动。1.2 整体架构三层解耦设计在架构设计上我采用了三层解耦的思路这样每一层都可以独立迭代不会因为某一层的改动导致整个系统崩溃。第一层是交互层负责接收用户的自然语言指令、文件上传、以及多轮对话管理。这一层的关键是意图识别和上下文保持。用户说“把上个月的销售数据整理成表格再生成一个趋势图”系统需要拆解出两个子任务数据整理和图表生成并且知道这两个任务之间存在依赖关系。第二层是智能体调度层这是整个套件的核心。我设计了一个主控智能体Orchestrator Agent和多个专业智能体Specialist Agents的协作模式。主控智能体负责理解用户意图、拆解任务、分配资源、监控执行状态专业智能体则分别负责文档生成、表格计算、演示文稿排版、数据可视化等具体领域。这种设计参考了ReAct模式Reasoning Acting的思想让智能体能够“思考一步、行动一步、观察结果、再决定下一步”。第三层是工具执行层包含具体的文档处理引擎、表格计算引擎、图表渲染引擎等。这一层不涉及智能决策只负责高效、准确地执行原子操作。比如打开一个docx文件、在指定位置插入段落、调整表格列宽、导出PDF等。三层之间通过标准化的消息协议通信交互层把用户指令转成结构化任务描述调度层把任务拆解成原子操作序列执行层按序列执行并返回结果。这种解耦带来的好处是如果我想换一个更强大的文档渲染引擎只需要替换第三层的对应模块上层的智能体逻辑完全不用动。1.3 技术选型背后的考量在技术栈选择上我做了几个关键决策每一个都经过了实际测试和权衡。智能体框架方面我对比了直接调用大模型API和基于现成智能体平台搭建两种路线。直接调用API的灵活性最高但需要自己实现任务拆解、状态管理、错误恢复等逻辑开发周期长。基于平台搭建虽然上手快但定制能力受限尤其是当需要深度集成文档处理能力时平台的抽象层反而成了障碍。最终我选择了混合方案核心调度逻辑自己实现保证可控性大模型调用和基础工具链使用成熟服务保证稳定性。文档处理引擎方面我选择了基于开源库自行封装的方式。市面上虽然有现成的文档处理SDK但要么功能太重、要么对AI友好的接口不足。自行封装的好处是可以针对智能体的调用习惯做优化比如提供“在光标位置插入一段带格式的文字”这样的高层接口而不是让智能体去操作底层的XML节点。通信协议方面我采用了基于JSON-RPC的轻量级方案。每个智能体暴露一组标准方法主控智能体通过统一接口调用。这样做的好处是新增一个专业智能体时只需要实现标准接口并注册到调度中心即可不需要修改主控逻辑。这里有一个容易踩的坑不要试图让一个智能体包揽所有任务。我最初尝试用一个“全能智能体”处理文档、表格、PPT所有需求结果提示词越来越长准确率越来越低。拆分成专业智能体后每个智能体的提示词可以聚焦在特定领域准确率明显提升。2. 核心智能体的设计与实现细节2.1 主控智能体的任务拆解逻辑主控智能体是整个套件的“大脑”它的核心职责是把用户的一句自然语言指令转化成一组可执行的任务序列。这个过程我拆成了四个步骤意图分类、实体抽取、依赖分析、执行规划。意图分类解决的是“用户想做什么”的问题。我把办公场景中的常见意图分成了几大类文档创建与编辑、表格数据处理、演示文稿生成、格式转换、内容摘要与改写、多文档合并等。分类模型我用了小样本微调的方式在基础大模型上针对办公场景做了适配准确率从通用模型的七成左右提升到了九成以上。实体抽取解决的是“操作对象是什么”的问题。比如用户说“把Q3销售数据表里的华东区数据单独拿出来做个对比图”系统需要识别出源文件是Q3销售数据表、筛选条件是华东区、输出形式是对比图。这些实体信息会作为参数传递给后续的专业智能体。依赖分析解决的是“任务之间有没有先后关系”的问题。有些任务可以并行执行比如同时生成文档摘要和提取关键词有些任务必须串行比如必须先完成数据筛选才能生成图表。我实现了一个简单的依赖图构建器根据任务类型和实体关系自动判断执行顺序。执行规划解决的是“具体怎么执行”的问题。主控智能体会为每个子任务选择合适的专业智能体并生成调用参数。如果某个子任务失败主控智能体会根据错误类型决定是重试、降级处理、还是向用户请求澄清。2.2 文档智能体的实现要点文档智能体负责处理文字类任务包括生成新文档、编辑现有文档、格式调整、内容摘要等。它的实现有几个关键点值得展开说。文档结构感知是第一个难点。一份docx文件在底层是一棵复杂的XML树直接让大模型去操作XML节点既不现实也不可靠。我的做法是在文档引擎和智能体之间加了一层“文档抽象层”把文档表示成段落、标题、列表、表格等语义单元的序列。智能体操作的是这些语义单元文档引擎负责把语义操作翻译成底层的XML变更。格式继承是第二个难点。当智能体在文档中间插入一段新内容时这段内容应该继承前后文的格式还是使用默认格式我的策略是如果用户没有明确指定格式新内容继承前一个同级别段落的格式。比如在一个二级标题后面插入正文新正文会继承前一个正文段落的字体、字号、行距。这个规则听起来简单但实际实现时需要处理很多边界情况比如文档开头插入、表格内部插入、跨节插入等。长文档处理是第三个难点。当文档超过一定长度时大模型的上下文窗口可能装不下全部内容。我的解决方案是分块处理加摘要传递先把文档按章节切分成块每块单独处理同时生成块级摘要处理后续块时把前面块的摘要作为上下文传入保证整体一致性。实测下来这种方式在处理几十页的文档时效果稳定。2.3 表格智能体的计算与可视化能力表格智能体负责处理结构化数据核心能力包括数据清洗、公式计算、透视分析、图表生成。它的设计思路和文档智能体类似也是通过抽象层把表格操作语义化。数据清洗方面智能体可以识别常见的脏数据模式比如日期格式不统一、数字带单位、空值填充等。用户只需要说“把这张表清洗一下”智能体就会自动检测并处理这些问题。这里的关键是清洗规则的可解释性——智能体不仅执行清洗还会生成一份清洗报告说明做了哪些处理、影响了哪些行方便用户核对。公式计算方面我实现了一个公式解析器支持常见的统计函数和条件表达式。用户可以用自然语言描述计算需求比如“计算每个销售人员的季度达成率”智能体会自动识别出需要除法运算并生成对应的公式。对于复杂计算智能体会分步执行并展示中间结果方便排查问题。图表生成方面智能体根据数据特征自动推荐合适的图表类型。比如时间序列数据推荐折线图分类对比数据推荐柱状图占比数据推荐饼图。用户也可以指定图表类型和样式。图表生成后以图片形式嵌入文档或单独导出支持常见的图片格式。2.4 演示文稿智能体的排版逻辑演示文稿智能体是我花时间最多的模块因为PPT的“好看”很难用规则描述清楚。我的做法是把排版问题拆成两个子问题内容组织和视觉呈现。内容组织方面智能体根据用户提供的素材自动生成大纲然后为每页幻灯片分配内容。分配逻辑遵循“一页一个核心观点”的原则避免信息过载。如果某页内容过多智能体会自动拆分或建议精简。标题和正文的层级关系也会自动处理保证逻辑清晰。视觉呈现方面我实现了一套基于模板的排版引擎。模板定义了母版、版式、配色方案、字体组合等要素。智能体根据内容类型选择合适的版式比如标题页、目录页、内容页、图表页、总结页。对于内容页智能体会根据文字量和图片数量自动调整布局避免文字溢出或留白过多。实操心得PPT排版中最容易出问题的是中文字体兼容性。不同系统上的默认中文字体不一样如果模板中指定了某个特定字体在另一台机器上可能显示异常。我的做法是优先使用系统通用字体族并在导出时嵌入字体子集保证跨平台一致性。3. 实操过程与核心环节实现3.1 环境搭建与依赖安装这套套件的运行环境我推荐使用Python 3.10以上版本主要依赖包括文档处理库、表格计算库、图表渲染库、以及大模型调用SDK。下面是我实际使用的依赖清单和安装命令。pip install python-docx openpyxl python-pptx pip install pandas numpy pip install matplotlib plotly pip install openai httpx pydantic pip install fastapi uvicorn其中python-docx、openpyxl、python-pptx分别负责Word、Excel、PowerPoint的文件读写pandas和numpy负责数据处理matplotlib和plotly负责图表生成openai和httpx负责大模型调用fastapi和uvicorn负责对外提供HTTP接口。安装完成后需要配置大模型服务的访问凭证。我建议使用环境变量管理敏感信息不要硬编码在代码里。import os from openai import OpenAI client OpenAI( api_keyos.environ.get(LLM_API_KEY), base_urlos.environ.get(LLM_BASE_URL) )注意如果你使用的是国内的大模型服务base_url需要替换成对应的地址。不同服务商的接口兼容性有差异建议先跑通一个简单的对话测试再继续。3.2 主控智能体的核心代码实现主控智能体的实现我拆成了三个核心类TaskParser负责解析用户指令TaskPlanner负责任务拆解和规划TaskExecutor负责调度执行。下面展示关键部分的代码逻辑。from pydantic import BaseModel from typing import List, Optional class SubTask(BaseModel): task_id: str task_type: str # document, spreadsheet, presentation action: str # create, edit, analyze, visualize params: dict depends_on: Optional[List[str]] None class TaskPlan(BaseModel): original_query: str subtasks: List[SubTask] execution_order: List[str] class TaskParser: def __init__(self, llm_client): self.llm llm_client def parse(self, user_input: str) - TaskPlan: prompt self._build_parse_prompt(user_input) response self.llm.chat.completions.create( modelgpt-4, messages[{role: user, content: prompt}], response_format{type: json_object} ) plan_data json.loads(response.choices[0].message.content) return TaskPlan(**plan_data) def _build_parse_prompt(self, user_input: str) - str: return f你是一个办公任务规划助手。请把用户的指令拆解成子任务。 用户指令{user_input} 请输出JSON格式的任务计划包含subtasks和execution_order两个字段。 每个子任务包含task_id、task_type、action、params、depends_on。 task_type可选值document, spreadsheet, presentation action可选值create, edit, analyze, visualize, convert, summarize TaskExecutor的核心逻辑是按执行顺序遍历子任务检查依赖是否满足然后调用对应的专业智能体。class TaskExecutor: def __init__(self): self.agents { document: DocumentAgent(), spreadsheet: SpreadsheetAgent(), presentation: PresentationAgent() } self.results {} def execute(self, plan: TaskPlan): for task_id in plan.execution_order: task self._find_task(plan, task_id) if not self._dependencies_met(task): raise RuntimeError(f依赖未满足: {task_id}) agent self.agents[task.task_type] result agent.run(task.action, task.params) self.results[task_id] result return self.results def _dependencies_met(self, task: SubTask) - bool: if not task.depends_on: return True return all(dep in self.results for dep in task.depends_on)3.3 文档智能体的关键实现文档智能体的核心是把语义操作翻译成文档引擎的API调用。我定义了一组标准操作每个操作对应一个方法。class DocumentAgent: def __init__(self): self.doc None def run(self, action: str, params: dict): if action create: return self._create_document(params) elif action edit: return self._edit_document(params) elif action summarize: return self._summarize_document(params) elif action convert: return self._convert_format(params) def _create_document(self, params: dict): from docx import Document from docx.shared import Pt, RGBColor doc Document() title params.get(title, ) sections params.get(sections, []) if title: heading doc.add_heading(title, level0) heading.alignment WD_ALIGN_PARAGRAPH.CENTER for section in sections: level section.get(level, 1) heading_text section.get(heading, ) content section.get(content, ) if heading_text: doc.add_heading(heading_text, levellevel) if content: doc.add_paragraph(content) output_path params.get(output_path, output.docx) doc.save(output_path) return {status: success, path: output_path}_edit_document方法需要处理更复杂的场景比如在指定位置插入内容、替换文本、调整格式等。我的实现方式是先定位目标段落然后执行操作。def _edit_document(self, params: dict): from docx import Document doc Document(params[input_path]) operations params.get(operations, []) for op in operations: op_type op[type] if op_type insert_after: target_text op[target] new_content op[content] for i, para in enumerate(doc.paragraphs): if target_text in para.text: new_para doc.add_paragraph(new_content) para._element.addnext(new_para._element) break elif op_type replace: old_text op[old] new_text op[new] for para in doc.paragraphs: if old_text in para.text: for run in para.runs: run.text run.text.replace(old_text, new_text) doc.save(params[output_path]) return {status: success, path: params[output_path]}3.4 表格智能体的数据处理流程表格智能体的核心能力是数据清洗和公式计算。数据清洗我实现了一个规则引擎支持常见的清洗操作。import pandas as pd import numpy as np class SpreadsheetAgent: def __init__(self): self.df None def run(self, action: str, params: dict): if action analyze: return self._analyze_data(params) elif action visualize: return self._generate_chart(params) elif action clean: return self._clean_data(params) def _clean_data(self, params: dict): df pd.read_excel(params[input_path]) report [] # 处理空值 null_cols df.columns[df.isnull().any()].tolist() for col in null_cols: null_count df[col].isnull().sum() if df[col].dtype in [float64, int64]: df[col] df[col].fillna(df[col].median()) report.append(f列 {col} 填充了 {null_count} 个空值为中位数) else: df[col] df[col].fillna(未知) report.append(f列 {col} 填充了 {null_count} 个空值为未知) # 处理重复行 dup_count df.duplicated().sum() if dup_count 0: df df.drop_duplicates() report.append(f删除了 {dup_count} 行重复数据) # 处理日期格式 for col in df.columns: if df[col].dtype object: try: df[col] pd.to_datetime(df[col]) report.append(f列 {col} 转换为日期格式) except: pass output_path params.get(output_path, cleaned.xlsx) df.to_excel(output_path, indexFalse) return {status: success, path: output_path, report: report}图表生成部分我根据数据特征自动选择图表类型并支持用户自定义样式。def _generate_chart(self, params: dict): import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False df pd.read_excel(params[input_path]) chart_type params.get(chart_type, auto) x_col params[x_column] y_col params[y_column] if chart_type auto: if df[x_col].dtype datetime64[ns]: chart_type line elif df[y_col].nunique() 10: chart_type bar else: chart_type line fig, ax plt.subplots(figsize(10, 6)) if chart_type line: ax.plot(df[x_col], df[y_col], markero) elif chart_type bar: ax.bar(df[x_col], df[y_col]) elif chart_type pie: ax.pie(df[y_col], labelsdf[x_col], autopct%1.1f%%) ax.set_xlabel(x_col) ax.set_ylabel(y_col) ax.set_title(params.get(title, f{y_col} by {x_col})) plt.xticks(rotation45) plt.tight_layout() output_path params.get(output_path, chart.png) plt.savefig(output_path, dpi150) plt.close() return {status: success, path: output_path}3.5 演示文稿智能体的排版实现演示文稿智能体的实现我采用了模板驱动的方式。先定义一套基础模板然后根据内容自动填充。from pptx import Presentation from pptx.util import Inches, Pt from pptx.enum.text import PP_ALIGN class PresentationAgent: def __init__(self): self.prs None def run(self, action: str, params: dict): if action create: return self._create_presentation(params) def _create_presentation(self, params: dict): prs Presentation() prs.slide_width Inches(13.333) prs.slide_height Inches(7.5) # 标题页 title_slide_layout prs.slide_layouts[0] slide prs.slides.add_slide(title_slide_layout) slide.shapes.title.text params.get(title, 演示文稿) slide.placeholders[1].text params.get(subtitle, ) # 内容页 for section in params.get(sections, []): bullet_slide_layout prs.slide_layouts[1] slide prs.slides.add_slide(bullet_slide_layout) slide.shapes.title.text section[heading] body_shape slide.placeholders[1] tf body_shape.text_frame for point in section.get(points, []): p tf.add_paragraph() p.text point p.level 0 p.font.size Pt(20) output_path params.get(output_path, output.pptx) prs.save(output_path) return {status: success, path: output_path}实操心得PPT的母版设计直接影响最终效果。我建议在代码中先定义好几套配色方案和字体组合智能体根据内容类型自动匹配。比如技术类内容用蓝色系和等宽字体营销类内容用橙色系和无衬线字体。这样生成的PPT至少不会“难看”用户只需要微调即可。4. 常见问题与排查技巧实录4.1 智能体调用超时与重试策略在实际运行中大模型调用超时是最常见的问题之一。尤其是在处理复杂任务时单次调用的响应时间可能超过30秒。我的解决方案是设置分级超时和自动重试。问题现象可能原因排查方法解决方案调用超时无响应网络波动或服务端负载高检查网络连接查看服务状态设置超时时间30秒失败后重试2次返回结果不完整上下文窗口溢出检查输入token数量分块处理减少单次输入长度任务拆解错误提示词不够明确查看拆解结果与预期的差异优化提示词增加示例文档格式错乱格式继承规则冲突对比源文档和输出文档明确指定格式避免依赖自动继承重试策略我采用了指数退避的方式第一次失败后等待1秒重试第二次失败后等待3秒第三次失败后等待9秒。如果三次都失败则向用户报告错误并建议简化任务。import time from functools import wraps def retry_with_backoff(max_retries3, base_delay1): def decorator(func): wraps(func) def wrapper(*args, **kwargs): for attempt in range(max_retries): try: return func(*args, **kwargs) except Exception as e: if attempt max_retries - 1: raise delay base_delay * (3 ** attempt) time.sleep(delay) return None return wrapper return decorator4.2 文档格式兼容性问题文档格式兼容性是另一个高频问题。不同版本的Office软件对docx、xlsx、pptx的解析存在差异导致生成的文档在部分环境下显示异常。我遇到过的典型问题包括中文字体在Mac和Windows上显示不一致、表格边框在某些阅读器中丢失、PPT动画效果在导出后失效。针对这些问题我总结了几个应对策略。字体问题的解决方案是使用通用字体族并在导出时嵌入字体子集。如果目标环境不确定优先使用“微软雅黑”或“宋体”这类覆盖面广的字体。表格边框问题的解决方案是显式设置所有边框样式不要依赖默认值。在python-docx中可以通过table.style和单元格的tcPr元素来精确控制。PPT动画问题的解决方案是尽量避免使用复杂动画如果必须使用在导出时选择兼容模式。实测下来简单的淡入淡出效果兼容性最好。4.3 数据精度与计算准确性表格智能体在处理财务数据时精度问题尤为关键。浮点数运算的舍入误差可能导致最终结果与预期不符。我的做法是在数据处理阶段统一使用Decimal类型避免浮点数直接运算。对于百分比、汇率等需要精确表示的数值在输出时统一格式化为指定小数位。from decimal import Decimal, ROUND_HALF_UP def precise_divide(a, b, decimal_places2): if b 0: return Decimal(0) result Decimal(str(a)) / Decimal(str(b)) return result.quantize(Decimal(0. 0 * decimal_places), roundingROUND_HALF_UP)另外在生成图表时坐标轴的刻度范围也需要根据数据特征自动调整。如果数据集中在某个区间自动缩放可能导致图表难以阅读。我的策略是如果数据范围小于整体量级的10%则手动设置坐标轴范围并在图表中标注。4.4 多轮对话中的上下文管理多轮对话是提升用户体验的关键但也是容易出问题的地方。用户可能在对话中引用之前的内容比如“把刚才那个表格再改一下”。如果上下文管理不当智能体会丢失之前的操作记录。我的解决方案是维护一个会话状态对象记录每一轮的操作类型、涉及的文件、关键参数。当用户发起新指令时先把会话状态作为上下文传入帮助智能体理解指代关系。class SessionContext: def __init__(self): self.history [] self.current_files {} def add_interaction(self, user_input, plan, results): self.history.append({ user_input: user_input, plan: plan.dict(), results: results }) # 更新当前文件引用 for task_id, result in results.items(): if path in result: self.current_files[task_id] result[path] def get_context_summary(self, max_turns3): recent self.history[-max_turns:] summary [] for item in recent: summary.append(f用户: {item[user_input]}) summary.append(f执行: {item[plan][execution_order]}) return \n.join(summary)注意上下文不是越长越好。过长的上下文会增加token消耗还可能引入无关信息干扰判断。我建议只保留最近3到5轮的关键信息更早的内容可以压缩成摘要。4.5 安全性与权限控制这套套件涉及文件读写和数据处理安全性不容忽视。我实现了几个基本的安全措施。文件访问控制方面智能体只能访问用户明确指定的目录不能随意读取系统文件。所有文件路径都经过规范化处理防止路径穿越攻击。操作审计方面每一次智能体操作都会记录日志包括操作类型、涉及文件、执行时间、执行结果。这样即使出现问题也能快速定位。敏感数据保护方面如果检测到文件中包含身份证号、银行卡号等敏感信息智能体会自动脱敏处理并在输出时提醒用户注意数据安全。import re SENSITIVE_PATTERNS { id_card: r\d{17}[\dXx], bank_card: r\d{16,19}, phone: r1[3-9]\d{9} } def mask_sensitive_data(text): for name, pattern in SENSITIVE_PATTERNS.items(): text re.sub(pattern, lambda m: m.group()[:3] * * (len(m.group()) - 6) m.group()[-3:], text) return text5. 扩展方向与个人实践体会5.1 可以继续深挖的几个方向这套套件目前已经能覆盖大部分日常办公场景但还有几个方向值得继续深挖。多模态输入是一个明显的扩展点。目前系统主要处理文本和结构化数据如果加入图片识别能力用户可以直接拍照上传纸质表格智能体自动识别并转成电子表格。这个方向的技术栈已经比较成熟主要是集成工作量。协作编辑是另一个方向。目前系统是单用户模式如果加入实时协作能力多个用户可以同时编辑同一份文档智能体负责协调冲突和合并变更。这个方向的技术挑战主要在并发控制和冲突解决。领域知识注入也很有价值。不同行业的办公文档有特定的格式和术语规范比如法律合同、医疗报告、财务报表。如果能为智能体注入领域知识生成的内容会更专业、更符合行业习惯。5.2 我在实际使用中总结的几条经验第一不要追求一步到位。我最初想做一个能处理所有办公任务的“超级智能体”结果发现每个领域都有大量细节需要处理贪多嚼不烂。后来改成先做好文档处理再逐步扩展到表格和PPT每一步都打磨稳定后再进入下一个领域整体进度反而更快。第二提示词的质量决定智能体的上限。同样的模型提示词写得好和写得差效果差距非常大。我的经验是提示词要具体、要有示例、要明确输出格式。对于复杂任务把拆解逻辑写进提示词比让模型自己发挥要可靠得多。第三错误处理比功能实现更重要。办公场景对准确性的要求很高一个格式错误可能导致整份文档不可用。我在错误处理上花的时间不比功能实现少包括输入校验、异常捕获、降级处理、用户提示等。这些工作虽然不直接产生功能但决定了系统能不能真正用起来。第四保持技术栈的简洁。我试过引入各种新框架和新工具后来发现很多都是过度设计。最终稳定运行的版本核心依赖不超过十个库。每引入一个新依赖就多一个潜在的故障点。能用标准库解决的尽量用标准库。这套AI智能体Office套件从构思到稳定运行前后花了大约三个月时间。期间踩过的坑、推翻的方案、重写的模块不计其数但最终看到用户只需要一句话就能生成一份格式规范的文档时那种成就感是实实在在的。如果你也在做类似的事情我的建议是从最小的可用场景开始快速跑通闭环然后再逐步扩展。不要一开始就追求完美架构先让东西跑起来再在迭代中优化。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进