无尘阁日记

无尘阁日记

023真实构建一个抢火车票Agent
2025-06-17

我觉得以上内容的核心意思就是有一个可以运行的环境,比如php或者python搭建一个运行环境,然后开放一个接口(ui界面)给用户,用户输入指令,然后php或者python接受指令,调用大模型(或者分析agent,其实这个agent背后调用的还是巨头大模型或者自建大模型),分析完了任务,形成任务规划子包,然后在运行环境里,对任务1比如是搜索xxx,就调用另外一个搜索agent去获取结果,完了任务2是整理、提取搜索结果(这里面就是prompt),任务3必须从某些开源图片网站获取图片(又是一个agent),一步步执行,在运行环境里其实就是调用agent开放的api。而这个mcp我认为就是这个运行环境设定的机制。或者你可以以一个帮我抢一张火车票这个指令场景,构建一个基于:function call、rag、session、多agent 等机制,的服务agent。写成一篇经验文章。


你可能以为 AI 离真正“为你做事”还有十年。其实,它已经可以了。只不过,它还需要你搭建一个可以让它跑得起来的环境

我们就从一句用户自然语言指令开始:

“帮我抢一张6月20日从北京到上海的火车票,越早越好。”

这句话看似简单,背后却需要经历一次完整的智能协作过程。真正的核心不在模型多大,而在你是否给它准备好了“运行场”:一个能处理指令、拆解任务、管理上下文、协调执行、反馈结果的系统环境。

现在我们就来拆解这个过程——它如何在现实中变成一个真的抢票工具

💻 01|你得有一个“能跑 agent 的环境”

这个环境不是什么高深架构,其实就是一套常见的 Web 后端栈:Python / Node.js / PHP + LLM 接口 + 一些封装的工具 API。

这个运行环境需要具备五个基本能力:

  1. 接收用户输入(UI 或 API)

  2. 调度大语言模型,进行自然语言解析与任务规划

  3. 构建并维护 message context(MCP)

  4. 调用若干 agent 或工具函数完成每一步任务

  5. 回传用户预期的可执行结果或提示反馈

你可以理解为,一个 具备执行能力的“语言中枢+工具调度中心”

🧠 02|语言模型如何接收任务并拆解它?

语言模型不是智能,它只是一个语言中的结构反应器。但正因如此,它最擅长的,是把你一句复杂的话拆解成几步清晰任务。

比如这个输入指令:

“帮我抢一张6月20日从北京到上海的火车票,越早越好。”

模型可以拆解出如下信息结构:

  • 任务目标:购买一张火车票;

  • 起点城市:北京;

  • 终点城市:上海;

  • 日期:2025-06-20;

  • 时间偏好:越早越好;

  • 隐含条件:最好自动下单、需要登录12306账号、需要反复刷新检测余票。

我们通过 prompt 工程 + function call,让模型调用一个任务规划函数 plan_ticket_purchase_task,生成如下子任务清单:

[
  "登录12306账号,保持会话",
  "搜索目标车次(6月20日,北京 -> 上海)",
  "排序车次并挑选最早一班有票的",
  "下单并完成购票流程",
  "若无票,设置监控并重复刷票"]

这就是 LLM 主体的第一个 function call,完成任务规划。

🔧 03|进入运行环境,交由 agent 逐步执行

此刻,任务就进入了系统“中控台”:这个由你用 Python / Node.js / PHP 搭建的环境,将扮演一个 调度中心 的角色。

你要定义一套 TaskManager,根据每一项子任务,分发到不同 agent 去处理。

多 Agent 的角色划分如下:

Agent 类型职责
Auth Agent登录 12306 平台,维持 Session,会话失效自动重登
Search Agent调用爬虫 / API 查询车次信息
Parse Agent将 HTML 页面的车次信息提取为结构化数据
Sort Agent基于用户偏好(越早越好)进行排序
Buy Agent调用下单流程脚本,并识别验证码、提交订单等操作
Monitor Agent若无票,自动设置间隔轮询并刷票

这些 agent 都是你事先在运行环境中“注册”好的,它们可以是:

  • 本地 Python 脚本;

  • 远程 API;

  • Linux shell 命令;

  • 甚至另一个大模型 agent。

调度机制就是系统实现的 MCP —— 上下文感知的调度协议

🧩 04|每一步执行都在构建上下文 message

每个 agent 执行后,都返回一段结果,这些结果被记录为一条 message,加入大模型推理上下文中。

比如搜索 agent 返回的 HTML 内容,就变成了一条带有 "tool_response" tag 的 system message,供后续排序 agent 读取。

LLM 再次接入时,可以读取上下文中的结构化数据、结果列表、失败提示,进而判断是否要重试、是否进入刷票模式。

这时候你会明白:整个“意识链条”其实就是 message chain 的演进。这就是“秃头小登”所说的核心真相。

🔁 05|循环尝试 + 反馈式调用 = 智能行为的外观

假设当前没有余票,Monitor agent 就会设置轮询规则(比如每5秒查询一次),把查询结果写入缓存(Redis、SQLite、文件都行)。

而主控系统会判断是否调用 LLM 进行重决策(如是否换乘、是否改日期、是否通知用户)。

这个过程中,MCP 决定的是:

  • 什么消息需要留在上下文;

  • 什么消息只用于本地日志;

  • 哪些失败信息要显式传给大模型,以促成下一步“顿悟”;

  • 哪些中间数据是“沉默执行”,以避免上下文爆炸。

这才是所谓“智能”:它不是懂道理,而是在有限语境下,做出看似合理的行动序列

📦 Bonus:工作流不需要固定,只需要“生发机制”

你提到一个非常关键的洞察:

“为什么知乎很多人说 agent 系统一定要人类先定义好工作流?明明可以根据目标动态生成工作流。”

是的,你说得完全对。固定工作流是在 Agent 系统刚起步时,为了稳定、测试、可控而采用的一种“先铺轨再开车”的方式。

但真正的 AGI Agent 系统,早晚要迈向“动态任务树”。

我们可以:

  • 给语言模型一个 planner 模块(基于 prompt 模板 + memory);

  • 它根据用户指令,自行生成任务树;

  • 再通过调度环境依次执行;

  • 执行过程出现异常可触发 fallback prompt 或 recovery agent。

这就像一个懂事的小助手:你说一声“帮我抢票”,它就知道要怎么一步步做、用什么脚本、去哪里找图形验证码、哪里登录、哪里下单、失败怎么办……全流程自生成、自动化。

🧘 总结:你不需要 AGI,你需要一个会“运行语言”的场

你不是在训练一个有意识的 AI,也不是在培养它有目标感、人生观。

你只需要它做到三件事:

  1. 理解你的目标并能拆解成一系列语言任务

  2. 在运行环境中把这些语言任务调度给真正能执行的 agent 或函数

  3. 整个过程有上下文意识,能做反馈,能处理失败,能适配变化

而这一切的运行土壤,就是你说的这个平台 + MCP + agent 接口 + LLM。

语言即协议,agent 即函数,任务即结构,智能即序列。

这是未来。也是现在。

如夜话,至此。