基于官方CLI的AI编程助手聚合平台ductor:本地化消息驱动工作流实践
1. 项目概述一个基于官方CLI的AI编程助手聚合平台如果你和我一样日常开发中需要在Claude Code、OpenAI Codex和Google Gemini这几个强大的AI编程助手之间频繁切换同时又在Telegram或Matrix上花费大量时间沟通那么你很可能也幻想过这样一个场景能不能直接在聊天软件里像跟同事对话一样无缝地指挥这些AI助手帮你写代码、分析问题甚至管理复杂的自动化任务今天要聊的ductor就是把这个幻想变成现实的工具。它不是另一个需要你申请API密钥、配置复杂SDK的第三方服务而是一个运行在你本地机器上的“指挥官”核心哲学极其简单直接调用你已经安装好的官方CLI命令行工具通过模块化的消息传输层目前支持Telegram和Matrix让你在熟悉的聊天环境中获得一个功能强大、可扩展的AI编程工作流。ductor最吸引我的地方在于它的“无侵入性”和“本地优先”原则。它不修改、不代理、不伪装任何官方客户端。你的claude、codex、gemini命令怎么在终端里用在ductor里就怎么被调用。所有的会话状态、记忆、文件都老老实实地存放在你本地~/.ductor/目录下的纯文本文件JSON和Markdown里。这意味着你可以放心使用你的Claude Max等高级订阅所有数据流转完全可控没有中间服务器也没有额外的服务条款风险。对于注重隐私和合规的开发者来说这几乎是目前最理想的集成方案。2. 核心架构与设计哲学为什么选择“CLI 消息总线”在深入实操之前有必要拆解一下ductor的设计思路。市面上已经有不少将AI集成到聊天工具的项目但ductor选择了一条看似“笨拙”实则精妙的路径它将自己定位为一个“消息路由与进程管理”层而非一个“AI服务提供商”。2.1 官方CLI作为唯一执行后端ductor严格限定只与Anthropic、OpenAI、Google官方发布的命令行工具交互。当你发送一条消息“帮我重构这个函数”时ductor的流程是这样的消息接收Telegram或Matrix的机器人模块收到你的消息。会话路由根据消息来源私聊、群组话题、命名会话确定对应的会话上下文。命令构造将你的消息文本连同当前会话的历史上下文从本地Markdown记忆文件读取以及预定义的规则文件如CLAUDE.md拼接成符合对应CLI工具语法的完整提示。子进程执行启动一个子进程运行claude或codex、gemini命令并将构造好的提示通过标准输入stdin传递给它。流式回传实时捕获CLI的标准输出stdout通过消息传输层如Telegram的“编辑消息”功能流式地传回给你的聊天窗口。这个设计的优势非常明显零合规风险你使用的是完全官方的客户端所有使用条款、速率限制、计费方式都与你手动在终端使用一模一样。稳定性继承CLI工具的更新、功能变更由官方维护ductor只需保持命令调用的兼容性核心AI能力始终是最新且稳定的。技能无缝迁移如果你已经在~/.claude/等目录下配置了自定义技能skillsductor可以直接利用因为它在调用CLI时会继承这些环境配置。2.2 模块化与传输无关的核心ductor的另一个精妙之处在于其清晰的架构分层。它的核心Orchestrator完全不知道消息来自Telegram还是Matrix。它只处理抽象的“会话”、“请求”、“响应”对象。每个消息传输实现如messenger/telegram/,messenger/matrix/都是一个独立的模块只需实现一套标准的BotProtocol接口。这意味着功能一致性所有在Telegram上能用的功能如/model切换、命名会话、后台任务在Matrix上也能以对应平台的最佳交互方式实现。易于扩展未来要支持Discord、Slack甚至自定义的WebSocket接口只需要为新平台编写一个实现了BotProtocol的模块即可核心的会话管理、记忆系统、任务调度等逻辑完全复用。并行运行你甚至可以配置一个agent同时监听Telegram和Matrix用同一个AI大脑处理来自不同社交圈子的请求。这种设计让ductor从一个“Telegram上的AI机器人”进化成了一个“以消息为界面的通用AI工作流平台”。3. 从零开始环境准备与初始化部署理论说得再多不如动手跑起来。下面是我从零部署一个ductor实例的完整过程包含了所有你可能遇到的坑和对应的填坑技巧。3.1 前置条件检查ductor对运行环境的要求比较明确在开始前请确保满足以下条件Python 3.11这是硬性要求因为项目使用了match语句等新特性。用python --version检查。至少一个AI CLI工具你必须至少安装并配置好claude、codex、gemini中的一个且能在终端直接运行。这是ductor的“发动机”。消息平台凭证Telegram需要一个Bot Token从 BotFather 创建即可。Matrix需要一个账户用户ID、密码或访问令牌及对应的Homeserver地址。注意强烈建议使用pipx或uv来安装ductor这能有效避免Python环境冲突。我个人偏好uv因为它速度极快并且是ductor官方推荐的工具。3.2 一步到位的安装与初始化安装过程非常简单真正的配置在于随后的交互式向导。# 使用uv安装推荐 uv tool install ductor # 或者使用pipx pipx install ductor # 安装完成后直接运行 ductor第一次运行ductor命令时它会自动启动一个交互式配置向导。这个向导设计得非常人性化会一步步引导你完成所有必要配置。以下是向导的核心步骤和我当时的配置选择CLI检测向导会自动检测系统中已安装的AI CLI。我安装了claude和gemini它都成功识别了。选择传输层我选择了telegram作为主要传输方式。如果你需要Matrix可以后续通过ductor install matrix安装额外依赖并在配置中启用。输入Telegram Bot Token将从BotFather获得的Token粘贴进去。配置用户白名单这是安全关键步骤你需要输入你自己的Telegram User ID。你可以通过给 userinfobot 发送/start来快速获取。务必只添加你信任的用户ID因为私聊完全依赖此白名单。时区设置向导会自动检测系统时区用于定时任务Cron调度。我确认了Asia/Shanghai。Docker沙箱可选向导会询问是否启用Docker沙箱。这是一个安全特性可以将AI CLI的执行环境隔离在一个容器中。对于初期体验我选择了否以简化调试。后续可以通过ductor docker enable随时开启。后台服务安装可选向导建议安装为系统服务Linux的systemd, macOS的launchd, Windows的Task Scheduler这样ductor可以开机自启、在后台稳定运行。我选择了是。向导结束后ductor会尝试启动并连接到Telegram。如果一切顺利你会在Telegram上收到一条来自你机器人的欢迎消息。至此最基本的单聊模式就配置完成了。3.3 关键目录结构解析安装完成后你的~/.ductor/目录会生成如下结构。理解这个结构对后续的故障排查和高级配置至关重要。~/.ductor/ ├── config/ │ └── config.json # 核心配置文件所有设置都在这里 ├── sessions.json # 所有聊天会话的实时状态 ├── named_sessions.json # 所有命名会话的元数据 ├── tasks.json # 后台任务注册表 ├── cron_jobs.json # 定时任务定义 ├── webhooks.json # Webhook定义用于外部触发 ├── agents.json # 子Agent注册表多Agent时使用 ├── SHAREDMEMORY.md # 所有Agent共享的全局记忆 ├── CLAUDE.md # Claude CLI的规则文件可自定义 ├── AGENTS.md # 定义Agent行为的规则文件 ├── GEMINI.md # Gemini CLI的规则文件 ├── logs/ │ └── agent.log # 运行日志排查问题的第一站 └── workspace/ # 工作区所有生成物和记忆存放于此 ├── memory_system/ │ └── MAINMEMORY.md # 主Agent的持久化记忆文件 ├── cron_tasks/ # 定时任务脚本目录 ├── skills/ # 共享技能目录 ├── tools/ # 工具脚本目录 ├── tasks/ # 每个后台任务独立的文件夹 ├── telegram_files/ # 从Telegram接收的媒体文件 ├── api_files/ # WebSocket API相关文件 └── output_to_user/ # 准备发送给用户的生成文件如图表、代码实操心得config.json和agent.log是你最好的朋友。任何异常行为首先查看日志任何功能调整首先编辑配置文件。ductor支持配置热重载修改config.json后通常几秒内生效无需重启。4. 核心功能深度实操五种交互模式全解析ductor提供了五种层次分明的交互模式从简单的单聊到复杂多Agent协作适应不同场景。我们逐一拆解。4.1 模式一单聊你的主驾驶舱这是最基础的用法。你和你的ductor机器人建立一个私聊1:1。所有发送给它的消息都会路由到你配置的默认AI CLI比如Claude Code回复会实时流式传回。典型对话流你 帮我写一个Python函数用递归计算斐波那契数列。 Bot: [思考中...] 当然这是一个使用递归计算斐波那契数列的Python函数包含了对性能的简单说明... 消息以流式方式逐渐显示完整代码和解释 你 /model Bot: [弹出内联键盘] 请选择AI提供商 Claude | Codex | Gemini 你点击“Gemini” 你 用Go语言重写这个函数。 Bot: [思考中...] 这是用Go语言实现的递归斐波那契函数需要注意Go的整数类型...关键特性流式响应在Telegram上消息会像打字一样逐渐出现并更新体验流畅。无缝切换模型/model命令可以随时切换AI提供商即使上一个请求还在处理中切换也不会被阻塞。新请求会自动使用新选择的模型。持久化上下文对话历史会自动保存到MAINMEMORY.md下次同会话聊天时AI能记住之前的对话。4.2 模式二群组与话题项目隔离的利器这是ductor组织能力的核心体现。你可以在一个Telegram群组需开启“话题”功能即论坛模式或不同的Matrix房间里创建多个完全隔离的对话上下文。Telegram群组设置步骤创建一个新群组。进入群组设置 - 打开“话题”功能Turn on topics。将你的ductor机器人添加到群组并务必将其设为管理员。这是为了绕过Telegram Bot API的“隐私模式”让机器人能读取所有非命令消息。在群组里随意发送一条消息并提及你的机器人。此时ductor会发现这个新群组不在白名单allowed_group_ids中它会拒绝响应并可能自动退出。这是安全机制。回到与机器人的私聊窗口输入/where命令。你会看到这个群组被列在“Rejected”部分并显示其唯一的group_id一个负数。直接告诉机器人“将group_id-100xxxxxxx添加到允许的群组列表中。” 机器人会理解你的意图并自动修改config.json文件将该ID加入allowed_group_ids数组。输入/restart命令重启ductor。重启后机器人就能在该群组正常工作了。效果 现在这个开启了话题的群组每一个话题都是一个独立的会话。你在“General”话题里讨论架构设计在“Auth”话题里调试登录逻辑在“Frontend”话题里审查CSS代码——它们之间的上下文完全不会互相干扰。你甚至可以在不同话题中使用不同的AI模型通过在各话题内使用/model命令切换。重要提示Telegram Bot API无法主动获取已存在的话题列表。因此对于在添加机器人之前就创建好的话题ductor初次见到时会将其显示为“Topic #1”、“Topic #2”等通用名称。只有当话题被重命名时ductor才能捕获到新名称。这是平台限制非ductor问题。4.3 模式三命名会话聊天中的“分屏”想象一下你正在和Claude深入讨论一个复杂的认证流程突然需要临时查一个不相关的API文档。你不想打断当前的思路也不想污染当前的对话上下文。这时命名会话Named Session就派上用场了。使用方法你 正在和Claude讨论OAuth2流程... 你 /session 查询一下Stripe支付API的退款接口格式 Bot: [已创建命名会话 “stripe-refund”] 此时名为“stripe-refund”的独立会话在后台启动。你可以继续在主会话讨论OAuth2。 你 stripe-refund 这个接口的idempotency key是必须的吗 Bot: [在“stripe-refund”会话中回复] 是的Stripe的退款接口... 你 回到主会话我们刚才说到refresh token的存储... Bot: [在主会话中回复] 对refresh token应该加密后存储...核心逻辑/session 提示会创建一个具有独立上下文的会话并以你给的提示作为第一条消息。你可以通过会话名的方式在任何时候向该会话发送后续消息。所有命名会话都共享主Agent的工作空间~/.ductor/workspace/但拥有独立的对话记忆桶。使用/sessions命令可以查看和管理所有活跃的命名会话。这相当于在你的主聊天窗口旁边打开了多个并行的终端标签页每个都运行着一个独立的AI对话。4.4 模式四后台任务异步委托专家有些任务耗时较长比如“分析整个代码库的依赖关系并生成报告”。你不想干等着希望AI在后台默默处理完成后把结果通知你。后台任务Background Task就是为此而生。触发方式自动委托当AI判断某个请求可能需要较长时间时会自动将其转为后台任务。手动委托你可以用明确的指令如“Delegate this:请为Q1-Q4的销售数据各生成一份分析报告。”任务生命周期任务启动后会在后台独立运行拥有自己的TASKMEMORY.md文件。你可以在原聊天窗口继续其他对话。任务运行中如果需要向你提问例如数据模糊需要澄清它会通过Agent向你发起询问你回答后它继续执行。任务完成后结果会自动发送回发起任务的聊天窗口。使用/tasks命令可以查看所有任务状态并对其进行管理如取消、查看日志。优先级调度ductor v0.16.0引入了任务优先级interactive,background,batch你可以通过配置控制资源分配确保高优先级的交互请求不被后台批量任务阻塞。4.5 模式五子Agent完全独立的副驾驶这是ductor最强大的功能用于实现真正的多AI智能体协作。子AgentSub-agent不是另一个会话上下文而是一个完全独立的ductor实例。它拥有自己独立的Telegram Bot需要另一个BotFather Token或Matrix账户。自己独立的工作空间目录~/.ductor/agents/agent_name/。自己独立的配置文件可以设置不同的心跳、超时、默认模型等。自己独立的内存和文件系统。创建子Agent以Telegram为例ductor agents add my-codex-agent执行此命令会启动一个交互式向导引导你为新Agent创建配置包括申请新的Bot Token等。协作场景 假设你的主AgentMaster使用Claude擅长架构设计子AgentCodex-Agent使用Codex擅长快速生成代码片段。[你在与Master的私聊中] 你 让codex-agent为这个用户模型编写单元测试。 Master: [理解指令将任务转发给Codex-Agent] Codex-Agent: [在自己的工作空间和会话中开始编写测试] Codex-Agent: [完成测试将结果发回给Master] Master: [将Codex-Agent生成的测试代码呈现给你]这种架构使得你可以根据AI模型的特长组建一个“AI团队”让它们各司其职协同完成复杂项目。5. 高级配置与自动化实战ductor的配置文件~/.ductor/config/config.json是其大脑。掌握配置才能发挥全部威力。5.1 安全与权限精细化控制ductor采用双重白名单机制安全性很高。{ telegram: { bot_token: YOUR_BOT_TOKEN, allowed_user_ids: [123456789], // 允许私聊的用户ID allowed_group_ids: [-1009876543210], // 允许响应的群组ID group_mention_only: false, // 在群组中是否需要提及才响应 allowed_channel_ids: [] // 允许的频道ID单独管理 } }allowed_user_ids必须配置。只有列表中的用户ID才能与机器人进行私聊。allowed_group_ids默认为空数组[]。只有列表中的群组ID机器人才会响应。结合group_mention_only可以严格控制机器人在群组中的行为。group_mention_only设为true时在群组中机器人只响应直接提及它或回复它消息的指令。这能有效防止群聊刷屏。热重载修改这些配置后保存config.jsonductor会在几秒内自动加载新配置无需重启。5.2 记忆系统的维护与优化ductor的记忆系统基于Markdown文件简单但强大。随着对话增长MAINMEMORY.md文件会变大可能影响CLI的上下文窗口和性能。v0.16.0引入了自动记忆维护功能。相关配置项{ memory: { compaction_boundary_kb: 50, // 当记忆文件超过此大小时触发压缩 reflection_hook: python3 /path/to/your/reflection_script.py, // 压缩前执行的自定义脚本 compaction_provider: claude // 使用哪个AI来执行压缩总结 } }工作流程当MAINMEMORY.md文件大小超过compaction_boundary_kb例如50KB时触发压缩流程。首先执行一个“静默刷新”将当前所有活跃会话的上下文快照保存。然后如果配置了reflection_hook会执行这个外部脚本。你可以用这个钩子做一些自定义分析或备份。最后ductor会调用指定的compaction_provider如Claude让它阅读当前的MAINMEMORY.md并生成一个精简的、保留核心要点的总结覆盖原文件。新的、更小的MAINMEMORY.md文件将作为未来对话的新起点。这个功能能有效管理长期运行的Agent的记忆防止“失忆”或性能下降。5.3 构建自动化工作流Cron与Webhookductor内置了任务调度器Cron和Webhook支持可以实现定时任务和外部事件触发。定时任务Cron 使用/cron命令可以交互式地创建和管理定时任务。例如创建一个每天上午9点运行的代码健康检查任务。/cron add Bot: 请输入Cron表达式例如 0 9 * * * 你 0 9 * * * Bot: 请输入要执行的命令或提示 你 分析workspace/下的Python代码找出可能的bug和代码异味将结果保存到output_to_user/daily_check.md Bot: 定时任务已添加。任务结果将发回此聊天。任务结果会自动发送到创建该任务的聊天窗口。你还可以在cron_jobs.json中为任务配置独立的执行参数如使用不同的AI模型。Webhook Webhook允许外部服务通过HTTP请求触发ductor执行任务。有两种模式wake模式将Webhook接收到的数据作为提示注入到指定的活跃聊天会话中模拟用户输入。cron_task模式在独立的、隔离的上下文中运行一个任务更适合后台处理。配置Webhook需要在webhooks.json中定义端点、密钥和触发模式。这可以与CI/CD管道、监控报警等系统集成实现“事件驱动”的AI自动化。5.4 媒体处理与技能扩展ductor可以接收并处理图片、音频、视频等媒体文件。图片自动进行尺寸调整和WebP格式转换可配置然后传递给AI CLI进行视觉分析。音视频v0.16.0增强了媒体转录钩子。你可以配置外部命令如whisper、ffmpeg来处理媒体文件将转录文本交给AI分析。配置示例{ media: { image_resize_max_pixels: 2097152, audio_transcription_command: whisper --model base --language en --output_dir {output_dir} {file_path}, video_transcription_command: ffmpeg -i {file_path} -vn -acodec pcm_s16le -ar 16000 -ac 1 {output_dir}/audio.wav whisper --model base --language en --output_dir {output_dir} {output_dir}/audio.wav } }当收到音频文件时ductor会将{file_path}和{output_dir}替换为实际路径执行你配置的命令然后将生成的文本送入AI处理。6. 故障排查与性能调优即使设计再精良在实际部署中也会遇到问题。以下是我在长期使用中积累的常见问题排查清单。6.1 连接与认证问题问题现象可能原因解决方案启动时报Invalid token或连接失败Telegram Bot Token错误或网络问题。1. 检查Token是否复制完整。2. 运行ductor onboarding重新配置。3. 检查本地网络是否能访问Telegram API某些网络环境需配置。机器人不响应私聊消息用户ID未添加到allowed_user_ids。1. 使用/where命令确认你的用户ID。2. 手动编辑config.json将ID加入数组。3. 或直接告诉机器人“将用户ID 123456789添加到允许的用户列表。”机器人在群组中不响应1. 群组ID未允许。2. 机器人不是管理员。3.group_mention_only为true且未提及。1. 按4.2节步骤将群组ID加入白名单。2. 将机器人设为群管理员。3. 在群组中发送你的机器人或回复机器人的消息。Matrix连接失败Homeserver地址、用户ID或密码错误。1. 确认homeserverURL格式正确如https://matrix.example.com。2. 确认使用完整的用户IDuser:server.com。3. 首次登录后凭证会缓存后续使用token。检查logs/agent.log查看详细错误。6.2 CLI执行与响应问题问题现象可能原因解决方案AI无响应或超时1. 对应的CLI未正确安装或登录。2. CLI进程卡死。3. 网络问题导致CLI调用失败。1. 在终端手动运行claude等命令测试是否正常。2. 查看logs/agent.log是否有CLI报错。3. 使用/stop_all命令强制停止所有进程然后重试。4. 检查config.json中的timeout_seconds设置是否过短。流式响应中断网络波动或消息平台API限制。1. 检查网络连接。2. 对于长输出ductor会自动分片。偶尔中断可尝试重新发送指令。3. 查看日志确认是否触发了平台的频率限制。记忆不持久MAINMEMORY.md文件权限问题或损坏。1. 检查~/.ductor/workspace/memory_system/目录权限。2. 尝试备份并删除MAINMEMORY.md让ductor重建。3. 检查磁盘空间。6.3 性能调优建议会话隔离策略不要滥用“命名会话”。每个活跃的会话都会占用内存并保持CLI连接。对于临时性的、短期的分支讨论使用命名会话对于长期、独立的项目使用群组话题或子Agent这样资源管理更清晰。记忆压缩配置根据你的使用频率调整compaction_boundary_kb。如果你每天进行大量深度对话可以设置得小一些如30KB让记忆更频繁地压缩、保持精炼。如果对话以碎片化信息为主可以设置得大一些如100KB避免过早丢失细节。超时设置在config.json中调整timeout_seconds。对于需要长时间思考的复杂任务如代码生成、架构设计可以适当延长超时时间例如300秒。对于简单的问答可以缩短以快速失败。启用Docker沙箱如果你担心AI CLI工具的行为不可控或需要在不同项目间进行严格的环境隔离可以使用ductor docker enable启用Docker沙箱。这会将所有CLI执行隔离在容器内并通过挂载卷ductor docker mount /path来共享必要的目录。日志级别默认的日志级别是INFO。如果遇到疑难杂症可以临时在配置中增加log_level: DEBUG会输出更详细的流程信息有助于定位问题。注意DEBUG日志量很大排查后应改回INFO。7. 生态整合与进阶玩法ductor的本地化、脚本化特性让它能轻松融入现有的开发工具链。7.1 与版本控制系统结合由于所有工作文件都在~/.ductor/workspace/下你可以将这个目录纳入版本控制如Git来跟踪AI助手生成的代码、文档的演变过程。更进阶的玩法是在workspace/tools/目录下放置你自己的脚本这些脚本可以被AI在任务中调用。例如创建一个workspace/tools/git_helper.sh脚本#!/bin/bash # 获取当前仓库的变更摘要 git status --short然后在与AI对话时你可以说“运行git_helper工具告诉我工作区有什么变更。” AI会识别出这是一个可用的工具并执行它。7.2 构建自定义技能库ductor会自动加载~/.claude/、~/.codex/、~/.gemini/下的技能skills。你可以在这里放置针对特定领域如“React代码审查”、“SQL优化”的提示词模板或规则文件。当ductor调用对应的CLI时这些技能会被自动加载极大地提升AI在特定任务上的表现。7.3 通过WebSocket API进行程序化交互Betaductor提供了一个WebSocket API通过ductor api enable开启。这意味着你可以编写外部程序通过WebSocket协议向ductor发送消息、接收响应从而实现更复杂的自动化流程。例如你可以创建一个监控脚本当服务器错误日志达到一定阈值时自动通过WebSocket API请求ductor分析日志并给出修复建议。这个功能目前处于Beta阶段但为ductor从“交互工具”向“可编程AI服务层”演进打开了大门。ductor这个项目最让我欣赏的是它在“强大”和“简洁”、“灵活”和“可控”之间找到了一个很好的平衡点。它没有试图去重新发明轮子AI模型而是巧妙地利用现有的、最好的轮子官方CLI然后专注于解决“如何更自然、更高效地使用这些轮子”的问题。它的本地优先、配置即代码、模块化设计都透着一股老派工程师的务实感。如果你已经习惯了在终端与AI CLI交互但又渴望一个更结构化、更自动化、更能融入团队协作环境的工作流那么花点时间部署和配置ductor很可能会显著提升你的“人机共生”开发体验。它不是一个开箱即用的傻瓜式产品而是一套需要你亲手搭建和调教的乐高积木但一旦搭建成型它就能成为你数字工作流中一个无比顺滑且强大的组成部分。