该项目展示了由 Webhook 和消息队列触发的异步智能体架构,通过立即返回 202 避免阻塞调用方。其文件持久化队列、幂等账本、分发器和死信队列设计,可用于构建可恢复的生产级 Agent。
“从零开始学 Agentic AI”系列的第 8 个项目颠覆了常见模式:不再是你向 Agent 输入内容,而是 Agent 在事件发生时醒来——可能是一个 webhook POST,也可能是队列中的一条消息——完成任务后,再次进入休眠状态。没有聊天循环,而且同一个事件绝不会被处理两次。
项目基于免费的 8B 模型构建(通过 NVIDIA NIM 使用 Llama 3.1)。所有基础设施都由确定性的 Python 代码实现,只有决策部分交给模型。
两个真实的事件源,无需任何外部基础设施:
# webhook.py — stdlib http.server, no framework
class WebhookReceiver(BaseHTTPRequestHandler):
def do_POST(self):
body = self.rfile.read(int(self.headers["Content-Length"]))
ev = Event.from_json(body) # id = idempotency key
QUEUE.append(ev) # enqueue, don't block on the model
self._respond(202, {"queued": ev.id})
接收器只负责将事件加入队列——它会立即返回 202 Accepted,绝不会等待 LLM。一个基于文件的仅追加队列(queue.jsonl)充当持久化缓冲区,再由 worker 从中依次取出事件进行处理。
dispatcher 会将事件类型映射到对应的 handler;真正由模型进行推理的地方就在各个 handler 中,例如对订单进行分类处理、对邮件进行分类并起草回复,以及对文件进行总结和路由:
def worker_tick():
ev = QUEUE.claim() # FIFO cursor
if LEDGER.seen(ev.id): # idempotency
return "skip: already processed"
handler = DISPATCH[ev.type]
for attempt in range(1, MAX_TRIES + 1):
try:
out = handler(ev) # <- the one place a model call happens
LEDGER.mark(ev.id); return out
except TransientError:
time.sleep(backoff_delay(attempt)) # bounded exponential
except BusinessReject:
LEDGER.mark(ev.id); return "rejected" # NOT an error — never retry
DLQ.add(ev, last_error) # exhausted → dead-letter
事件 ID 就是幂等键。processed-ledger 会记录每一个已经处理过的 ID,因此事件即使被再次投递,也只会成为一次空操作——不会重复扣款,也不会重复发送邮件。在录制的运行过程中,ord-1001 被投递了两次:一次来自真实的 webhook POST,另一次是重新加入队列。第二次投递命中了 ledger,没有消耗任何模型调用。
临时故障(例如下游返回 503)会使用有上限的指数退避策略进行重试;业务拒绝(例如订单总金额为 $0)不属于错误,因此永远不会重试。尝试 N 次后,如果事件仍然处理失败,就会连同原始 payload 和最后一次错误一起进入 dead-letter queue。这样 worker 可以继续处理后续事件,而不会被一个故障事件卡住。
以下过程使用 NVIDIA NIM(llama-3.1-8b)实时运行并录制:
ord-1001 通过真实的 POST http://127.0.0.1:8808/events 发送 → 返回 202,处理完成。
ord-1001 被再次投递 → 幂等空操作(7 次投递 → ledger 中只有 6 条不同记录)。
eml-2002 的下游连续两次返回 503 → 退避 → 第 3 次尝试处理成功。
ord-1002 的下游始终不可用 → 3 次尝试全部失败 → 进入 dead-letter queue。
ord-1003(总金额为 $0)→ 被业务规则拒绝,没有重试,也没有消耗模型调用。
只有下游的成功或失败是通过脚本预设的(以确保演示可以复现);所有 LLM 调用都是实时进行的。
这个模式的核心是:模型负责决策,但队列、去重 ledger、重试策略和 DLQ 都由普通的确定性代码实现——正因如此,事件驱动的 Agent 才能够在无人值守的情况下安全地持续运行。
仓库中提供了真实运行记录和完整代码(包含注释):
实时演示:https://dev48v.infy.uk/agentic/project8-event-triggered.html
仓库:https://github.com/dev48v/agentic-ai-from-zero
接下来是项目 9:一个多 Agent 辩论系统。
如果需要采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。