opencode工具系统、服务面与TUI交互实战集成详解
上篇写完之后不少朋友一直在追问几个问题opencode 除了拿来对话、改代码能不能把它当成一个真正能调度的工具平台那些自定义工具、外部服务到底怎么接进去终端界面能不能改得顺手一点这些问题其实指向的是同一件事——opencode 不只是一个聊天框它的工具系统、服务面模型供给与认证、外壳TUI 交互三块拼起来才是完整形态。这篇下篇我就把这三块拆开讲透再放一个完整的实战集成案例从零开始让你能把 opencode 真正嵌进自己的工作流里。先说清楚一个定位问题上篇讲的是“怎么用 opencode”下篇讲的是“怎么用透 opencode”。如果你只是想让它帮你改几个文件上篇就够了但如果你希望它能在你的项目里当一个真正干活的 agent——自己查代码、自己跑命令、自己调外部接口——那么工具和服务面这两块你就绕不开。外壳则是决定你天天用起来舒不舒服的关键。这篇文章适合已经开始用 opencode、但对它的扩展能力还没有完整概念的读者也适合那些正在纠结“opencode 到底能不能替代我手头工具链的一部分”的团队。1. 工具系统给 Agent 装上一双好用的手1.1 内置工具清单与调用机制opencode 的 agent 之所以能“动手”靠的是一套工具机制。模型本身只会生成文本它要读写文件、执行命令、发起网络请求都必须通过工具来完成。你可以把工具理解成给模型配的一双手——模型决定“下一步要做什么动作”工具负责把这个动作真正落地。内置工具里最常见的几个我按实际使用频率排个序read读取文件内容。模型需要理解代码前会先调用它。grep按正则搜索内容。比 read 更省 token适合先定位再细读。glob按模式匹配文件路径。常用于搞清楚“这个目录下有哪些文件”。bash执行终端命令。这是让 agent 真正“干活”的核心工具跑测试、装依赖、查进程都靠它。write / edit写文件或做局部编辑。edit 适合小范围修改write 适合重建文件。web_search / fetch联网搜索和抓取网页内容。需要实时信息时用到。task创建子任务委派给子 agent 并行处理。调用机制值得多说一句。模型并不是一次性把所有工具都调一遍而是根据当前对话状态、系统提示词里的工具描述以及每一步的执行结果动态决定下一次调用。opencode 会把每个工具的执行结果stdout、退出码、文件内容等作为上下文反馈给模型形成一个“思考 → 调用 → 观察结果 → 再思考”的循环。所以你在 TUI 里会看到一连串的工具调用日志那不是乱来的是 agent 在按自己的推理链路逐步推进。这里有个很容易忽略的点工具的描述和参数 schema 会直接影响模型的使用意愿。你给工具写的描述如果含糊比如“获取一些信息”模型可能根本不会调用它而如果你把描述写成“获取某目录下所有文件的修改时间列表用于判断最近变更范围”模型在合适的场景下就会主动调用。opencode 的工具注册机制本质上就是把一份 JSON Schema 喂给模型模型根据这份 schema 来决定是否调用——所以 schema 写得好不好直接决定工具被不被用。1.2 用插件写一个自定义工具内置工具覆盖了大多数场景但真正让 opencode 变成“自己的工具”的是自定义工具能力。opencode 支持通过插件系统注册新的工具写起来不复杂基本上就是定义一个 schema、实现一个处理函数。举个我实际写过的例子。当时我需要让 agent 能直接查询某个内部服务的健康状态而不是每次都去 ssh 到机器上手动 curl。于是我做了一个名为service_status的工具核心逻辑就是这样import { definePlugin } from opencode; export default definePlugin({ tools: { service_status: { description: 查询内部服务的健康状态返回 JSON 格式的状态信息, args: { serviceName: { description: 服务名称例如 user-service, type: string, required: true, }, }, async run(args) { const resp await fetch( https://internal.example.com/health/${args.serviceName} ); return await resp.text(); }, }, }, });这段代码看着简单但有一个关键点在args的description上。我给serviceName写明了“例如 user-service”模型在不确定传什么值时就会照着示例猜而不会自己编造一个不存在的服务名。这种“示例驱动”的做法在自定义工具的参数设计里非常有效能明显降低模型调用时的参数错误率。另一个经验是自定义工具尽量做成幂等的、只读优先。什么叫幂等同一个输入执行多次结果一致且不产生副作用。比如查询类工具天然幂等。但如果你的工具是“给某个服务发通知”这种有副作用的操作务必在 description 里写明“该操作会对外部系统产生实际影响”并且建议在参数里加一个dryRun预演模式选项。这样模型可以在不确定时先预演再由人工确认真正执行。我踩过的坑是工具内部做了很重的计算但没有设置超时和错误捕获。模型调用它时如果网络抖动这个调用会长时间挂起agent 整个流程就被卡住了。所以无论工具内部做什么都要记得加超时控制并返回明确的错误消息而不是让异常把整个会话搞崩。1.3 工具编排怎么让模型高效干活有了工具不等于会用工具。打个比方你给一个人锯子、锤子和尺子他知道这些都是工具但不代表他会按正确的顺序把它们组合起来盖一栋房子。opencode 的模型同样需要“工具编排”的能力而我们可以通过一些操作来引导它。我的习惯是给 agent 一个最小工作协议。比如在系统提示里约定先 grep 定位再 read 细读最后 edit 修改修改完必须跑测试。这个协议不用写很多字模型看到之后会主动按这个流程走。实际上 opencode 的 agent 模式本身就有“读代码 → 提出计划 → 修改 → 验证”的循环我们要做的是让它在修改代码这种高风险动作上慢下来、多验证几步。另一个有用的做法是让模型使用task工具进行子任务拆分。比如代码库里有三个独立的模块需要同步修改你可以在提示里告诉模型“这三个模块相互独立可以并行处理”。模型会创建多个子 agent 各自处理一个模块最后把结果汇总回来。这在处理批量重构时能大幅度缩短时间但要注意子任务之间如果存在共享文件的写冲突并行反而会出问题。所以拆分前要先判断任务之间的依赖关系。还有一个 token 成本控制的小技巧默认模型在长对话里会越来越啰嗦工具调用也会越来越频繁。我一般会在关键任务开始时提醒一句“请尽量减少不必要的工具调用优先用 grep 而非反复 read 整个文件”。模型对这类指令非常敏感能明显压低 token 消耗。尤其是代码仓库很大的时候这一步能让单次会话的花费下降百分之三四十实测下来很稳。# 查看当前使用的模型和 token 消耗 opencode models模型列表会显示当前可用模型和各自的统计信息你可以借此确认自己的提示策略有没有真的起到省 token 的效果。2. 服务面模型供给与认证管理要做对2.1 服务面到底指什么“服务面”这个词在 opencode 的语境里指的是 agent 运行时所依赖的外部服务供给层。通俗一点说模型从哪里来API key 怎么配本地模型怎么接MCP 服务怎么连这些都属于服务面的范畴。这一层之所以重要是因为 opencode 本身不生产模型推理能力它只是一个调度器和交互壳。模型的质量、稳定性、响应速度直接决定了你使用 opencode 的体验。服务面配得好你觉得 everything 都流畅配得不好再好的提示词也会被模型拖后腿。opencode 的配置中心是opencode.json或opencode.jsonc支持注释放在项目根目录下。它会自动加载项目级配置用户级配置则存放在~/.config/opencode/下。两者的覆盖关系是项目级配置会覆盖用户级配置这也符合“项目优先”的直觉。2.2 多模型配置与智能路由opencode 天然支持多模型但不是所有模型都以相同的方式接入。在服务面这一层我们要区分两类模型第一类是托管 API 模型比如海外主流大模型服务商提供的 Claude、GPT 等。只要在配置里填上对应的 provider服务商、model模型名、API key 即可。opencode 会使用模型服务商提供的在线推理接口。第二类是本地模型。比如通过 Ollama 或 LM Studio 跑的本地开源模型。本地模型的优势是数据不出内网、无额外费用但推理速度和质量通常不如大厂 API。它的配置方式也很简单把 provider 设为本地服务地址模型名填本地拉取的名字即可。我实际使用的配置大概长这样{ $schema: https://opencode.ai/schema.json, provider: { ollama: { models: { qwen2.5-coder:14b: { name: 本地代码模型 } } } }, model: { default: claude-sonnet-4-5, small: qwen2.5-coder:14b, large: claude-opus-4-1 } }model.default是主模型负责复杂推理和代码修改model.small适合快速任务比如生成 commit message、做简短问答model.large留给最困难的推理任务。opencode 会在不同场景下自动选择合适的模型这个路由能力在长会话里非常好用。关键点在于不是所有任务都需要最强的模型。你让最强的模型去生成一个 commit message纯属杀鸡用牛刀——既贵又慢。让一个 14B 的本地小模型跑这种琐碎任务又快又省钱效果也不差。这就是智能路由的实用价值。2.3 认证安全与密钥管理模型服务商都要求 API key 认证opencode 提供两种配置方式一种是把 key 写进环境变量。例如export ANTHROPIC_API_KEYsk-ant-...另一种是通过opencode auth login交互式登录它会引导你完成授权流程并把凭据存储在系统的密钥链里。我个人推荐第二种因为 key 不会出现在 shell 历史或项目文件里。但这里有一个实际操作中的坑如果你在服务器上跑 opencode没有图形界面的密钥链可用它会回退到以明文文件存储凭据。这种情况下务必确保这个文件只有你自己可读chmod 700 ~/.local/share/opencode chmod 600 ~/.local/share/opencode/auth.json顺便提醒千万不要把 API key 提交到 git 仓库哪怕是 private 仓库也别这么干。密钥一旦进入 git 历史后面想清除就非常麻烦。我在 .gitignore 里一定会加上.env和 auth 相关文件。如果你同时管理多个团队的项目每个项目要使用不同的 key我建议在项目根目录放一个.env文件并确保它不进 git。opencode 启动时会自动加载项目里的.env这样每个项目就能天然隔离 key不会出现“这个项目用的是另一个团队的 key”这种乌龙。本地模型并不需要 API key但如果你在内网部署了网关可能仍然需要自定义认证头。这属于少数场景不展开但如果你遇到了记得去看配置文档里关于headers的字段说明。MCP 服务面值得一提。opencode 支持 MCP模型上下文协议工具服务这意味着你可以把外部的工具服务以标准协议接到 agent 上来。例如接入一个内网文档检索服务、数据库查询服务agent 就能通过 MCP 工具直接访问这些内部系统不必自己拼 prompt。不过接入 MCP 服务时需要注意网络策略。不要把需要内网访问的 MCP 服务暴露到公网本地跑的服务优先用 stdio 方式联动而不是监听端口。MCP 的工具和普通内置工具对模型来说是同级别的存在只不过程序里多了一个命名空间mcp__前缀但提示词设计的原则完全一致。3. 外壳TUI 交互与终端体验3.1 界面布局与常用快捷键opencode 的外壳是一个 TUI文本用户界面它跑在终端里不需要打开浏览器。这既是优点也是门槛优点是轻量、快、适合 SSH 环境缺点是如果你不熟悉终端操作刚开始会觉得界面有点“硬核”。但实际用起来它的信息密度和操作效率是网页版聊天工具很难比的。整个界面大致分三块左侧是会话列表和状态信息右侧是对话主区域底部是输入框。工具调用的日志会以折叠块的形式显示在对话流里展开就能看到每次调用的输入和输出。常用的快捷键不多记住这几个就能正常用快捷键作用CtrlP切换会话CtrlN新建会话CtrlL清屏或者快速切换大模型CtrlE打开编辑器输入多行内容CtrlD删除当前的对话vim模式按:开头输入命令如果你觉得默认按键不顺手opencode 支持自定义 keybindings。这个配置项在opencode.json里你可以把某个操作绑定到更顺手的按键上。我个人习惯把“切换会话”改成CtrlJ/K上下方向因为 P/N 的键位在盲打时总是按错而 J/K 是 vim 用户最熟悉的方向键。还有一个很容易被忽略但极其实用的功能编辑模式。按下CtrlE之后输入框会变成一个多行编辑器你可以贴一大段代码、多行指令再统一提交。对于需要复杂提示词的场景这比在单行输入框里反复粘贴要舒服得多。3.2 主题定制与会话管理TUI 好不好看直接影响使用心情。opencode 支持自定义主题颜色、边框、高亮样式都可以调。配置里有一段theme字段比如想要一个更护眼的暗色配色可以这样写{ theme: { primary: #7c9dff, secondary: #4a7c59, danger: #c44e4e, success: #69b578, background: #1a1b26, surface: #24283b, text: #c0caf5 } }需要注意的是TUI 渲染需要终端支持真彩和 Unicode。实测下来在大多数现代终端里显示正常但如果你用的是一个比较老的终端模拟器颜色可能会变成 256 色近似显示整体视觉效果会差不少。所以如果发现颜色不对先检查终端本身是否支持而不是急着调配置文件。会话管理是另一个高频使用的功能。opencode 的每个会话都会自动保存退出 TUI 再重新打开历史消息还在。你随时可以用/sessions查看历史会话列表或通过CtrlP在不同会话之间切换。这个机制对于“同时推进多个任务”的场景特别有用会话 A 用于重构订单模块。会话 B 用于排查线上崩溃问题。会话 C 用于日常问答。三个会话互不干扰各自身份和上下文独立。我甚至会用不同的模型跑不同会话——重要任务用强模型日常问答用轻量模型。3.3 与编辑器的协作姿势很多人的直觉是opencode 到底是编辑器插件还是独立工具其实它是独立的 TUI 工具你还可以刻意让它和编辑器配合使用。最常见的协作姿势是在编辑器里看代码在 opencode 里发指令。比如你在编辑器里定位到一个 bug切到 opencode 说“修一下某个函数相关文件在 src/utils/xxx.ts”它读文件、改代码你再切回编辑器看 diff。这种切换在单显示器下很流畅。第二个姿势是选中即问。某些编辑器支持把选中内容通过快捷键发送到外部命令你可以把选中的代码段管道给 opencode 让它做解释或 review。例如在终端里selected_code | opencode run 帮我解释这段代码的逻辑opencode run是非交互模式后面直接跟任务描述stdin 的内容会作为上下文输入。这个命令在写脚本时非常有用。第三个姿势是彻底反过来让 opencode 作为“大脑”你在编辑器里做执行。这种情况常见于模型对代码库不熟时你帮它把文件内容复制进对话它给方案你手动改。虽然听起来原始但在高度机密的环境里不允许 AI 服务接触源码这是唯一合规的用法。4. 实战集成把 opencode 嵌进日常工作流4.1 非交互模式跑自动化任务前面提到的opencode run是自动化集成的入口。它的存在意味着 opencode 不只是交互工具还能作为命令行工具被脚本调用。最典型的场景是批量代码迁移。假设项目里有几十处老接口调用要改成新接口手动改要一两个小时。你写一个简单的循环脚本for file in $(find src -name *.ts | head -20); do opencode run \ --agent 修改旧接口调用 \ 读取 $file把其中调用旧接口的地方全部替换为新接口写法保持其他逻辑不变 done这种方式虽然简单粗暴但非常有效。每个文件单独跑一个任务互不干扰失败了也不影响其他文件。配合 Git 可以逐文件 review diff安全性比让 agent 一次性改几十个文件要高很多。第二个场景是自动生成提交信息。在 Git 的prepare-commit-msghook 里调用 opencode让它根据 diff 生成提交信息可以省掉大量写 commit message 的时间。我试过几次之后发现它生成的标题不一定比你手写的好但它会覆盖到所有变更点不会像人一样漏掉某个文件。注意在 hook 里要限制模型复杂度用轻量模型就够了太重会拖慢每个 commit。第三个场景是定时巡检任务。用 crontab 或系统定时器每天跑一次 opencode 检查代码里的 security 风险标记生成一份报告发到团队群。这种任务用交互 TUI 反而麻烦opencode run加输出重定向就能搞定opencode run 审查代码库中的硬编码密钥和危险函数调用输出简洁报告 report.md4.2 CI 里的代码审查与批量任务在 CI 流程里集成 opencode 是进阶玩法。主流的 CI 系统都支持在 runner 上执行命令opencode 只要配置好 API key就能作为一个“AI 审查员”跑在流水线里。我做过一个简单的 PR 审查 job核心步骤是checkout 代码。找到 PR 的 diff。把 diff 发给 opencode让它重点检查潜在 bug、安全隐患、与代码库风格不一致之处。将结果作为 PR 评论。这一步并不复杂但在一个中等规模的团队里它能顶上一个初级 reviewer 的工作量。AI review 的最大价值不是发现复杂问题而是永不疲劳地检查低级问题——比如 forgot to handle error、硬编码了密钥、某个边界条件没判断。人类 reviewer 容易事后疲劳AI 不会。当然AI 审查不能替代人工 review。它更像“第一道防线”把明显的低级问题过滤掉之后人工 reviewer 才有精力集中在架构和语义层面的问题上。批量任务则更简单。比如在发布周期里需要生成 changelog、跑一遍废弃 API 扫描、统一格式、批量补充注释……这些都是opencode run的舒适区。把它们写成 Makefile 或 npm script{ scripts: { ai:changelog: opencode run 根据最近提交历史生成 changelog只输出 markdown, ai:review: opencode run 审查当前改动输出问题列表, ai:format: opencode run 统一代码风格不要改变逻辑只做格式化 } }4.3 团队共享环境下的权限隔离团队里共用一台开发服务器是 opencode 使用中最容易出现“事故”的场景。你想啊多人共用同一个账号、同一套环境变量一个 agent 误操作执行了rm -rf后果有多严重所以权限隔离必须做。首要原则每个团队成员的会话要隔离。如果你用 tmux 共享会话那你和同事是在同一个 TTY 里操作同一个 agent——它的每一步操作你们都能看到但你也会在没有知觉的情况下被同事的操作干扰。更安全的方式是每个人在自己的 SSH 会话里跑 opencode配置文件互相不交叉密钥各自管理。其次要利用好 opencode 本身的权限确认机制。opencode 对某些危险操作如写文件、执行 bash 命令可以设置为“每次都要人工确认”。这在交互模式下很有用偶尔会打断你但值得。不过在自动化模式opencode run下没有人工确认环节所以脚本里使用的 prompt 要格外小心——尽量限定 agent 的工作目录和可操作范围。我的做法是给危险操作单独准备一个“沙箱目录”让 agent 只能在这个目录里自由发挥生产环境的代码只允许“生成 diff”而不允许直接修改。这个约束写在系统提示词里虽然不能百分之百保证模型遵守但实测下来模型对这类指令的遵守度相当高。MCP 服务接入也要按权限隔离。团队成员各自的 MCP 服务配置文件独立不能把所有内部服务暴露给所有成员。比如数据库查询 MCP只给需要用到的同事用。4.4 一次重构任务完整走一遍最后放一个完整的工作流实例让大家看看前面提到的能力是怎么串起来的。场景某后端项目需要一个模块的调用链路从“旧接口 A”切换到“新接口 B”。涉及约 30 个文件接口签名有差异需要做参数映射。手动改大概需要半天我们拿 opencode 来跑。第一步建立对话范围。在项目根目录启动 opencode新建会话告诉它我们正在把支付模块的老接口替换为新接口。代码库在 src/payment 目录下。 目标是让所有调用老接口的地方都切换为新接口保持行为不变。 请先分析影响范围列出所有需要改的文件再分步修改。 先不要改任何文件先给我清单。这一步很关键先让 agent 出一份“影响清单”而不是立刻动手。清单出来之后人工 review 一遍确认范围没有遗漏。第二步分模块执行。确认清单后让 agent 逐个文件修改。每改完一个文件要求它展示 diff并在最后统一跑编译和测试。这个阶段我建议开两个会话一个会话负责“读代码 → 改代码”另一个会话专门负责“看 diff → 做 review”。分开能避免上下文被 diff 刷屏导致模型注意力分散。第三步验证与回溯。全部改完之后跑一遍全量测试把报错丢回给 agent 修复。这个循环可能要重复两三轮。实测下来接口签名变化这类机械性工作agent 的完成质量相当稳定90% 以上的文件一次改对剩余的靠测试反馈修正。整个过程算下来从开始到全部通过测试大约耗时 40 分钟。其中大部分时间花在人的 review 和测试等待上纯 agent 干活的时间不到 10 分钟。对比手动改半天时间体感收益非常明显。5. 常见问题与排查技巧实录5.1 工具调用异常的排查思路模型没有调用应该调用的工具。这个问题的根源通常是工具描述不清或者系统提示词里没有明确触发条件。排查方法是打开 TUI 的工具调用日志看模型在哪个环节放弃了调用然后针对性修改工具的 description。记住模型是基于描述做决策的描述越具体调用越准确。工具参数校验失败。比如你给一个工具传了不存在的枚举值。我的经验是在 schema 里尽量用enum字段约束可选值而不是让模型自由发挥。比如状态字段明确列出pending / running / done / failed四种模型就几乎不会传别的值。另外在description里给出示例值也能显著降低传参错误。工具执行超时或长时间无响应。多数情况是工具内部做同步阻塞操作比如请求外部服务但没有设置超时。排查步骤先确认工具内部是否设置超时再把工具内部错误捕获后的信息原样返回给模型让它根据错误决定下一步。不要在工具函数里吞掉异常后返回空字符串——模型拿到空结果会一头雾水。5.2 服务面连接与限流问题401 认证失败。优先检查两点一是环境变量是否正确加载在 TUI 里执行/env查看当前环境变量确认 key 存在二是 key 是否过期或被吊销去服务商后台确认。如果用了多种认证方式要确认优先级有些配置里环境变量和配置文件同时存在时可能环境变量覆盖了配置文件的 key导致 key 不符。429 限流。这是服务面最头疼的问题。模型服务商对并发请求和每分钟调用数都有限制。如果你在自动化脚本里批量跑opencode run非常容易触发限流。解决办法在循环脚本里加sleep或者指数退避重试。也可以把并发数压到 1一次只跑一个任务。实测下来串行跑比并行跑慢不了多少但触发限流的概率能降低一个量级。本地模型连不上。Ollama 起没起、模型名写没写对这两个问题占九成。先用ollama list确认模型存在再把 opencode 配置里的模型名改成完全一致的名字。另一个坑是端口号Ollama 默认 11434LM Studio 默认 1234两者默认端口不同配置地址要写对。MCP 服务连不上。优先用 stdio 方式调式。如果你配置了一个 sse 方式的远程服务先确认网络策略允许内网访问然后看 opencode 日志里有没有握手失败的记录。MCP 的问题通常不是协议本身的问题而是地址、认证头、网络三层配置的问题。5.3 TUI 显示错乱与终端兼容界面布局乱掉。多半是终端宽度不够或者终端窗口大小变化后 TUI 没有正确重绘。按一下CtrlL强制刷新通常能解决。如果频繁发生换一个支持 TUI 更成熟的终端模拟器。颜色显示不对。优先判断终端是否支持真彩。在终端里跑一下颜色测试如果没有平滑渐变而是出现色块说明终端只支持 256 色。opencode 的主题在 256 色下也能显示但部分配色会偏移。想要最好的显示效果请使用支持真彩的终端渲染方案。中文输入和显示问题。TUI 对中文字符的双倍宽度支持依赖终端和字体如果在某些终端里中文对不齐试试点阵字体或换字体。这个属于终端自身问题不是 opencode 的 bug。终端卡顿。当工具调用日志特别多时TUI 渲染压力会增加。我会在配置里关掉一些低价值的日志类型只保留命令执行结果和错误提示。日志太多时模型上下文也会膨胀影响后续推理质量适当过滤日志既省资源又省 token。5.4 权限误操作与安全兜底agent 执行了不该执行的命令。最有效的兜底是“先确认再执行”机制。opencode 的权限系统可以按命令前缀配置让特定命令必须经过确认才能执行。比如/permission deny rm -rf或/permission ask git push。你还可以把权限规则写在项目配置里团队共享这些规则。agent 改坏了文件。每次修改前确认在 Git 环境里工作这样任何一步都能回滚。我的习惯是任何让 agent “修改代码”的会话开始前先手动提交一次当前工作区或者确保没有未提交的重要改动。这样 agent 改坏了一条git checkout .就能恢复。敏感数据泄露风险。如果你把内部代码发给云端模型数据会离开你的网络边界。对于敏感项目要么用本地模型要么只把非敏感信息的摘要发给云端模型。我见过有人直接把包含数据库连接串的.env内容贴进对话后来只能紧急轮换所有密钥。这个教训值得反复强调prompt 里不要出现密钥如果必须处理密钥用变量占位符替代后再给模型看。我自己的安全底线其实总结起来就三条第一生产环境代码改之前必先存 Git 快照第二危险命令必须经过人工确认第三密钥永远不出现在对话和日志里。这三条严格执行opencode 用了很久没有出现过一次事故。最后分享一个体会opencode 这类工具你最需要投入时间的不是背命令而是理解它的“分工哲学”——模型负责推理和决策工具负责执行外壳负责交互服务面负责供给。四者各司其职你只需要在正确的位置放上正确的配置和约束。上篇讲的是怎么让它跑起来这篇讲的是怎么让它真正成为你工具箱里的一环。如果你能把自定义工具和服务面摸透再装上几个顺手的外部服务它就不再是一个“聊天玩具”而是能实实在在替你在代码库和系统之间来回跑腿的干将。