资讯详情

多Agent集群24小时稳定运行实战:架构设计、调度机制与运维踩坑记录

📅 2026/10/10 4:12:36 | 华诺云谱 👁 阅读
多Agent集群24小时稳定运行实战:架构设计、调度机制与运维踩坑记录
这段时间我折腾出来一套 24 小时不停工作的多 Agent 集群不是那种跑几分钟就结束的 demo而是真的把一堆 AI Agent 挂在后台日复一日地处理任务。这个项目从构思到稳定运行前前后后踩了不少坑也把很多藏在文档背后的细节摸了一遍。写这篇东西是想把整个从零搭建的思路、架构选型、核心机制和实际运维经验完整复盘一遍给正在从单 Agent 走向多 Agent 协作的同学一份能直接抄作业的参考。所谓多 Agent 集群简单说就是把多个具备不同角色、不同提示词配置的 AI Agent 实例组织起来通过消息队列、调度器、状态存储这些基础设施协同工作。我这边主要用来做定时信息采集、长文本分析、内容自动整理这类任务之前单 Agent 跑经常卡死在半路现在换成集群之后稳定性提升了好几个量级。这篇内容适合已经跑通过单个 Agent、想往分布式方向走的人也适合正在选型任务编排方案的技术负责人。1. 为什么我会去搭一个多 Agent 集群1.1 单 Agent 把我逼疯了我先讲讲之前用单 Agent 的痛苦经历。最开始我的方案很简单一个常驻 Python 进程循环从任务列表里拿一条任务调用模型接口处理完再拿下一条。听起来没啥问题跑起来才知道难受。比如一个任务需要先抓网页、再做摘要、然后翻译、最后归档这一串流程跑下来可能十几分钟期间模型接口偶发超时整个流程就卡死。有一次我夜里挂了一个批量任务预计八个小时跑完结果凌晨三点某个第三方接口超时程序直接抛异常退出。第二天早上起来一看前面六个小时的工作全部白费还得从头再来。这种“做了很久突然全毁”的挫败感是促使我下决心换架构的直接原因。再往后我还发现单 Agent 几乎没有容错设计。上下文窗口是固定的一个长任务跑到一半上下文塞满了后面的推理质量就明显下降。任务只能串行处理一批 20 个任务就得排队等哪怕手上有 200 万 tokens 的配额也用不起来。最要命的是任何一个子环节出问题整体就挂没有任何隔离。1.2 “24 小时不停工作”到底是什么标准很多人一听 24 小时运行第一反应是“挂个守护进程崩了自动重启”。但实际上一个真正能长期运转的 Agent 系统要求远比这个高。我把它拆成三个层面来理解。第一层是消息层面外部产生的任务不管是 API 推进来的还是定时任务触发的都必须可靠地进入系统不能丢。第二层是状态层面某个 Worker 挂了之后它手里正在处理的任务不能被遗忘必须能被检测到、重新分配到别的 Worker 上。第三层是资源层面任务量有波峰波谷系统得能在高峰期多干活、低峰期少占资源而不是一遇到突发流量就雪崩。用便利店来类比一个 24 小时便利店不是挂个灯牌就行得有人轮班、有库存管理和应急处理。对 Agent 集群来说核心就是那四个字可恢复性。所有设计都围绕“某个环节失败了系统还能继续”来展开。这是我的总原则。1.3 这个方案适合谁参考这套集群方案不是为所有场景准备的。如果你是低频、短任务比如每天跑一两次数据抓取单 Agent 配合好的重试逻辑就足够了上集群反而增加运维负担。但如果你面临的是下面这些情况集群化就很值得考虑。第一类是自动化和批处理场景比如定时采集行业信息、批量处理文档、生成报表。任务量大且可以并行。第二类是长链路 AI 工作流一个任务要经过多个 Agent 角色协作比如先研究、再写作、最后质检。第三类是稳定服务型场景想给自己的项目加一个随时能响应的 AI 助手后台要求故障不影响主流程。我建议读这篇文章的人至少要会基本的 Docker 和 SQL对消息队列有模糊概念。如果是零基础可以先把单 Agent 跑通再来看我会讲到的任务状态机、心跳、队列消费这些概念就能对上号了。2. 整体架构设计与技术选型2.1 系统长什么样四个层次多 Agent 集群的架构说复杂很复杂说简单也就四层。接入层、调度层、执行层和协作基础设施。接入层负责把外部事件变成系统里的标准任务。我这里做了三种接入方式一个 HTTP API 接口方便其他系统往里推任务一个定时触发器本质是 cron 表达式解析器到点就往队列里塞任务一个文件监听器监控某个目录有新文件进来就生成对应的处理任务。调度层是整个集群的大脑运行着一个常驻的 Scheduler 进程。它负责任务的扫描、优先级排序、投递、超时检测和失败重试。调度器不直接调模型它只做“决策”决定哪个任务现在该由谁来处理。执行层就是一组 Worker 进程每个 Worker 是一个 Agent 运行时。我让 Worker 按角色区分比如“采集员 Agent”“分析员 Agent”“写作 Agent”它们从消息队列里领取属于自己的任务执行完把结果写回状态库。这层是可以水平扩展的想加速就多拉几个 Worker。协作基础设施是底层支撑包括消息队列负责任务传递、关系型数据库负责任务状态和元数据、向量存储负责 Agent 的长期记忆、分布式锁负责避免多个 Worker 抢同一份资源。这个分层的好处是各层之间只通过接口通信某个 Worker 升级不会影响调度器。2.2 为什么我没有直接上 K8s很多朋友看到“集群”两个字第一反应就是 Kubernetes。我的实际建议是别急着上除非你已经明确知道自己需要它。我最初也纠结过后来想明白了K8s 能解决的问题在初期阶段大多数根本不会遇到。我用的是一个更朴素的方案Docker Compose 编排 systemd 进程守护。一套 docker-compose.yml 把 PostgreSQL、Redis、Scheduler、三个 Worker 和监控组件管起来服务器重启之后 systemd 自动拉起整个栈。这个方案成本低理解成本低出问题好排查。那什么时候需要迁移到 K8s我给自己画了三条线。第一Worker 角色类型超过十种手工维护容器编排变得吃力第二需要真正的自动弹性扩缩容比如队列堆积时自动拉起一批 Worker跑完自动销毁第三涉及到异构资源调度比如某些 Agent 需要 GPU某些不需要需要更精细的调度能力。在此之前Compose 足够。技术原则我反复跟自己强调能少引入一个组件就少引入一个。每多一个组件就多一份部署、监控和排障负担。个人项目最怕的不是功能不够而是运维爆炸。2.3 消息队列、数据库与记忆存储的取舍消息队列上我对比过 Kafka 和 Redis Stream。Kafka 吞吐量大、生态成熟、消息回溯能力强但运维成本高需要 ZooKeeper 资源虽然新版慢慢弱化依赖对个人项目来说偏重。Redis Stream 的消费者组模型已经够用而且我本来就部署了 Redis省一个组件。最终选了 Redis Stream。任务状态存储我直接用了 PostgreSQL。任务系统的核心是状态机需要事务能力比如“从 pending 改为 running”这个操作必须原子完成否则两个 Worker 可能同时领走同一个任务。PostgreSQL 在这方面非常可靠我保留了对任务表的大量 SQL 查询排障时可读性极好。长期记忆这块我用的是一个 PostgreSQL 扩展提供的向量检索能力而不是单独搭一套向量数据库系统。扩展的好处是表结构和向量索引在同一个实例里备份、权限、事务都好管理。对于项目初期的数千条记忆量级性能完全够。选型真正要考虑的不是“哪个更强”而是“我的场景需要什么”。日常跑几百个任务Kafka 的百万级吞吐根本用不到项目只有几万条记忆独立向量库就是浪费。3. 核心机制拆解调度、心跳与任务状态3.1 任务模型与调度策略整个系统的核心是一张任务表我把它叫 tasks字段设计如下id BIGSERIAL PRIMARY KEY type TEXT NOT NULL -- 任务类型collect / analyze / write payload JSONB NOT NULL -- 任务入参JSON 格式 status TEXT NOT NULL -- pending / running / done / failed priority INT DEFAULT 5 -- 优先级1 最高9 最低 attempt INT DEFAULT 0 -- 已尝试次数 max_attempts INT DEFAULT 3 -- 最大尝试次数 available_at TIMESTAMPTZ -- 最早可执行时间用于定时任务 owner TEXT -- 当前占用的 Worker ID trace_id TEXT -- 链路追踪 ID created_at TIMESTAMPTZ DEFAULT NOW()调度器可以理解为一段轮询 SQL 加投递逻辑。它会扫描所有 pending 状态且 available_at 已到期的任务按照“优先级优先 创建时间先后”排序取一批然后把任务 ID 投递到对应的 Redis Stream 队列。关键是投递后要立刻把任务状态从 pending 更新为 running并把 owner 置为某个 Worker 的 ID这一步用一条带条件的 UPDATE 语句完成保证同一秒内两个调度器不会投递同一个任务。投递和状态更新需要保证一致性吗严格说要原子性但我的做法是“先改状态再投消息投递失败则回滚状态”。因为 Redis 和 PostgreSQL 是两个系统想做到强一致就得引入分布式事务太重了。通过幂等消费来兜底见粗粒度异常任务最多被重复投递不会被丢失。调度策略上我还加了一个小优化慢任务和快任务分流。涉及长时间抓取的任务投到 slow 队列普通短任务投到 fast 队列Worker 启动时按比例订阅两类队列避免一个慢任务堵住了后面几十个快任务。3.2 心跳、失联与任务接管Worker 上线后会启动一个后台线程每五秒往心跳表里写一条记录。心跳表结构很简单worker_id、worker_role、heartbeat_at。调度器每隔十秒扫一次心跳表发现某个 worker 的 heartbeat_at 超过三十秒没更新就把它标记为 offline。标记 offline 之后最关键的操作是“孤儿任务接管”。该 Worker 名下所有 running 状态的任务全部改回 pendingattempt 加一owner 清空available_at 设为当前时间加退避时间。这样其他 Worker 就能再次领取这个任务。如果 attempt 已经超过 max_attempts任务直接置为 failed并把失败原因记录下来。这里有个很隐蔽的坑Worker 只是网络抖动或数据库连接断开它自己并不知道已经被调度器标记为 offline。等它恢复过来手里可能还有正在跑的任务而且它还继续执行着。如果不做处理就会出现旧的执行和新的执行叠加的情况。我的处理方式是Worker 每次执行下一步操作之前先检查自己的 Worker ID 是否仍然有效也就是调度器没有把自己标记成 offline。如果已经被下线Worker 立刻丢弃当前任务不再提交结果进入“准备退出”状态。这个设计术语叫“优雅降级”简单说就是承认自己已经“死了”别再给系统添乱。3.3 Agent 上下文和长期记忆怎么隔离多 Agent 系统最容易出现的问题是上下文串味。A 任务积累的信息被 B 任务读到结果就是两份报告牛头不对马嘴。我引入了一个“会话”概念每个任务创建一个独立的 session_id所有对话轮次、中间结果、临时文件都挂在 session_id 下面。会话数据默认只存活到任务结束。任务完成后我会从会话中提取“值得沉淀的结论”写入长期记忆表。长期记忆表按命名空间隔离所谓命名空间就是 agent_role比如“分析员的记忆”和“写作员的记忆”物理上分开避免互相污染。同一个角色内部的记忆再做场景标签方便检索。长期记忆的写入流程是先对文本做切块再生成向量最后存入带向量的表。检索时把用户的问题也向量化做相似度搜索取排名靠前的片段拼进提示词。这套逻辑很像现在流行的那种“带记忆的知识库”玩法但区别在于我把它和任务生命周期绑定起来了。为什么这么重视隔离因为 Agent 模型本身是无状态的所谓的记忆完全依赖外部存储。存储的隔离性直接决定了多 Agent 协作时内容会不会互相干扰。我在早期版本踩过记忆污染的坑后来加了命名空间和 session 才彻底解决。4. 实操部署从零开始搭建集群4.1 部署拓扑与容器编排我用的是一台 16 核 32G 内存的普通服务器把所有组件都跑在 Docker 里。部署清单包括PostgreSQL、Redis、Scheduler、三个 Worker对应三个角色、一个 API 网关容器、Prometheus 和 Grafana 用于监控。整体拓扑是单一主机上的容器组外部请求只进 API 网关内部服务之间通过容器网络互通。docker-compose.yml 的关键部分大概长这样version: 3.8 services: postgres: image: postgres:16 environment: POSTGRES_DB: agent_cluster POSTGRES_USER: agent POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: - pg_data:/var/lib/postgresql/data restart: always redis: image: redis:7 command: redis-server --appendonly yes volumes: - redis_data:/data restart: always scheduler: build: ./scheduler environment: DATABASE_URL: postgresql://agent:${DB_PASSWORD}postgres/agent_cluster REDIS_URL: redis://redis:6379 depends_on: - postgres - redis restart: always worker-analyze: build: ./workers/analyze environment: DATABASE_URL: postgresql://agent:${DB_PASSWORD}postgres/agent_cluster REDIS_URL: redis://redis:6379 ROLE: analyze depends_on: - postgres - redis restart: always worker-collect: build: ./workers/collect environment: DATABASE_URL: postgresql://agent:${DB_PASSWORD}postgres/agent_cluster REDIS_URL: redis://redis:6379 ROLE: collect depends_on: - postgres - redis restart: always worker-write: build: ./workers/write environment: DATABASE_URL: postgresql://agent:${DB_PASSWORD}postgres/agent_cluster REDIS_URL: redis://redis:6379 ROLE: write depends_on: - postgres - redis restart: always volumes: pg_data: redis_data:这份配置最核心的思路是把每个角色做成独立镜像通过 ROLE 环境变量区分。镜像里的代码是同一套只是加载的提示词配置和工具集不同。这样做的好处是公共逻辑只维护一份角色差异通过配置表达。Docker Compose 的 restart: always 保证了容器崩了会自动拉起但注意这不等于高可用只是进程级守护。真正的任务级高可用还要靠前面讲的调度器心跳检测和任务接管机制两者是互补关系。4.2 关键配置参数与调优记录参数调优是踩坑踩出来的。我记录几个最关键的调优点直接给结论。首先是 Worker 并发数。最开始我图快把每个 Worker 的并发任务数设为 8结果模型接口限流开始疯狂报错任务失败率直线上升。后来我压到每个 Worker 并发 3 个任务接口限流基本消失整体吞吐反而更高了。模型接口的并发瓶颈通常不在机器性能而在 API 配额所以并发数要结合配额来算。其次是超时设置。我给任务配置了两层超时单次工具调用超时 30 秒整个任务总超时 30 分钟。为什么要设置总超时因为 Agent 一旦进入某种死循环式的推理状态可能会反复调工具停不下来没有总超时任务就会永久占着 Worker。第三是 Redis Stream 的队列长度和消费组管理。每个队列设置了最大长度超过就丢弃最旧的消息因为任务状态在数据库里消息丢了还能重新投递这个设计让我不用担心队列膨胀。不过消费组的 pending 列表要定期处理长时间未确认的消息得重新认领我会写一个定时任务来做这个事。最后是 PostgreSQL 连接池。Scheduler 进程分配 10 个连接每个 Worker 分配 5 个。连接池太小会出现获取连接的等待太大会把数据库连接打满。我刚开始把所有进程都配成 20结果数据库先扛不住了。这个教训告诉我连接数要按进程数乘并发数来算而不是随手拍一个数。4.3 高可用与平滑升级策略高可用不是一个功能而是一套流程。我长期运行下来最重要的两件事是备份和升级流程。备份方面PostgreSQL 我每天凌晨做一次全量备份每小时做一次增量备份保留最近七天。Redis 开启了 AOF 持久化即使宕机也能恢复到最近一秒的状态。这里说明一下Redis 里存的只是待消费的任务消息丢了可由数据库状态恢复所以 Redis 的持久化级别不用太高AOF everysec 足够。升级方面Worker 的滚动升级流程是先把某个 Worker 的消费者停掉让它处理完手上正在执行的任务然后关闭容器、拉新镜像、重新启动。关键点是“先摘流量再升级”这和重启一个普通服务是两回事。调度器升级则更敏感因为它负责派发任务。我的做法是同时启动一个新版本调度器新版本抢占 Leader 锁之后旧版本自动退位。这个 Leader 锁用 Redis 的 SETNX 实现带过期时间每 15 秒续约一次。这套机制保证了调度器升级不需要停整体服务。配置管理我坚持一个原则密钥一律走环境变量配置文件只提交非敏感的公共逻辑。这样即使代码仓库泄露也不会把模型 API 密钥这些敏感信息暴露出去。密码和密钥放在服务器上的 .env 文件里权限设为仅当前用户可读。5. 监控、日志与告警24 小时盯盘的底气5.1 指标、日志与链路追踪系统有没有在正常工作不能等用户反馈要自己用监控发现。我建立了三层可观测机制指标、日志、链路追踪。指标层我采集五类核心数据队列深度、任务处理速率、任务成功率、Worker 心跳延迟、系统资源占用。这些指标通过开源监控采集器暴露给 Prometheus再由 Grafana 展示成仪表盘。我给自己搭的仪表盘很简单几个大数字加趋势线一眼就能看出系统状态。日志层要求所有进程输出 JSON 格式的结构化日志并且每条日志都带 trace_id。trace_id 从任务创建时生成贯穿调度器、消息队列、Worker、数据库操作的整个链路。排查问题时拿着 trace_id 一搜整个过程就串起来了。没做这个之前排查一个问题要在多个日志文件之间反复跳效率非常低。链路追踪我没有上完整的分布式追踪框架因为我的链路相对简单调度器到 Worker 到外部调用最多三层。用 trace_id 加日志字段就能覆盖。真的把痕迹系统铺起来收益不大成本高。可观测性的目的是快速定位问题不是把工具体系搞得越高级越好。给一个最小可用的监控指标清单指标采集方式告警阈值参考队列深度Redis LLEN超过 10000 持续 10 分钟任务成功率数据库统计低于 80% 持续 5 分钟Worker 离线数心跳表统计大于 50% Worker 离线任务平均耗时数据库统计相比基线翻倍持续 30 分钟系统内存使用节点采集器超过 85% 持续 15 分钟5.2 告警规则怎么定告警规则设计得不好运维体验会非常糟糕。要么告警太多变成“狼来了”要么告警太少漏掉真问题。我把自己总结的经验分成了三个优先级。紧急告警是必须立刻处理的比如“所有 Worker 全部离线超过五分钟”。这种情况说明整个集群已经停止运转需要马上介入。重要告警是短期内需要处理的比如“队列积压持续上升且超过阈值”这说明处理能力跟不上任务增长速度。一般告警是观察性的比如“单个任务重试超过两次”让系统继续跑我抽空看日志。告警阈值不能拍脑袋要参考系统正常状态的历史数据。比如我一开始把任务成功率阈值设为 99%结果动不动告警。后来观察了一周发现正常波动就在 95% 左右有时候个别任务失败是正常的。我把阈值调成 80% 并持续五分钟告警数量一下子就合理了。还有一个很实用的技巧是设置告警静默期。比如每天凌晨的系统维护窗口内很多指标波动是正常的不需要打扰。我给告警规则加了时间条件凌晨两点到四点的通知发到群里但不开声音。这样既不丢信息又不影响休息。5.3 自愈机制不是所有故障都要人管经历过几次半夜被告警叫醒之后我开始思考一个问题哪些事情系统自己就能解决不必打扰人。我逐步建立了一套自愈机制把运维负担降下来。第一层是进程守护。Docker 的 restart policy 加上 systemd 的守护负责容器级别的拉起。这一层能解决进程崩溃、OOM 被杀这类基础问题。第二层是任务重试。任务失败后自动进入退避重试大多数临时性错误重试一次就好了。第三层是队列堆积的简单弹性伸缩。我写了一个检测脚本当队列深度超过阈值时自动通过 Docker API 拉起一个额外的临时 Worker队列清空后自动关闭。这套自愈机制的核心思想是能自动化处理的就不让人处理让人只处理那些需要判断和决策的问题。比如“为什么最近任务成功率在缓慢下降是不是模型接口质量变化了”这种问题必须人来判断。而“某个容器挂了”这种问题机器处理比人快得多。自愈机制让 24 小时运行真正变得可行。我现在可能一整天不看后台系统照样在跑。只有真正异常的情况才会手机上弹一条紧急告警。这种感觉和最初“天天盯着日志怕出事”的状态完全不同。6. 踩坑实录常见问题与排查路径6.1 任务重复执行下游被反复调用这是我上线初期遇到最严重的问题同一个任务在数据库里显示成功但下游系统收到的调用比预期多了一次。排查后发现根因出在“先改状态再投消息”的流程上。场景是这样的Worker 处理完任务先把结果写入了数据库准备把状态改成 done。但这个提交需要时间而调度器发现任务已经超过计划执行时间判定超时就把任务重新投递了。另一个 Worker 接到任务又执行了一遍。典型的“分布式系统一次与仅一次”难题。我的解决方案分两层。第一层是幂等键每个任务携带一个全局唯一的请求 ID下游系统按 ID 去重。第二层是数据库状态机的严格更新Worker 执行前先确认当前状态仍是 running成功后再用条件更新语句把状态改为 done更新条件里带上“当前状态必须等于 running”这样重复提交就只会命中一次。这次经历给我最大的教训是生产环境里不能假设“消息只会被消费一次”。所有关键业务操作都要默认会被重复执行然后用幂等来兜底。这个认知转换是分布式系统实践中最重要的一课。6.2 Worker 进程活着但任务不走了有一次监控显示 Worker 全部在线心跳正常但队列深度只增不减。表面看起来一切正常实际已经停摆。这种故障最容易被忽视因为没有进程崩溃也没有红色告警。排查时我先看 Worker 日志发现没有新的消费记录。接着查数据库连接发现连接数打满了。为什么会打满因为某几个任务在调用模型接口时长时间无响应占着数据库连接不放后续任务获取不到连接全部卡在等待状态。这个问题的本质是“资源被长耗时任务占住导致其他任务饿死”。解决措施有三个一是限制单任务的总执行时间超时直接强制中断并释放资源二是把数据库连接池上限调低避免一个进程把连接耗尽三是增加一个监控信号当“连接池等待时间”超过阈值时主动报出来而不是等队列堆积才被察觉。这类故障给我的经验是进程活着不代表系统健康必须盯资源使用率和队列处理速率这类指标而不是只看“在线状态”。在线状态是二维的健康状态是多维的。6.3 队列积压导致的连锁故障有一批批量任务接入时我同时提交了上万条任务Redis Stream 队列深度瞬间飙升。Worker 的处理能力跟不上队尾任务的等待时间越来越长很快超过了总超时导致任务一投递就被判超时然后无限循环重试。整个系统进入了类“雪崩”的状态。这个问题的根源在于我没有区分任务类型把长耗时任务和短耗时任务混在同一个队列里。几个耗时十分钟的任务排在了前面后面几百个耗时几秒的任务全在排队。解决的方法是把队列做物理隔离。长任务走 slow 队列短任务走 fast 队列Worker 按固定比例订阅两类队列。同时入口处加了一个限流器超过系统处理能力上限的任务先返回“排队中”的提示而不是全部无条件接收。宁可让新任务等待也不让系统进入雪崩状态。调整之后系统的吞吐稳定性好了很多。即使某一类任务量暴增也只影响那一类队列不会拖垮其他任务链路。这个设计思路我一直推荐给朋友隔离和限流是保护系统稳定的最后一道防线。6.4 多个 Agent 抢占同一个外部资源多 Agent 集群还有一个真实存在的坑多个 Worker 同时操作同一个外部资源。我这边的场景是在做并发的网页采集两个 Worker 同时处理同一个 URL 目录下的文件发生写覆盖导致生成结果文件内容错乱。解决思路是给资源加分布式锁。任务在执行前先声明自己需要哪些资源用 Redis 的分布式锁对资源名加锁。锁操作我用 Lua 脚本实现原子性设置锁超时时间防止持锁 Worker 崩溃导致死锁。锁的粒度一定要细锁整个目录会串行化所有任务锁单个文件又会有频繁加锁的开销。另一个关联问题是共享 API 配额。多个 Agent 同时调用同一个外部服务可能导致总用量超额被限流。我给外部服务调用加了一个简单的令牌桶限流器所有 Worker 共享同一个桶从源头控制并发请求量。这类问题的核心是多 Agent 看起来是在各干各的但底层是共享同一个世界的。外部资源和 API 配额就是那个共享的世界不做好协调并行反而会拖后腿。最后说点实在的这套多 Agent 集群搭完后我最大的收获不是代码和架构而是想明白了一个道理所谓 24 小时不停工作核心不是“不出错”而是“可恢复”。错误一定会发生模型接口会超时第三方服务会抖动进程会被杀死但只要状态能恢复、任务能重新调度、关键操作是幂等的系统就能一直转下去。还有一点经验是想清楚技术方案的边界。我用 Docker Compose 而不是 K8s用 Redis Stream 而不是 Kafka用 PostgreSQL 扩展而不是独立向量库每一步都问过自己“我现在真的需要这个重量级组件吗”。这个问题问到现在帮我省下了大量维护成本。接下来我打算把调度器拆成多实例彻底去掉单点再去探索基于成本的 Worker 路由比如把耗时短的任务优先安排给响应快的 Agent 实例。这个系统离完美还很远但至少它已经做到了从“跑起来”到“长期跑住”的过渡。希望这篇复盘能帮你少走我走过的那些弯路。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑