
1. 为什么做羲和从能聊天到能干活的跨越做开发工具这些年我越来越清楚一件事AI 编码助手如果只能聊天价值就折掉了一半。市面上的 AI 编程助手从最早基于代码补全的模型到现在能理解整个仓库上下文的对话式产品能力确实在快速进化。但真用起来你会发现一个尴尬的点——它把代码写得再漂亮最后落地执行的还是你。复制代码、打开终端、跑测试、修报错、再提交这一整条流水线 AI 全程围观却插不上手。羲和XiheAgent想解决的就是这个断层。它的定位不是又一个AI 问答盒子而是把代码问答和任务执行打通的一条完整链路。你问它这个调度任务为什么一直失败它不仅能定位到问题代码还能在你授权后直接把补丁提交到调度平台、触发一次重跑、帮你确认执行结果。从给答案到把事办成这是羲和与普通对话式编码助手最本质的区别。这个项目适合谁如果你维护着多套服务每天要处理大量重复的查代码、改配置、调任务、看告警这类体力活羲和的模式会非常对胃口。如果你只是想要一个能聊代码的 Copilot现有工具已经够用没必要搭一整条执行链路。做这个项目的核心判断是AI 的判断能力只有和工程体系的执行能力对接起来它才能从一个参谋变成队伍里能干活的成员。2. 整体设计三层架构与关键取舍2.1 功能层自然语言入口与意图路由羲和的用户入口就是一个对话框但后端的第一步并不是直接把问题丢给大模型而是先做意图路由。我把它分成三类问答类解释一下这个函数的逻辑、任务类调度平台里 id 为 1024 的任务今天为什么失败了、操作类把修复后的脚本重新提交并触发执行。这三类对系统的能力要求完全不同。问答类只需要检索代码、组织答案不触碰任何外部系统任务类需要拉取调度平台的执行日志、结合代码上下文做根因分析操作类最重需要把自然语言转成具体的 API 调用并且经过用户确认后才真正执行。把这三类混在一个 Prompt 里让模型自己猜很容易出现答非所问、越权操作的情况。所以我在前端就做了一个轻量级分类器用少量标注数据训练了两层意图判断先判断是否涉及执行再判断涉及哪个目标系统。2.2 解析层代码理解与任务拆解确定意图后解析层负责把用户的自然语言和系统状态对齐。比如用户说上次那个任务又挂了这个上次和又挂了必须被解析成具体的对象哪个工作流哪个任务实例失败原因是什么这需要三个信息源的配合。代码索引对仓库做 tree-sitter 语法解析和 embedding 向量化建立文件—函数—调用关系的索引支撑代码检索和影响面分析。状态快照实时拉取 DolphinScheduler 的工作流定义、实例状态、日志摘要让模型能基于真实运行数据回答问题而不是凭空猜测。历史上下文保留同一个会话窗口内的对话记忆用户说上次那个时能关联到之前讨论过的具体任务。任务拆解部分我踩过的坑是一开始让模型直接输出调用某个 API的完整参数结果经常出现参数幻觉比如把 processDefinitionId 和 projectId 搞混。后来改成两步走——模型先输出结构化的操作意图 JSON再由代码层把 JSON 映射到真实的 API 调用参数这样即使模型猜错了 ID代码层也能通过名称匹配做二次校验纠偏。2.3 执行层沙箱、调度器与消息通道执行层是整个系统风险最高、也最需要做防护的部分。我的设计是三段隔离代码执行沙箱任何由 AI 生成或修改的脚本不会直接跑在宿主机上。我用了容器方案每次执行拉起一个临时容器挂载只读的代码目录网络默认隔离执行完销毁。调度器桥接服务与 DolphinScheduler 的交互单独做成一个后端服务封装创建、更新、发布、触发、查询状态等操作提供一套带 token 鉴权的 HTTP 接口给羲和调用。消息通道企微告警、站内通知都走统一的消息服务保证任务失败、执行成功这类关键事件能及时触达相关人。这层设计最重要的原则是执行链路必须有人参与确认的环节。涉及数据变更、任务发布这类操作羲和会先把完整的执行计划列出来改了什么、调用什么接口、影响哪些任务等用户点击确认后才真正发出请求。宁可多一步确认也不能让 AI 在无人监管的状态下动生产环境。3. 代码问答能力不只是能聊还要聊得准3.1 代码索引的搭建与坑代码问答的质量很大程度上取决于检索能力而不是模型能力。我一开始图省事把整个仓库的文件全塞进上下文指望长上下文模型自己找答案。结果仓库稍微大一点Token 消耗爆炸而且关键信息容易被淹没在无关代码里。后来改成索引优先的方案用 tree-sitter 解析出每个文件的函数、类、导入关系再对函数体的摘要做向量化查询时先搜出 Top 5 相关函数连同它们的调用链一起交给模型。这个方案里有一个很关键的细节——索引要与实际执行任务联动。比如用户问某个调度任务为什么失败系统不是直接搜全仓库而是先通过 DolphinScheduler 拿到该任务对应的脚本路径再只对这个脚本及其依赖文件做检索分析。范围一缩小准确率提升非常明显。实测下来定位问题的准确率从大约六成提高到接近九成。检索的质量依赖分块策略。太粗的块整个文件会混入大量无关信息太细的块单行又丢失上下文。我最后用的是函数级分块 按调用链拼接每个块是一个函数的完整实现检索时把被测函数的前后调用者一起打包给模型。这样模型既能看懂某个函数在做什么也能理解它在整个调用路径里的位置。3.2 代码问答里的上下文管理技巧模型上下文窗口虽然一直在变大但塞得下不代表效果好。代码问答场景里我总结出三条上下文纪律先结论后推理Prompt 结构上要求模型先输出结论比如失败原因大概率是数据库连接池耗尽再给出推理过程。因为工程人员在使用时第一眼需要的是判断方向细节可以慢慢看。日志优先级高于代码排查任务失败问题时执行日志往往比代码本身更有价值。我在系统里做了一个日志预处理模块自动对海量日志做摘要提取只保留异常栈、关键错误码、耗时统计再把这部分压缩后的信息连同相关代码一起交给模型。会话内的多轮改写用户后续追问那该怎么改模型需要结合前面提到的任务和日志来回答。我维护了一个会话状态表每一轮都重新拼接当前目标 关键上下文摘要 最新问题而不是把全部历史消息一股脑丢进去。4. 任务执行核心链路对接 DolphinScheduler 的实践4.1 为什么选 DolphinScheduler 作为执行底座做任务执行这一步面临一个选型问题自己写调度器还是接入现成的调度平台。我的选择是直接对接 DolphinScheduler原因有三点。第一它的 REST API 覆盖了从项目管理、工作流定义到任务实例查询的完整链路省去了自己造轮子的成本第二它天然支持 Shell、SQL、Python、HTTP 等多种任务类型正好满足 AI 生成产物多样化的执行需求第三社区活跃、文档齐全遇到调度 bug 时能找到现成的解决方案。当然接入 DolphinScheduler 不是没有代价。它本身的部署和维护就有一定复杂度依赖数据库、ZK 等组件API 版本间也有一些兼容性问题。我的经验是把桥接服务做成独立模块把 DolphinScheduler 的 API 调用全部收敛在这一层避免上游业务代码被调度平台的细节污染。4.2 任务提交与状态同步的核心链路羲和触发一个任务执行的完整链路如下用户确认执行计划 → 羲和执行服务 → DS Bridge 服务 → DolphinScheduler REST API → 创建工作流/更新流程定义 → 发布上线 → 启动工作流实例 → 轮询实例状态 → 状态入库 → 按结果决定下一步告警/通知/继续操作这一步里最容易出问题的地方在于 DolphinScheduler 的版本概念。它的流程定义更新后必须显式执行发布操作新版本才会生效。我第一版对接时漏了这一步结果出现一个很隐蔽的 bug代码更新成功了但实际跑的还是旧版本脚本。后来在桥接服务里加了一个强制流程——创建或更新流程定义后立刻调用 release 接口并且校验返回结果中的版本号与预期一致才彻底解决这个问题。任务实例的状态同步我做过一版短轮询方案每 10 秒查一次实例状态直到终态。但调度任务里有很多长耗时任务跑数、训练等短轮询既浪费请求又容易触发 API 限流。现在改成两段式前端先等 30 秒用 DolphinScheduler 的查询接口拿一次状态如果还在运行中就转成后台异步监听通过企微 webhook 回调通知最终结果。这样既保证了实时性又不会一直占着连接。4.3 执行产物的校验与回滚机制AI 执行任务最怕一个问题跑是跑起来了但结果不对。我加了三个校验环节。第一语法级校验AI 生成的 Shell/SQL 脚本在提交给调度平台前先做静态检查Shell 用bash -nSQL 用 Explain 模式预执行避免把明显有语法问题的脚本发到生产调度平台。第二Mock 预演对有时间窗口的任务先在测试库里跑一遍逻辑确认核心指标正常后再正式触发。第三版本留痕每次任务执行前自动记录当前脚本的 MD5执行结果异常时能快速对比到底是代码变了还是环境变了。回滚机制上我依托 DolphinScheduler 的流程定义版本管理做了一个一键回退接口。当 AI 修改后的脚本在生产环境跑挂时桥接服务能自动拉取上一个正常版本并重新发布。实测中这个功能拯救了不止一次线上事故值得专门做成一个独立能力。5. 失败告警任务挂了怎么让人第一时间知道5.1 企业微信告警通道的搭建调度任务不可能永远成功告警能力是整套执行链路的安全网。我选择企业微信机器人作为主要告警通道原因是它接入成本低、触达率高——团队里大家本来就在企微上消息不容易被漏掉。企微机器人的 webhook 接口调用很简单但对消息格式有要求。我封装了一个微信推送服务支持文本和 Markdown 两种消息类型。文本消息适合简单的任务失败通知Markdown 消息适合带详细上下文的告警卡片。企微 webhook 发送时有个隐藏限制频繁调用会触发频控一般限制是每个机器人每分钟最多 20 条消息。我在这层加了本地队列做削峰把突发的大量告警合并成一条汇总消息发出去避免封禁。5.2 告警模板与信息分级告警不是把错误信息原样丢出来就完事。我设计了三个级别的告警模板P0 级立即通知关键生产任务连续失败超过阈值推送 Markdown 格式的完整告警卡片包含失败时间、任务 ID、错误摘要、触发人、建议处理方向。P1 级汇总通知批量任务中有部分失败每 15 分钟汇总一条列出失败任务清单和占比避免告警轰炸。P2 级静默处理非核心任务失败只记录日志并在日报中体现不打扰人。告警内容里我特别加了一个AI 诊断意见字段。这个字段由羲和在检测到失败事件后主动拉取执行日志和代码变更记录生成一句话判断比如疑似最近一次脚本修改引入了空指针建议回滚到上一版本。这个能力在实战中很受团队欢迎——告警不只是通知你出事了还顺带告诉你大概哪里出事了。5.3 告警防抖与升级机制告警太多会让人麻木太少又怕漏掉关键事件。我实现了一个简单的防抖器同一任务同一类型的失败在 30 分钟内只发送一条告警后续状态变化比如恢复成功会再补一条恢复通知。这样既不会轰炸又能让团队了解到事态的全过程。升级机制也是必要的。当 P0 告警发出后 10 分钟内任务仍未恢复并且没有人在企微群里点击我接手处理系统会自动升级通知到值班负责人并附带完整的失败链路时间线。这个机制本质上是在AI 自主执行和人肉兜底之间做了一个平衡——AI 可以尝试自动修复但人有权利也有渠道随时接管不能让机器在故障场景下完全失控。6. 落地过程中的常见问题与排查实录6.1 任务状态不一致AI 以为成功了实际上失败了这是我在使用中遇到的最头疼的问题。AI 通过 API 查询 DolphinScheduler 任务实例状态时有时会拿到SUCCESS的状态但实际任务是失败的。查下来原因是DolphinScheduler 的流程实例状态是最终态但内部单个任务节点可能有 FAILED 却被后续的重试逻辑覆盖或者流程虽然标记为成功但某些分支节点被跳过没有真正执行。我的解决办法是状态判断不能只依赖流程实例的 summary 状态必须去查询实例下每个任务节点的明细状态任何一个关键节点是 FAILED 就算整体失败。同时在中枢服务里维护一张任务执行状态表以自己实时记录的状态为准DolphinScheduler 的返回只作为辅助参考。这样即使调度平台因为各种原因返回了误导性状态告警逻辑也能基于真实记录做出正确触发。6.2 Token 超限与上下文污染任务执行失败后拉取日志做分析时很容易把一条几 MB 的日志全塞给模型直接触发 Token 超限。更隐蔽的问题是大量重复运行日志会污染模型的判断——模型看到的是几十次一模一样的INFO日志真正的异常信息反而被淹没了。后来我加了一个日志摘要层对原始日志做行级分类INFO/WARN/ERROR/异常栈只保留 ERROR 和异常栈前后各 20 行再对重复内容做去重和合并。这样一个几 MB 的日志文件通常能压缩到 1000 字以内既省钱又提高了分析准确率。另一个技巧是给模型显式说明这是压缩后的日志摘要不是完整日志缺失上下文可能影响判断这能显著减少模型基于不完整信息做出错误推断的概率。6.3 权限与安全的边界控制AI 能执行任务后权限边界就变成了首要问题。我踩过的一个教训是桥接服务刚开始用的 token 具有全部项目管理权限某次 AI 在上下文驱动下把另一个业务线的调度任务也顺手更新了。虽然因为流程里有人工确认环节没有造成实际损失但这暴露了权限粒度太粗的问题。现在的方案是羲和系统对接企业内部的单点登录用户在对话框里触发执行操作时羲和会校验该用户对目标项目的操作权限只有同时满足用户有权限 桥接服务 token 有权限才放行。审计日志也会完整记录每次操作的用户、时间、指令、API 调用和返回结果作为事后追溯的依据。从实际经验看权限控制不是一个技术问题而是一个组织问题——你需要在系统设计之初就和生产运维团队确认清楚哪些操作允许自动化、哪些必须留给人来做。6.4 DolphinScheduler 的高可用与 API 限流调度平台本身的稳定性会直接拖垮整个自动化链路。DolphinScheduler 的 API 有并发连接数限制大量任务同时触发时会出现连接超时和数据拉取失败。我的方案是在桥接服务里做两层保护一个简单的信号量控制并发请求数最高 20 个并发另一个是请求级重试机制——对 5xx 和超时错误做三次指数退避重试对 4xx 错误直接丢弃不重试。还有一个取巧的做法是高频状态查询不直接打到 DolphinScheduler而是缓存到 Redis由桥接服务自己维护一个调度事件表只在任务状态发生跳变时触发后续动作。这极大地降低了对调度平台的请求压力。目前这套机制已经跑了几个月DolphinScheduler 侧没有再出现过因查询压力导致的服务不可用。7. 后续演进方向与个人体会羲和目前已经稳定承担了团队日常的代码问答、故障排查和任务调度辅助工作。我个人体会最深的一点是开发一个 AI 编码助手技术难点从来不在模型本身而在于你愿不愿意花精力把所有周边系统代码仓库、调度平台、消息通道、权限体系打磨得足够规整。AI 的能力边界很大程度由它所接触的系统边界决定——只给它一个对话框它就只是一个聊天机器人给它接上整个工程体系它才真正成为团队的一员。后续我打算做两个方向的扩展。一是增加更多执行入口比如支持通过语音触发告警确认操作在移动端就能完成紧急故障的处理闭环二是把 AI 的执行经验沉淀成可复用的知识库——每次修复成功的案例都自动生成故障报告和修复模板让下一次类似问题时羲和能直接给出经过验证的解决方案而不是每次都从零开始推理。如果你也在做类似的方向我的建议是先把最小闭环跑通不要一上来就想做一个综合大系统。从让 AI 能查询任务状态这样一个小能力开始逐步扩展到修改、执行、告警每加一个能力都要确保可回滚、可审计、可人工干预。自动化是手段可靠才是目标这条原则值得贯穿整个项目的生命周期。