用微信调度AI Agent:从消息接入到异步任务调度系统实战

发布时间:2026/8/27 4:46:30
用微信调度AI Agent:从消息接入到异步任务调度系统实战 这是一篇关于用社交软件调度AI Agent的完整实操教程。思路是这样的把“通过微信发消息调动AI干活”这件事拆解成一条完整的技术链路——从Agent核心概念到消息接入层企业微信群机器人/个人号方案到调度器设计再到任务分发与反馈闭环最后补充排错和工程建议。代码以Python为主贴近真实落地场景可直接参考实现。在进入正文之前先把结论放在前面用微信调度Agent本质上不是一个“聊天机器人”需求而是一个“异步任务调度平台”需求。你的落脚点应该放在调度器设计和任务生命周期管理上而不是花太多时间纠结消息格式好不好看。1. 这个需求背后的技术本质Agent 与调度1.1 你真正想做的是什么很多朋友看到“用微信调度AI智能体Agent干活”这个标题第一反应是做一个“微信聊天机器人”——用户发消息机器人回复消息。这个理解不能说完全错但会把你带偏。当我们说“调度Agent干活”时我们指的是微信只是入口/遥控器真正干活的是一个异步、可扩展、带状态管理的任务执行系统。用户在微信里发一句“帮我跑一下今天的销售数据报表”背后发生的是一整套动作微信消息被接收并解析。系统识别用户意图判断这是数据分析任务而不是闲聊。系统为该请求创建一个任务实例分配一个 Agent。Agent 开始执行任务可能涉及数据库查询、代码执行、第三方API调用等。任务完成后结果被回传到微信对话窗口。所以这篇文章的重点会是Agent调度系统的设计与实现以及如何把微信这条消息通道接入到这个调度系统里。1.2 什么是 AgentAgent智能体在 AI 领域没有一个完全统一的定义但在工程落地中我们可以把它理解为一个“具备自主完成特定任务能力”的程序单元。它和普通函数的区别在于函数是被动调用的输入参数、输出结果。Agent 具有一定程度的“自主性”它可以拆解任务、选择工具、调用外部系统甚至根据中间结果调整策略。举个例子。你写一个getSalesData(date)函数它只能返回原始数据。而一个销售数据分析 Agent它可以自己判断需要先查数据库然后做一次异常值清洗再生成图表最后写一段解读文字。你只需要告诉它“跑一下昨天的销售数据”它自己完成一系列子任务。1.3 为什么需要调度Agent 本身是一个执行单元但一个真实项目里不可能只有一个 Agent。你可能同时有数据分析 Agent。定时任务 Agent。内容生成 Agent。运维告警 Agent。业务操作 Agent比如下单、审批。这些 Agent 同时存在而且请求随时可能涌入。这时候就需要一个调度系统来解决几个问题该由哪个 Agent 来干这个活路由多个请求同时来怎么办并发控制、队列Agent 执行过程中挂掉了怎么处理超时、重试、补偿任务结果怎么告诉发起人回传链路Agent 是否有权限执行这个操作鉴权与审批这些问题后续我们都会讲到。先记住一个核心结论消息通道微信是表调度系统是里。2. 整体架构与方案选型2.1 整体架构在动手写代码之前先把架构图在脑子里画出来。整条链路分为四层消息接入层微信入口 ↓ 意图识别与任务路由层 ↓ 调度器 / 任务队列 ↓ Agent 执行层干活的 ↑ 回传结果到微信我用一张 ASCII 简图来表示[微信/企业微信] --消息-- [Msg Gateway] --解析-- [Intent Router] | v [Scheduler / Queue] | ------------------------------------- | | | v v v [Agent 1] [Agent 2] [Agent 3] | ------------------------------------- | v [Result Notifier] --回传-- 微信2.2 技术栈选型模块可选方案说明消息接入企业微信群机器人 Webhook、企业微信应用消息 API、个人号协议有封号风险、Telegram Bot 等个人开发首选企业微信群机器人或普通群机器人方案避免账号风险消息接收服务Python FastAPI / Flask或 Node.js Express其中 FastAPI 上手快、性能不错示例用 FastAPI队列Redis RQ、Celery Redis/RabbitMQ、AWS SQS 等轻量场景 RQ 够用生产建议 Celery 或 SQSAgent 载体大模型 API 调用如 OpenAI、开源模型本地部署、自研规则引擎 LLM 混合本文示例先写一个基于函数封装的“轻量 Agent”避免过度复杂存储Redis状态缓存、PostgreSQL/MySQL任务记录、审计个人项目可以先只用 Redis生产必须有持久化注意这里不限定具体的模型厂商重点是调度逻辑。大模型只负责意图识别和任务拆解真正执行的动作还是由代码完成。2.3 关于“个人号”与“企业微信”的选择很多朋友想用自己的个人微信做入口。这里要提醒一个风险个人号接入第三方自动化框架存在账号限制风险严重时可能封号。从安全角度出发个人项目建议优先用以下方式企业微信群机器人Webhook 形式只能主动发消息不能接收用户消息。企业微信应用可以接收用户发来的消息并主动推送结果这是官方接口比较安全。微信公众号服务号支持接收用户消息但需要认证对个人不一定方便。群机器人 指令轮询用户通过机器人发送指令到某个中转服务。本文的示例将围绕“企业微信应用”和“Webhook 机器人”两条路线展开。你的应用如果只是“命令下发结果回传”用群机器人 Webhook 就够了如果希望“用户发消息触发任务”则使用企业微信应用。如果只是自己用也可以考虑 Telegram BotAPI 更简洁、调试成本更低思路是相通的。3. 核心问题拆解从一条微信消息到一个任务在写代码之前我们先把一条消息从发出到完成的全过程拆解开用文字描述清楚后续代码才能有所依据。3.1 消息入口微信侧产生一条消息可能是用户在企业微信应用里输入/report 2025-06-01用户发给群机器人机器人 查一下今天的服务器状态自动触发定时任务到点主动调用 Agent不同的入口接收和处理方式不同。但一旦消息进入系统路径是一样的。3.2 消息解析与意图识别这是第一个关键步骤也是“有没有 AI 含量”的分水岭。方案一规则匹配轻量方案优点是快、可控、可离线运行。适合指令固定、格式明确的场景。/report 2025-06-01 → 任务类型report_generator参数date2025-06-01 /status → 任务类型server_status_check方案二大模型意图识别智能方案把用户的自然语言输入交给大模型让它输出结构化指令。例如设计一个函数调用Function Calling提示词让模型输出如下 JSON{ task_type: report_generator, params: { date: 2025-06-01, format: markdown } }这种方案的优点是自然语言门槛低用户不用记指令。缺点是费 token、有延迟、可能识别错误。我建议生产环境采用规则优先 LLM 兜底的混合方案固定格式指令走规则自由输入走大模型。3.3 任务路由拿到task_type后调度器需要找到处理该任务类型的 Agent。这一步本质上是一个映射关系report_generator - ReportGeneratorAgent server_status - ServerMonitorAgent kod_kod - CodeTaskAgent路由表可配置、可热更新。生产环境不要写在代码 if-else 里建议存在配置中心或数据库并支持灰度切换。3.4 任务入队与异步执行这里要理解一个关键点微信消息响应时间是受限的你不能在用户发消息的 HTTP 请求里同步执行一个耗时任务。例如用户发送“跑一下昨天全平台销售数据分析”这个任务可能要执行 2 分钟。如果你在微信回调接口里同步执行请求会超时用户那边只会看到错误。正确做法是微信回调接口收到消息后快速把任务写入队列并立即返回“已收到正在处理中”。调度器从队列中拉取任务分配给合适的 Agent 执行。Agent 完成后通过回调接口把结果主动推送回微信群/应用。3.5 任务状态与反馈一个任务从创建到结束会经历以下状态PENDING等待中 → SCHEDULED已分配 → RUNNING执行中 → SUCCEEDED成功 / FAILED失败 / TIMEOUT超时 / CANCELED取消每个状态的转换都要有记录。这样以后排查问题时可以回答“这个任务为什么没回传结果”。4. 实战用 Python 实现一套“微信消息 → Agent 调度”的最小闭环下面我们进入正题实现一个最小可运行的示例。这个例子不会直接对接企业微信真实接口因为涉及密钥、回调 URL 等离题且不好演示而是采用“模拟微信消息 Post 到网关”的方式然后把消息拆解、路由、入队、执行、回传的完整链路实现出来。如果你已经了解 FastAPI 和 Redis这块会非常轻松如果还不太熟悉照着代码走一遍也能理解整体结构。4.1 创建项目结构首先建立一个项目目录结构如下wechat-agent-scheduler/ ├── app/ │ ├── __init__.py │ ├── main.py # FastAPI 入口 │ ├── schema.py # Pydantic 模型 │ ├── agents/ │ │ ├── __init__.py │ │ ├── base.py # Agent 基类 │ │ ├── report_agent.py │ │ └── server_agent.py │ ├── scheduler.py # 调度器 │ ├── router.py # 意图路由 │ └── notifier.py # 回传通知 ├── requirements.txt └── README.md4.2 添加依赖在requirements.txt中写入fastapi0.115.0 uvicorn[standard]0.30.6 pydantic2.9.2 redis5.0.8 rq1.16.2 httpx0.27.2安装命令pip install -r requirements.txt版本号以你安装时的最新稳定版为准这里给出的是撰写本文时的常用版本组合。如果安装失败去掉版本号重新安装即可。4.3 定义消息模型文件app/schema.pyfrom typing import Any, Optional from pydantic import BaseModel class WeChatMessage(BaseModel): 模拟微信回调消息结构 msg_id: str # 消息唯一 ID from_user: str # 发送人 content: str # 消息内容 msg_type: str text # 消息类型默认文本 class Task(BaseModel): 任务模型 task_id: str # 任务 ID task_type: str # 任务类型如 report_generator params: dict[str, Any] # 任务参数 status: str PENDING # 任务状态 result: Optional[Any] None error: Optional[str] None created_from: str # 消息来源 created_by: str # 发起人这里有两个模型一个负责接收微信消息另一个负责内部流转。4.4 Agent 基类文件app/agents/base.pyimport abc from typing import Any from app.schema import Task class BaseAgent(abc.ABC): Agent 抽象基类所有 Agent 必须实现 execute 方法 def __init__(self, name: str): self.name name abc.abstractmethod def execute(self, task: Task) - Any: 执行任务返回结果 raise NotImplementedError def can_handle(self, task_type: str) - bool: 判断当前 Agent 是否能处理该任务类型 return False设计说明execute是每个 Agent 都要实现的核心方法这里入参是任务对象出参是任意类型后续序列化传给调度器。can_handle用来让调度器遍历已注册的 Agent找到合适的处理者。你也可以换一种方式注册的时候直接指定task_type映射方式不重要重要的是“解耦”。4.5 实现两个具体 Agent报表生成 Agent文件app/agents/report_agent.pyimport time from typing import Any from app.agents.base import BaseAgent from app.schema import Task class ReportGeneratorAgent(BaseAgent): 模拟一个生成销售报表的 Agent def __init__(self): super().__init__(namereport_generator) def can_handle(self, task_type: str) - bool: return task_type report_generator def execute(self, task: Task) - Any: 这里模拟执行任务的过程实际场景可以接入数据库查询、图表生成等 date task.params.get(date, unknown) # 模拟耗时的报表生成过程 time.sleep(2) report { title: f销售数据报表 {date}, total_sales: 128000, order_count: 356, summary: 整体销售趋势平稳华东区贡献最大。, generated_by: self.name, } return report这里故意加了time.sleep(2)是为了模拟真实场景里 Agent 执行耗时的情况。真实项目中这块可能是一个数据库查询 一个数据分析脚本 一个文件生成过程。服务器状态检测 Agent文件app/agents/server_agent.pyfrom typing import Any from app.agents.base import BaseAgent from app.schema import Task class ServerMonitorAgent(BaseAgent): 模拟服务器状态检测 Agent def __init__(self): super().__init__(nameserver_monitor) def can_handle(self, task_type: str) - bool: return task_type server_status def execute(self, task: Task) - Any: # 实际项目可以在这里调用 ping、调用云监控 API、读取 /proc 数据等 return { status: healthy, cpu_usage: 23%, memory_usage: 41%, disk_usage: 62%, checked_at: 2025-06-01 10:30:00, generated_by: self.name, }4.6 意图路由文件app/router.py这里实现的是“从用户消息中解析出任务类型和参数”。我们同时支持两种方式。import json import re from typing import Optional from app.schema import WeChatMessage def parse_command_like(content: str) - Optional[dict]: 尝试解析指令式消息如 /report 2025-06-01 # 简单正则/命令名 参数 match re.match(r^/([a-z_])\s*(.*)$, content.strip()) if not match: return None cmd match.group(1) args_str match.group(2).strip() if cmd report: return { task_type: report_generator, params: {date: args_str or today}, } if cmd status: return { task_type: server_status, params: {}, } return None def parse_llm_intent(content: str) - dict: 用大模型解析自然语言意图。 这里不实际调用大模型 API而是给出一个模拟示例。 实际项目中可以把 content 发给大模型要求它返回结构化的 JSON。 # 在真实项目中你的代码会像这样调用大模型 # response llm_client.chat.completions.create( # model..., # messages[ # {role: system, content: 你是任务解析器只输出JSON}, # {role: user, content: content} # ], # response_format{type: json_object} # ) # return json.loads(response.choices[0].message.content) # 下面是一个模拟结果仅用于演示 if 报表 in content or 销售 in content: return { task_type: report_generator, params: {date: 2025-06-01}, } if 服务器 in content or 状态 in content: return { task_type: server_status, params: {}, } # 兜底返回一个无法识别的状态 return { task_type: unknown, params: {raw_content: content}, } def route_message(msg: WeChatMessage) - dict: 消息路由入口先尝试指令解析再尝试 LLM 解析 parsed parse_command_like(msg.content) if parsed is not None: return parsed return parse_llm_intent(msg.content)parse_command_like负责处理/report 2025-06-01这类指令parse_llm_intent负责处理“帮我跑一下昨天的销售报表”这类自然语言输入。真实项目中parse_llm_intent会调用大模型接口这里只做了模拟因为大模型的 API 调用方式变化较快需要你根据使用到的模型调整。4.7 调度器接下来是核心调度器。文件app/scheduler.pyimport uuid from typing import Optional from app.agents.base import BaseAgent from app.agents.report_agent import ReportGeneratorAgent from app.agents.server_agent import ServerMonitorAgent from app.schema import Task class Scheduler: 任务调度器负责把任务分发给合适的 Agent def __init__(self): self.agents: list[BaseAgent] [] self.register_agent(ReportGeneratorAgent()) self.register_agent(ServerMonitorAgent()) def register_agent(self, agent: BaseAgent): 注册一个 Agent self.agents.append(agent) print(f[Scheduler] Agent 已注册: {agent.name}) def create_task( self, task_type: str, params: dict, created_from: str , created_by: str , ) - Task: 根据路由结果创建任务 task Task( task_iduuid.uuid4().hex, task_typetask_type, paramsparams, created_fromcreated_from, created_bycreated_by, ) print(f[Scheduler] 任务已创建: {task.task_id}, type{task.task_type}) return task def dispatch(self, task: Task) - Optional[BaseAgent]: 找到能处理该任务的 Agent for agent in self.agents: if agent.can_handle(task.task_type): return agent return None def run_sync(self, task: Task): 同步执行任务适合测试用。 生产环境中这个方法会被放入异步任务队列中执行。 agent self.dispatch(task) if agent is None: task.status FAILED task.error f没有找到能处理 {task.task_type} 的 Agent return task task.status RUNNING try: result agent.execute(task) task.status SUCCEEDED task.result result except Exception as e: task.status FAILED task.error str(e) return task调度器的核心逻辑就两个dispatch遍历已注册的 Agent找到能处理某个任务类型的那一个。run_sync同步执行任务并更新任务状态。生产环境里run_sync不会直接同步跑而是把任务封装后投入到 RQ/Celery 队列中。这里为了演示先保留同步版本。4.8 回传通知器文件app/notifier.pyimport json from app.schema import Task class Notifier: 通知器把任务结果转成可以回传到微信的内容 def format_result(self, task: Task) - str: 把任务执行结果格式化成适合微信展示的文本 if task.status SUCCEEDED: result task.result # 这里假设 result 是 dict实际项目中可能需要更完善的序列化 return f任务执行成功 ✅\n任务ID: {task.task_id}\n结果: {json.dumps(result, ensure_asciiFalse, indent2)} else: return f任务执行失败 ❌\n任务ID: {task.task_id}\n错误: {task.error} def send_to_wechat(self, message: str, target: str ): 模拟发送消息到微信。 实际场景中这里会调用企业微信应用消息接口或群机器人 Webhook。 # 在企业微信应用中调用 API 推送 markdown 消息给用户 # requests.post( # https://qyapi.weixin.qq.com/cgi-bin/message/send, # json{...} # ) print([Notifier] 开始回传消息到微信 ) print(message) print([Notifier] 消息回传结束 ) # 为了简单建一个全局通知器实例 notifier Notifier()真实项目中这里会替换成腾讯企业微信 API 调用或群机器人 Webhook。4.9 FastAPI 网关入口文件app/main.pyimport uuid from fastapi import FastAPI, HTTPException from app.notifier import notifier from app.router import route_message from app.scheduler import Scheduler from app.schema import Task, WeChatMessage app FastAPI(titleWeChat Agent Scheduler, version0.1.0) # 全局调度器 scheduler Scheduler() app.get(/health) def health_check(): 健康检查接口 return {status: ok} app.post(/wechat/message) async def handle_wechat_message(msg: WeChatMessage): 接收来自微信的消息解析、路由、创建任务并执行。 这是最小演示版本等以后接真实环境时需要改成异步任务队列。 # 1. 路由消息得到任务类型和参数 route route_message(msg) if route[task_type] unknown: return { msg: 无法识别该指令请使用 /report [date] 或 /status 格式或用自然语言描述需求。 } # 2. 创建任务 task: Task scheduler.create_task( task_typeroute[task_type], paramsroute[params], created_fromwechat, created_bymsg.from_user, ) # 3. 执行任务最小演示同步执行 task scheduler.run_sync(task) # 4. 回传结果 result_text notifier.format_result(task) notifier.send_to_wechat(result_text) # 5. 返回给微信网关一个确认信息 return { msg_id: msg.msg_id, task_id: task.task_id, task_status: task.status, reply: result_text, }4.10 运行与验证启动服务uvicorn app.main:app --reload --host 0.0.0.0 --port 8000新开一个终端用 curl 模拟微信消息推送curl -X POST http://localhost:8000/wechat/message \ -H Content-Type: application/json \ -d { msg_id: msg_001, from_user: zhangsan, content: /report 2025-06-01 }预期输出终端会打印调度日志和回传内容[Scheduler] Agent 已注册: report_generator [Scheduler] Agent 已注册: server_monitor [Scheduler] 任务已创建: 1a2b3c4d5e..., typereport_generator [Notifier] 开始回传消息到微信 任务执行成功 ✅ 任务ID: 1a2b3c4d5e... 结果: { title: 销售数据报表 2025-06-01, total_sales: 128000, order_count: 356, summary: 整体销售趋势平稳华东区贡献最大。, generated_by: report_generator } [Notifier] 消息回传结束 再用自然语言消息测试curl -X POST http://localhost:8000/wechat/message \ -H Content-Type: application/json \ -d { msg_id: msg_002, from_user: lisi, content: 帮我看看服务器状态 }如果一切正常会走 LLM 意图识别分支目前是模拟逻辑路由到server_monitorAgent。到这里一个“微信消息 → Agent 调度 → 结果回传”的最小闭环就完成了。但说实话这只是玩具级别的实现。真正能用于生产环境还得做下面这些增强。5. 进阶改造从同步到异步任务队列当前示例是同步执行的也就是微信回调接口会一直等待 Agent 执行完成。这在演示中可以生产环境不行。为什么HTTP 请求有超时限制一般 3~30 秒取决于网关配置。Agent 执行可能远超这个时间。同步接口会占用大量连接资源并发一高系统直接卡死。无法支持定时任务、重试、优先级等高级调度能力。所以正式项目要引入消息队列。下面是一个基于 Redis RQ 的改造示例。5.1 改造思路把run_sync替换为“把任务丢进 Redis 队列”然后启动一个或多个 Worker 进程去消费队列。主进程中收到微信消息后只做三件事校验消息合法性。路由并创建 Task。把 Task 序列化后推入 Redis 队列并立即返回“已受理”。Worker 进程负责从队列取出 Task。找到对应的 Agent 执行。执行完成后把结果写入 Redis / 数据库并调用企业微信 API 回推结果。5.2 改造后的核心代码在app/main.py中不再直接调用scheduler.run_sync而是import json import uuid from fastapi import FastAPI, HTTPException from redis import Redis from rq import Queue from app.router import route_message from app.scheduler import Scheduler from app.schema import Task, WeChatMessage app FastAPI(titleWeChat Agent Scheduler Async, version0.2.0) # 连接 Redis redis_conn Redis(hostlocalhost, port6379, db0) task_queue Queue(agent_tasks, connectionredis_conn) # 调度器只用于创建任务不用于同步执行 scheduler Scheduler() app.post(/wechat/message) async def handle_wechat_message(msg: WeChatMessage): route route_message(msg) if route[task_type] unknown: return {msg: 无法识别指令请换个说法。} task: Task scheduler.create_task( task_typeroute[task_type], paramsroute[params], created_fromwechat, created_bymsg.from_user, ) # 把任务推入队列交给 Worker 异步执行 task_queue.enqueue( app.worker.process_task, task.model_dump(), job_timeout600, result_ttl3600, ) return { msg_id: msg.msg_id, task_id: task.task_id, task_status: PENDING, msg: 任务已受理执行完成后会推送结果。, }5.3 Worker 实现新建文件app/worker.pyimport json from rq import get_current_job from app.notifier import notifier from app.scheduler import Scheduler from app.schema import Task def process_task(task_dict: dict): RQ Worker 执行任务 job get_current_job() task Task(**task_dict) task.status RUNNING scheduler Scheduler() agent scheduler.dispatch(task) if agent is None: task.status FAILED task.error f没有找到能处理 {task.task_type} 的 Agent else: try: result agent.execute(task) task.status SUCCEEDED task.result result except Exception as e: task.status FAILED task.error str(e) # 回传结果到微信 result_text notifier.format_result(task) notifier.send_to_wechat(result_text) # 这里可以写把任务状态保存到数据库的逻辑 # save_task_status(task) return task.model_dump()启动 Workerrq worker agent_tasks --url redis://localhost:6379/0这样就实现了“微信接口秒回 后台异步执行 完成后回推消息”的完整闭环。6. 常见问题与排查思路6.1 任务创建了但微信上没有收到回传结果可能原因排查方法解决思路Agent 执行抛异常查看 Worker 日志是否出现FAILED在except中补充堆栈日志用logger.exception(e)回传接口调用失败手动测试企业微信 Webhook确认 Webhook 地址可用确认消息格式适配企业微信机器人限制任务超时查看job_timeout是否设置太小给耗时任务单独加大超时时间Worker 没启动检查 RQ 队列状态确保 Worker 命令行参数中的队列名与入队队列名一致6.2 消息能识别但路由到了错误的 Agent检查parse_command_like的正则是否覆盖了所有指令。检查parse_llm_intent中模型返回的task_type是否在 Agent 注册表中有对应。建议在路由结果中增加日志输出打印原始的route字典。6.3 大模型误识别导致参数错误在提示词中要求模型严格按照 JSON Schema 输出并给出几个 few-shot 示例。对模型返回的task_type做白名单校验不在白名单内直接拒绝执行。对敏感参数如日期、金额、SQL 条件做代码级校验。6.4 并发一高Redis 队列堆积严重增加 Worker 数量多开几个rq worker agent_tasks进程。对任务做优先级划分紧急任务用高优先级队列。如果没有时间上的紧急要求可以用 RQ 的enqueue_at做定时调度削峰填谷。6.5 加一个通用排查清单□ 第一步确认消息是否进入了网关看 FastAPI 访问日志 □ 第二步确认意图路由是否命中看 route 输出 □ 第三步确认任务是否入队看 RQ 队列长度 □ 第四步确认 Worker 是否消费看终端日志 □ 第五步确认 Agent 执行是否报错看异常日志 □ 第六步确认回传通知是否发出看 Notifier 日志这个清单基本能覆盖 90% 的问题。7. 工程化建议与最佳实践整套链路跑通之后需要往工程化方向收敛。下面是来自实际项目落地中的几条经验按重要程度排序。7.1 任务必须有持久化和审计Redis 队列只适合做缓冲不适合做唯一存储。生产环境务必做到每个任务在数据库PostgreSQL/MySQL中有一条完整记录。记录创建时间、开始时间、结束时间、最终状态、执行结果、异常信息。对危险任务如删除、修改数据、发送消息增加人工审批环节。7.2 Agent 注册要配置化不要写死在代码里上面示例中Agent 是在代码里register_agent的。Agent 数量少没问题Agent 一多就难维护。建议把 Agent 路由表存入数据库或配置中心例如agent_nametask_typeendpointenabledweightreport_generatorreport_generatorhttp://agent-report:8080true10server_monitorserver_statushttp://agent-monitor:8080true10调度器每次根据task_type查表选择空闲中的 Agent 实例实现平滑扩展和灰度下线。7.3 微信侧要设计“指令说明”与“错误反馈”用户不是开发者不可能记住你的所有指令。建议在微信自动回复中加入 “帮助” 指令返回一份命令清单。当任务解析失败时不仅要告诉用户“不认识”还要给出相近指令提示。对耗时较长的任务先回复“已受理”再异步推送结果。7.4 设计安全的执行边界Agent 能执行的操作越多安全隐患越大。敏感操作必须满足最小权限Agent 使用独立的只读账号访问数据库需要写操作时走独立流程。人工确认涉及删除、覆盖、资金、对外发布等操作时增加评审/双人审批。操作留痕所有 Agent 执行过的操作保存日志方便事后审计。命令白名单如果 Agent 要执行 Shell 命令务必使用白名单机制禁止自由拼接命令。7.5 引入超时与重试机制每个 Agent 执行任务都要设置超时时间避免某个 Agent 卡死导致任务堆积。同时要设计重试策略网络瞬时故障最多重试 3 次。业务参数错误不重试只记录。大模型调用超时指数退避重试。重试必须保证“幂等性”——同一个任务执行两次和一次的结果一致。例如数据报表生成两次没关系但扣款任务重试两次就会出大事。所以每个任务要有幂等键执行前先检查是否执行过。7.6 日志规范建议每个任务都生成一个task_id所有日志带上这个 ID。这样从微信消息到最终结果一条链路可以用task_id串起来。日志格式建议2025-06-01 10:00:01 INFO [task_id1a2b3c] 收到微信消息 fromzhangsan, task_typereport_generator 2025-06-01 10:00:02 INFO [task_id1a2b3c] Agent report_generator 开始执行 2025-06-01 10:00:04 INFO [task_id1a2b3c] Agent report_generator 执行成功耗时2.1s 2025-06-01 10:00:04 INFO [task_id1a2b3c] 回传结果到微信8. 一些值得继续深入的方向整套系统跑通后如果想进一步丰富功能可以从以下几个方向延伸。8.1 定时调度有很多任务其实不需要“用户发消息才执行”而是定时执行比如每天早上 9 点推送昨日销售简报。每周一生成一次项目周报。每 5 分钟检测一次服务器状态异常时告警。这块可以引入 APScheduler或者直接使用 RQ 的定时入队能力。维护一张任务调度表把“定时任务”也看成一种任务来源然后用独立的调度进程触发。8.2 多模型 Agent 协作复杂任务可能需要多个 Agent 协作。例如“分析销售数据并生成 PPT 发到群文件”这个任务可以拆成销售数据分析 Agent查询数据库生成图表和数据结论。内容生成 Agent把结论整理成 PPT 文案。文件生成 Agent调用文档服务生成 PPT。消息推送 Agent把 PPT 上传到企业微信。这就是所谓多 Agent 协作。框架上可以用 LangGraph 或自研的状态机核心是明确每个 Agent 的输入输出以及它们之间的依赖关系。我建议先用“工作流 状态存储”的方式做让每个 Agent 完成后把产物放到共享存储如 Redis/MinIO后续 Agent 再去取。这样比直接让 Agent 之间相互调用更可控。8.3 用大模型做更复杂的中控当前示例中大模型只做了意图识别。进阶玩法是让大模型做“任务拆解”它自己决定要调用哪几个 Agent按什么顺序调用。这需要使用 Function Calling 机制即把系统内所有 Agent 的能力作为“函数”暴露给模型。模型收到用户请求后自己选择调用哪些函数、传什么参数并聚合最终结果。这种方式体验最好但工程复杂度也最高建议在掌握基础调度框架之后再尝试。9. 写在最后用微信等社交软件调度 AI Agent本质上做一个“消息网关 任务调度中心 多 Agent 执行器”的三角结构。微信只是入口真正干活的是调度系统。希望这篇教程能帮你把整条链路串起来。从一个小闭环出发逐步加入异步队列、权限校验、定时调度和多 Agent 协作你的个人项目或团队自动化工具就会越来越像一个正经的“AI 调度平台”。核心代码已经全部给出照着建项目一步步改造成你自己的版本。欢迎在评论区聊聊你的 Agent 调度设计思路或者你在接入企业微信时踩过的坑。