
AgentScope 这阵子在 AI 应用开发圈子里讨论度确实高尤其是做多智能体Multi-Agent应用落地的那帮人几乎人手一份对比报告。它最让我眼前一亮的地方不是又造了个“大模型调用框架”而是它把“多个 Agent 协同干活”这件事从作坊式的脚本拼接拽到了工程化的轨道上。我花了两周时间把 2.0 版本从源码到示例工程完整过了一遍还拿它重构了一个内部的知识库问答自动工单分类的小系统。这篇就从一个实际动手者的角度聊聊 AgentScope 到底牛逼在哪、怎么上手、以及那些文档里不会明说的坑。如果你正准备选型多智能体框架或者已经被 LangChain 那套复杂的编排搞到头大这篇值得看完。1. AgentScope 到底是干什么的为什么要关注它1.1 先搞清楚多 Agent 开发的痛点在哪很多人一开始接触 Agent 开发都是从“调 API、拼 Prompt”起步的。单个 Agent 的对话、工具调用其实不难做拿个大模型 Key写几轮对话历史再挂几个 Function Call一个“有点智能”的客服机器人就出来了。但真到了生产环境你会发现事情完全不是这么回事。业务方不会只要一个机器人他们要的是“一个能查库存、能算价格、能自动开单、遇到异常还能找领导审批”的完整虚拟员工。这就意味着你需要让 5 个、10 个乃至更多的 Agent 协作一个负责理解用户意图一个负责调库存接口一个负责算账一个负责走审批流它们之间还要互相传递上下文、共享状态、处理失败重试。这时候如果没有一个好的编排框架代码会迅速腐化成意大利面每个 Agent 之间的调用关系硬编码在函数里消息传递靠全局变量出错之后根本追查不到是谁把状态改坏了。我见过最夸张的一个项目为了协调 4 个 Agent写了 2000 多行胶水代码最后连作者本人都说不清楚数据是怎么流过去的。1.2 AgentScope 的定位和核心价值AgentScope 是阿里通义实验室开源的一套多智能体开发框架它想解决的问题只有一个让“多个大模型 Agent 协同工作”像写单机程序一样简单同时具备分布式扩展的能力。它不是又一个“模型接入层”。它做的是整个 Agent 生命周期的管理从 Agent 的构建、消息的定义与传递、协作流程的编排到运行时的监控与调试甚至包含一套专门为多 Agent 场景设计的消息回溯机制。直白点说如果用盖房子类比LangChain 提供的是砖头、水泥和瓦刀而 AgentScope 提供的是整栋房子的预制板模块外加一套施工图纸和管理规范。这个定位差异非常关键。它决定了你用它干活时不需要关心“这个 Agent 的消息该存到哪个变量里”“Agent 之间的调用是同步还是异步”这种脏活累活框架替你把这些底层的复杂逻辑消化掉了。对于团队协作开发来说它提供的标准化消息协议和 Agent 抽象也能避免“每个人的 Agent 长得都不一样接不到一起”的尴尬。1.3 它适合谁用不适合谁用以我这段时间的体验AgentScope 最对口的场景是做企业内部复杂流程自动化的团队比如工单处理、供应链协同、数据分析报告自动生成。需要多个角色配合完成任务的应用比如“项目经理 程序员 测试员”三位一体的 AI 开发团队。已经在用 LangChain 但被其管道式编排限制住的开发者想升级到更灵活的多智能体拓扑。学术界做多智能体仿真、社会学博弈研究的它的分布式特性很适合跑大规模模拟。不太适合的则是你只是想把大模型接进现有系统做个简单的“智能问答”或者你的业务场景根本不需要多个角色协作只是单点工具调用。这种情况下用 AgentScope 属于高射炮打蚊子反而增加了学习和运维成本。选型这件事合适比牛逼更重要。2. 架构拆解AgentScope 的三大核心设计是怎么解决协作难题的2.1 Agent 抽象一切皆可成为 AgentAgentScope 里Agent 是第一公民。它的抽象层级做得非常有意思官方内置了一堆常用的 Agent 类型比如用于对话的UserAgent模拟用户、AssistantAgent助手、ReActAgent带推理和行动循环的智能体还有用于工具调用的ToolAgent。但最让我欣赏的是它把消息本身也 Agent 化了。什么意思就是你在 AgentScope 里传递的Msg对象不是简单的 string而是一个包含了发送者、接收者、内容、类型、元数据的数据包。消息可以携带结构化数据比如一个 JSON 格式的库存查询结果、可以引用其他消息甚至可以携带 Python 对象和回调函数。这个设计的牛逼之处在于Agent 之间的协作不再局限于“你问我答”的文本对话而是可以进行结构化的数据交换。比如 A Agent 算出来的收益表可以直接以 DataFrame 的形式发给 B Agent 做下一步处理B 拿到后不需要再解析文本、猜格式。在金融风控这种对数据精度要求极高的场景这个能力几乎是救命的。2.2 管道式编排与控制流解耦AgentScope 的编排模型借鉴了深度学习框架的思路把任务执行表达成一个 Pipeline管道但又不局限于简单的“线性串联”。它支持的控制流包括顺序执行、条件分支if、循环for/while、并行执行parallel以及异步消息传递。这里有个在工程上很实用的设计Agent 的执行流程和消息的传递是解耦的。控制流负责“什么条件做什么事”消息传递负责“数据怎么流动”两者互不干扰。举个例子在金融研报生成场景里主流程是“数据采集 → 行情分析 → 报告撰写 → 合规审查”的串行逻辑但这个过程中数据采集 Agent 可以同时向多个数据源发起异步请求并行执行行情分析 Agent 在等待数据时可以先去读取历史报告模板。如果用传统的函数调用方式写这种并行逻辑你会头疼死但在 AgentScope 里这只是一个 Pipeline 定义的事情。它的执行引擎底层还做了调度优化可以通过配置而切换为 Ray 或单机多进程执行。之前 LangChain 搞分布式多 Agent 得靠langgraph配置复杂不说查起错来也别扭。AgentScope 在这块做得更“傻瓜化”默认情况下你写完的 Pipeline 原样跑加一个配置项就能上 Ray 跑分布式。2.3 消息回溯与调试机制多 Agent 排错的救命稻草如果你写过复杂的多 Agent 应用一定经历过最毛骨悚然的场景15 个 Agent 跑了一分钟最后输出的结果完全错了但你根本不知道是哪一个环节开始错的。传统方案只能靠 print或者给每个 Agent 的调用加日志费时费力。AgentScope 在这块的突破性设计叫做消息回溯msg_history_backtracking。整个执行过程中的每条消息都被记录在案形成了一个消息时间轴。你可以像回放视频一样把某次任务执行完整地重放一遍检查每一个 Agent 收到了什么消息、基于什么状态做了决策、最终输出了什么结果。这个机制在调试“智能体幻觉”或“上下文污染”问题时尤其好用。我之前遇到一个 CaseA Agent 把 B Agent 输出的中间结果误当作了最终答案导致整个报告数据错位。用回溯功能一看立马定位到是消息的Type字段没有区分“中间分析”和“最终结论”只需要在消息里加一下标识就解决了。这种问题要是靠肉眼看日志估计得排查一周。3. 实操记录手把手教你搭一个“分析检索写作”三 Agent 协作系统3.1 环境准备与安装细节AgentScope 的安装分两层先装基础框架再按需装模型后端和工具库。我推荐直接从 GitHub 拉源码安装能避免一些版本匹配的坑。# 1. 克隆官方仓库2.0 版本分支 git clone https://github.com/agentscope-ai/agentscope.git cd agentscope # 2. 创建虚拟环境Python 3.9 以上别用 3.13有些依赖还没适配 python -m venv venv_agentscope source venv_agentscope/bin/activate # 3. 安装核心包默认不装分布式依赖如果你需要跑 Ray 再装 pip install -e . # 4. 如果要用内置的一些工具比如网页检索、代码执行装 extra 依赖 pip install -e .[rag,tool]安装过程中最容易踩的坑是依赖冲突。AgentScope 对pydantic和openai的版本有要求特别是如果你环境里之前装过新版的 transformers很可能会碰到 protobuf 版本打架的问题。我的建议是严格按照官方 requirements 来不要自作主张升级某个依赖包否则跑起来各种不明原因报错排查成本极高。3.2 配置你的模型后端AgentScope 对模型接入做了一个很优雅的抽象你不需要在每个 Agent 里单独写模型初始化代码而是在全局配置一次之后 Agent 按名字调用就行。import agentscope # 用 OpenAI 兼容接口接入任何厂商的大模型 agentscope.init( model_configs[ { config_name: my-gpt4, # 自定义别名之后直接引用 model_type: openai, # 支持 openai, dashscope, anthropic 等 model_name: gpt-4o, api_key: YOUR_API_KEY, generate_args: { temperature: 0.7, max_tokens: 4096, } }, { config_name: embedding-model, model_type: openai, model_name: text-embedding-3-small, api_key: YOUR_API_KEY, } ] )这里有个工程上的细节值得点赞同一个大模型可以注册多个不同的config_name分别配不同的 temperature 或 max_tokens。比如 GPT-4o 你可以注册一个gpt4-analysistemperature0.2用于严谨的数据分析和一个gpt4-writertemperature0.9用于创意写作。这样不同角色 Agent 拿到的虽然是同一个基座模型但行为模式完全不同比在代码里反复切换参数要干净得多。3.3 定义三个协作 Agent我们的目标是做一个“AI 行业新闻自动分析器”一个 Agent 负责检索最新 AI 新闻分析者一个 Agent 负责打分和提炼观点评论者一个 Agent 负责整合成一篇短文写作助理。我用三种不同的 Agent 类型来演示 AgentScope 的灵活性。from agentscope.agent import AgentBase from agentscope.message import Msg # 1. 分析者内置 ReActAgent支持工具调用新闻检索 class NewsAnalyzer(AgentBase): def __init__(self, nameanalyzer): super().__init__( namename, sys_prompt( 你是一名严谨的 AI 行业分析师。 收到用户的查询后使用搜索工具查找最新资料。 返回消息时必须包含【新闻标题】【来源】【时间】【核心内容】四个字段。 ) ) # 注册一个检索工具 self.tools {search_news: self._search_news_func} def _search_news_func(self, query: str) - str: # 实际项目里接 Bing/SerpAPI 等搜索 API # 我这里模拟返回固定结果便于演示 return f[模拟搜索结果] 关于{query}的最新报道... def reply(self, x: Msg None) - Msg: # 内部调用 ReAct 循环自动决定是否需要调用工具 return self.react_step(x) # 2. 评论者纯文本分析不需要工具 class NewsCritic(AgentBase): def __init__(self, namecritic): super().__init__( namename, sys_prompt( 你是一名资深科技评论员。 你会收到一份新闻简报请从行业影响、技术突破、商业价值三个维度打分1-10分。 只输出 JSON 格式的打分结果不要其他文字。 ) ) def reply(self, x: Msg None) - Msg: # 从 x 中提取分析文本调用大模型 prompt f请分析以下新闻:\n{x.content} response self.model(prompt) return Msg(nameself.name, contentresponse, roleassistant, msg_typeanalysis) # 3. 写作助理整合最终内容 class NewsWriter(AgentBase): def __init__(self, namewriter): super().__init__( namename, sys_prompt( 你是一名科技专栏编辑。 根据分析师的观点和评论者的评分写一篇 300 字左右简讯。 语言要求通俗、有重点、带数据佐证。 ) ) def reply(self, x: Msg None) - Msg: prompt f请整合以下材料成一篇简讯:\n{x.content} response self.model(prompt) return Msg(nameself.name, contentresponse, roleassistant, msg_typefinal_report)注意这里我刻意没有把三个 Agent 的代码写得太“花哨”每一个的reply都遵循同样的套路接收消息 → 解析内容 → 调用模型或工具 → 返回Msg。这就是 AgentScope 的统一抽象带来的好处不管内置类型还是自定义类型在编排器眼里它们都是“输入一个 Msg输出一个 Msg”的黑盒这让后续的管道编排变得极其简单。3.4 Pipeline 编排让三个 Agent 像流水线一样干活下面这段是整个演示的核心展示了 AgentScope 最核心的 Pipeline 能力。from agentscope.pipeline import Pipeline # 创建三个 Agent 实例 analyzer NewsAnalyzer() critic NewsCritic() writer NewsWriter() # 定义一个顺序执行管道2.0 还支持并行分支后面讲 pipeline Pipeline( steps[ analyzer, # 第一步检索并分析新闻 critic, # 第二步打分 writer, # 第三步写稿 ] ) # 启动消息触发整个流程 init_msg Msg( nameuser, content帮我分析一下最近关于多智能体框架的行业动态, roleuser, ) final_result pipeline.run(init_msg) print(final_result.content)就这么简单。pipeline.run(init_msg)的底层逻辑是把init_msg交给analyzer.reply()拿到的返回消息自动作为下一个 Agentcritic的输入以此类推。你不需要手动管理消息传递不需要写循环不需要关心上一个 Agent 输出的是文本还是结构化数据。如果你要处理并行分支比如“既要检索 A 主题又要检索 B 主题然后再汇总”可以这样写from agentscope.pipeline import ParallelBranch pipeline Pipeline( steps[ ParallelBranch( branches[ [analyzer_a], # 分支 1检索 A [analyzer_b], # 分支 2检索 B ] ), writer, # 等两个分支结果齐了再汇总写作 ] )这种“分支-汇总”模式在实际业务里极其常用。我做过的一个竞品分析系统就是同时并行调用 5 个分析师 Agent 分别研究不同竞品最后汇总给写作 Agent 生成报告。代码结构跟上面完全一样只是分支更多。换在传统编程模式下这种并发协调至少得手写几十行线程管理代码。3.5 用内部消息机制传递复杂状态如果三个 Agent 之间需要共享的数据非常复杂比如要传一个 Pandas DataFrame、一张图表、甚至一个临时文件路径直接拼在content文本里显然不合适。AgentScope 的Msg对象支持在初始化时挂任意额外的字段这些字段不会影响模型生成却能跟着消息管道走到下一个 Agent。# 分析者返回时把结构化数据挂到额外字段上 result_msg Msg( nameself.name, content新闻分析完成原始数据见 analysis_data 字段, roleassistant, msg_typeanalysis, analysis_data{keywords: [LLM, Agent], score: 8.5} ) # 评论者收到消息后可以直接用 x.analysis_data def reply(self, x: Msg None) - Msg: keywords x.analysis_data[keywords] # 直接取不需要解析文本 ...这一点看着小实际用起来极其舒服。它把“模型可读的文本”和“程序可读的结构化数据”拆开了。模型看到的是自然语言描述程序看到的是精确的数据结构两种信息互不污染。我之前用别的框架搭多 Agent 系统时为了让下游 Agent 的 Python 代码能拿到准确数据得写一堆正则去解析模型的输出而 AgentScope 直接把这个脏活从根上解决了。4. AgentScope 2.0 的新特性RAG as Service 和 Java 客户端4.1 RAG as Service 是怎么简化知识库接入的2.0 版本里最重磅的更新我觉得是内置了RAG as Service能力。从使用者的角度看就是不用再自己调向量数据库、自己写检索提示词了AgentScope 把整个 RAG 链路封装成了一个标准服务注册一下就能用。以前做一个带知识库的 Agent流程是这样的加载文档 → 切分 → 调 embedding 接口向量化 → 存入向量库 → 写检索代码 → 构造 prompt 模板。每一步都可能出问题特别是文档切分切大了检索精度差切小了上下文塞不下。AgentScope 2.0 的做法是from agentscope.rag import RAGService, Document # 1. 初始化 RAG 服务指定向量存储方式 rag RAGService( embedding_model_configembedding-model, # 用前面定义的 embedding 配置 storagefaiss, # 向量库后端也可用 Milvus ) # 2. 注入文档支持 pdf、docx、md 等 rag.add_documents([ Document(path企业知识库.pdf, sourceinternal), Document(path产品手册.docx, sourceinternal), ]) # 3. 在 Agent 的 tool 列表里挂上检索工具 rag_tool rag.create_tool( nameknowledge_search, description从企业内部知识库检索信息入参为查询字符串, top_k3 )之后 Agent 在回复过程中如果遇到不确定的信息会自动调用这个knowledge_search工具拿到检索结果后再组织答案。整个过程和之前定义的NewsAnalyzer挂工具的方式完全一致学习成本为零。我实测下来它对检索结果的封装做得尤其到位返回的时候会自动带上文档来源和页码这样最终的答案可以附上引用信息。这对企业知识库这种“答案必须可溯源”的场景极其重要。内部审计的时候你能说清楚每条回答是依据哪份文档的第几页得出的合规压力一下就小了很多。4.2 2.0 在可观测性和性能上的升级2.0 另一个让我觉得“从业余走向专业”的改动是引入了更完善的可观测性接口。老版本调试基本靠打印2.0 支持了结构化的 Trace 导出。from agentscope.monitor import Tracer, ConsoleReporter tracer Tracer(reporters[ConsoleReporter()]) pipeline.run(init_msg, tracertracer)跑完之后控制台会把整个调用链打印出来每个 Agent 的耗时、模型调用次数、工具调用次数、消息大小。如果你是做生产系统这个 Tracer 可以直接对接 Prometheus 或 SkyWalking 做指标采集。性能方面2.0 对异步并行执行做了大幅优化。官方给的数据是在 16 核机器上跑 100 个 Agent 的并行仿真比 1.0 队列式执行快了接近 20 倍。个人实测没有跑那么大规模但在一个 8 Agent 的并行分支场景里总耗时从原来的 40 多秒压缩到了 6 秒出头体感非常明显。这背后是把并行 Agent 的消息调度从进程内队列挪到了可控的线程池并通过引入入站出站缓冲机制避免了 GIL 竞争。4.3 关于 agentscope java 的那些文章说的是什么搜索“agentscope java”的时候出现了一堆文章我这里顺便说明一下。这些文章讨论的主体并非 AgentScope 的官方核心包而是社区在 Java 服务端场景下的集成探索。AgentScope 官方主仓库是 Python 的但阿里内部很多业务系统是 Java 技术栈所以社区的开发者们尝试用 HTTP 服务包装 Python 的 Agent 场景再通过 Spring Boot 去做接入。我翻了其中几篇核心套路基本一致把 Python 侧跑起来的 AgentScope Pipeline 封装成一个微服务对外暴露 HTTP/WebSocket 接口Java 侧通过 OpenFeign 或者 WebClient 去调用。这种方案本身可行但它本质上是个“跨语言桥接”并不是说 AgentScope 跑在 JVM 里了。如果你所在团队是纯 Java 技术栈我的建议是不要强求让 AgentScope 跑在 Java 里而是让 Python 侧的多智能体团队独立部署成一个 Agent 服务层通过标准 API 和 Java 业务层对接。这样模块边界清晰两边都能用自己最擅长的技术栈出了分布式问题也好排查。这个模式我们已经用在了两个生产项目上非常稳。5. 避坑指南这些文档没写清楚的实操教训5.1 模型 API 兼容问题比想象中严重AgentScope 官方文档宣称支持各种 OpenAI 兼容接口但实际上不同模型服务商的“兼容度”差异很大。我一开始图便宜接了一个国内厂商的 OpenAI 兼容端点结果发现它的 Function Call 返回格式在边缘 case 上有问题导致 Agent 的工具调用经常解析失败错误信息还特别隐晦。后来老老实实按官方推荐的方式接入并做了几个适配补丁才解决。这里提醒一句如果你用的是非 OpenAI 原生模型最好先在单 Agent 的 ReAct 场景里测一轮工具调用确认没问题再上多 Agent 编排否则很可能把问题混在一起排查难度指数级上升。5.2 并行分支不要滥用颗粒度要想清楚刚开始用ParallelBranch的时候我犯过一个典型错误把同一个 Agent 的 20 个子任务并行扔出去想提高吞吐。结果模型服务的限流策略把我直接封了 IP。后来学乖了并行度的设置要根据底层模型的 RPM每分钟请求数来在 Pipeline 里通过max_concurrency参数限制最大并行数。如果底模型是 QPS5那你并行度设 20 就是给自己找麻烦。合理做法是设一个略低于模型限流的并发上限再加一个简单的任务队列做缓冲。5.3 消息回溯的文件大小比你想象的大消息回溯虽然好用但它会记录每一条消息的完整内容。跑一个复杂的 Pipeline生成了 1000 条消息回溯文件可能就好几百兆。如果你的 Agent 里还传了图片、PDF 等二进制内容那磁盘空间会占用得更加惊人。我现在的做法是生产环境默认不开启回溯只有调试阶段才通过环境变量打开需要长期留痕的业务只保留关键阶段的消息切片而不是全部内容。这个取舍要提前想好否则监控告警“磁盘空间不足”时你会后悔的。5.4 RAG 服务的底层依赖重部署要规划pip install -e .[rag,tool]这个安装命令看起来简单但它会拉进来一堆重依赖faiss-cpu、pyspark某些版本、tika等。尤其是 tika它是个 Java 服务用来解析文档的在纯 Python 的 Docker 镜像里跑会有点别扭。如果你部署的是轻量级容器建议把 RAG 服务单独拆成一个组件不要跟主服务挤在一起镜像体积和启动时间都会好看很多。6. 常见问题速查表为了让你少走弯路我把这半个月实践中遇到的问题整理成一个速查表。如果你在部署或使用过程中碰到了下面某一条可以直接照方抓药。症状可能原因解决思路安装时提示distutils错误Python 版本过高3.12降到 Python 3.9-3.11 重新创建虚拟环境Msg消息里中文乱码终端编码问题非框架问题设置PYTHONIOENCODINGutf-8Agent 不调用工具直接给答案系统提示词或模型能力不足在 sys_prompt 里明确工具使用条件或换更强的模型ParallelBranch结果不全有分支抛了异常但外层静默吞掉检查子 Agent 的 reply 是否 catch 了所有异常外层没有重新抛出模型 API 响应报invalid_request_error某个 Agent 的上下文超长调低单 Agent 的max_tokens或开启消息截断策略Pipeline 运行非常慢日志级别是 DEBUG 且开着消息回溯生产环境设置LOG_LEVELINFO关闭回溯知识库检索返回空结果embedding 模型和检索模型不匹配统一用同一个 embedding 配置不要混用不同厂商向量在 Windows 上跑分布式报错Ray 对 Windows 支持不完善单机直接跑进程模式生产环境换 Linux除表格之外还有个排查心法遇到多 Agent 协作结果不对不要急着看代码逻辑先开消息回溯把消息时间轴过一遍看业务数据是在哪一步开始发生漂移的。八成问题出在消息内容的预期错位而不是代码本身的语法或运行时错误。7. 一个让你快速感知 AgentScope 威力的进阶玩法如果你已经跑通了上面三 Agent 的例子我建议你再试一个稍微进阶的玩法用 AgentScope 的批量仿真实例playground模拟 10 个用户同时向客服系统提问验证系统的并发稳定性。import agentscope from agentscope.playground import Simulator sim Simulator( app_pipelinepipeline, # 你的客服 Agent 管道 user_agents[ UserAgent(namefuser-{i}, sys_prompt模拟一个着急的客户提问) for i in range(10) ], max_rounds5 # 每个用户最多对话 5 轮 ) results sim.run() print(results.get_metrics())这段代码一跑你会直观感受到多 Agent 系统在仿真测试上的威力。它能一次性模拟出 50 轮完整对话并统计出每轮的平均响应时间、失败率、工具调用次数。拿这个数据去给业务方展示系统能力比任何 PPT 都有说服力。这也是 AgentScope 区别于其他框架的一个隐藏卖点不止让你开发 Agent还让你能像做压力测试一样验证 Agent 系统。我在搭建这个客服仿真时还发现了一个使用技巧UserAgent的sys_prompt里可以写“模拟一个愤怒的用户反复追问价格问题”这样测出来的系统边界情况比普通提问丰富得多。把各种极端用户性格都仿真一遍相当于给系统做了一次低成本的红队测试效果拔群。8. 最后再分享一点个人体会AgentScope 用下来我最深的感触是一个好的多智能体框架不应该让你整天关注 Agent 之间是怎么通信的、消息是同步还是异步、数据存哪个变量而应该让你把精力集中在怎么定义更好的角色、怎么设计更合理的流程、怎么写出更有效的提示词。AgentScope 恰恰就是在“把复杂性兜住”这件事上做得极好。和 LangChain 相比它在多 Agent 协作这一层的抽象更彻底并且为解决“分布式协同”和“运行时可观测”搭好了一座完整的地基。和 AutoGen 相比它对非对称角色协作和复杂工作流的支持更直观学习曲线也更平缓。当然它也不是完美的Java 生态的短板、RAG 服务的重依赖、以及面对超长上下文时的策略都还有优化空间但这些在“靠谱的多智能体编排”这个核心命题面前都属于可以接受的小瑕疵。如果你正纠结选哪个多智能体框架我的建议很简单去 GitHub 把 AgentScope 的源码拉下来挑一个跟业务最近的内置示例跑通再对比一下自己用别的方式实现的代码量答案会很清楚。我选择在博客上推荐它就是因为我重构的那套系统代码行数少了大概 60%并且第一次让团队所有人都能看懂完整的调用链路——这些实实在在的变化比任何技术选型的理由都更有说服力。