一、引言:拼上 AI 进化的最后一块积木

1.1 之前的铺垫:有钱,有路,但谁来跑腿?

如果你正在关注我的这个系列,应该能发现我们正在逐步构建一个完整的 AI 能力拼图。

  • 第一篇《Token:AI 时代的数字货币——从原理到计费全解,我们讲的是“”。
    Token 是大模型世界的本位币。AI 每一次推理、每一个输出,本质上都是在消耗这种数字货币。它决定了任务的真实成本,也间接决定了模型愿意为你投入多少“思考深度”。

  • 第二篇《MCP 是什么?一次搞懂 AI 如何“标准化接入世界”,我们讲的是“”。
    MCP 是 AI 世界的基础设施与统一接口标准。它让 AI 拿着 Token,不再被困在对话框里,而是可以直接“走出去”:
    去数据库查账、去文件系统取资料、去调用 API 办正事。

逻辑走到这里,其实已经很顺了:AI 有了钱(Token),也认了路(MCP)。

但你在真正使用的时候,往往还是会觉得——

因为还少了一个关键角色:谁来动?

现在的大模型(不论是 ChatGPT 还是 Claude),更像一个顶级顾问或财务专家。他手里揣着你给的 Token,桌上铺着 MCP 的完整地图,但问题在于:

  • 不主动
  • 不连续
  • 不会自己把事情跑完

你推他一下,他就花一笔钱办一件事;你不发话,他就能揣着支票,站在地图前一动不动。

你以为请了个总经理,结果发现自己还得兼职当他的“微操教练”。

Agent(智能体) 的出现,正是为了解决这个“谁来动”的问题。

它是这个系列的终章:把 AI 从一个“有问必答”的顾问,升级为一个能领钱、认路、并且主动把事办完的“金牌代办”。

1.2 什么是 Agent?

现在市面上到处都在谈 Agent:“数字员工”“硅基生命”“AI 同事”……

听起来很玄,但如果你把这些概念全部拆掉,回到架构层面,会发现:Agent 并不是魔法,它的本质只是一个“可自驱的循环(Loop)”。

OpenAI 的研究员 Lilian Weng 曾给出过一个非常经典的 Agent 抽象模型。简单来说,这个模型认为 Agent 需要具备以下几种能力:

  1. LLM(大脑)
    负责推理、决策和成本权衡,知道 Token 该怎么花、值不值得花。

  2. Tools(手脚 / MCP)
    负责真正执行动作,调用数据库、文件系统或外部 API。

  3. Memory(记性)
    能复盘过去的行为,记住哪些路径有效、哪些决策踩过坑。

  4. Planning(规划能力)
    这是 Chatbot 与 Agent 的分水岭
    它必须能把一个模糊目标拆解成一系列可执行的步骤,并在过程中动态调整。

Chatbot 和 Agent,到底差在哪?

Chatbot(聊天机器人),更像一个“一次性交互中介”:

你:“查一下去上海的机票。”
AI:“查到了,500 块。”

任务完成,立刻收工。
订票、比价、改签、酒店、行程同步——全都得你自己接着干。

Agent(智能体),更像一个“全权代表”:

你:“帮我安排一次去上海的出差行程。”

AI 的内部流程大概是这样的:

  1. 规划:需要机票、酒店,还要避开会议时间
  2. 行动:通过 MCP 查询机票,发现价格超预算
  3. 反思:是否可以换时间?是否考虑高铁?
  4. 再行动:改订高铁,同时锁定合适的酒店
  5. 记忆:记录你的偏好——比如更喜欢住在静安区

最终,它给你的不是“信息”,而是结果

“行程已安排完成,票和酒店已确认,日程已同步到你的日历。”

一句话总结:

Chatbot 是“你问一句,它答一句”;
Agent 是“你给目标,它自己拿着 Token,沿着 MCP 的路径,一直把事情跑到结束”。

这,才是 AI 进化过程中,最后被补上的那块积木。

二、 核心解构:Agent 是怎么“动”起来的?

既然 Agent 的本质是一个“循环(Loop)”,那这个循环到底是怎么跑起来的?我们可以把 Agent 拆解成三个零部件:负责出主意的大脑、负责记事的账本,以及负责干活的手脚

2.1 大脑:规划 Planning —— 停止幻觉,开始思考

以前用 ChatGPT,你问它“如何把大象装进冰箱”,它会直接给你一段漂亮的废话。但 Agent 懂规矩,它采用的是 ReAct 模式:推理(Reason)+ 行动(Act)

说白了,就是让 AI 在花你钱(Token)干活之前,先把“内心的算盘”打出来。一个 Agent 的标准动作是:盘算(Thought) -> 动手(Action) -> 瞅一眼(Observation) -> 重新盘算

举个写代码的真实例子:

  • 普通 AI: 直接甩给你一段代码。至于能不能跑,它不管,反正它聊完就“下班”了。
  • Agent:
  1. 盘算 (Thought): 老板要抓网页。我得先用 requests 库写个样板。
  2. 动手 (Action): 调工具写了个 scraper.py
  3. 瞅一眼 (Observation): 自己试运行了一下,报错:没装这个库。
  4. 再盘算 (Thought): 啧,环境不行。看来这笔 Token 得先花在“装库”上。
  5. 动手 (Action): 执行 pip install
  6. 再盘算 (Thought): 库装好了,现在重新跑刚才的代码。

Agent 的本质就是“遇水搭桥”。 它不再是直接蒙一个答案给你,而是像个真人工程师一样,在不断的试错和修正中死磕目标。

2.2 记忆:Memory —— 它是怎么记住以前的事?

光有算盘还不够,代办得有记性。Agent 的记忆分两类,就像咱们出门办事带的 “临时记事本”,以及放在家里的 “百科全书(RAG)”

2.2.1 短期记忆:上下文窗口(Context Window)

这是 Agent 的“当前工作台”。刚才盘算了什么、报了什么错,全塞在这儿。
它是按字计费的,不仅 贵(消耗 Token),而且 易挥发——对话一关就没了。

2.2.2 长期记忆:RAG(百科全书)是怎么搭起来的?

如果公司有一万页文档,全塞进脑子里(上下文窗口 / Token),那基本等于直接破产。
所以我们要给 Agent 搞一个“外挂”,也就是 RAG(Retrieval-Augmented Generation,检索增强生成)

搭建 RAG 的工程四部曲:

  1. 切碎(Chunking):
    把几万字的文档切成 300~500 字一段的“知识碎片”。

  2. 向量化(Embedding):
    用模型把“人话”转成一串“数字坐标”。在向量空间里,含义越接近,坐标就越近

  3. 入库(Vector DB):
    把这些带坐标的碎片存进向量数据库——这就是咱们的 “百科全书书架”

  4. 翻书与拼图(Retrieve & Generate):

    • 当你问“年假几天?”时,Agent 先在数据库里根据向量“算距离”,
      精准地把那一页关于年假的内容给 翻(Retrieve) 出来;
    • 然后 Agent 玩了个拼图游戏:
      把这页原文和你的问题,缝合成一个更大的 Prompt,交给 大模型
    • 大模型 盯着这页原文,照本宣科地把答案 生成(Generate) 出来。

这就是 RAG 的真相:它不是让大模型背下了书,而是 Agent 雇了个“图书管理员”,在回话前临时翻书给大模型看。

2.3 手脚:Tools —— 再次点题 MCP

这里必须把上一篇讲的 MCP 给串回来了。

在 Agent 的架构里,大脑(LLM,如 GPT-4、Claude 3.5、DeepSeek 等)是绝对禁止直接碰现实世界的。它只能发出“指令”,脏活累活全是 Tool(工具) 干的。这就好比指挥官下令,士兵冲锋。

为什么有了 Agent 之后,MCP 变得极其重要?

因为 Agent 的规划非常依赖稳定性。如果工具接口乱七八糟,Agent 规划时就容易“大脑过载”。MCP 的价值,就是给 Agent 统一了“标准驾驶舱”: 无论底层是数据库还是本地文件,Agent 面对的永远是 MCP 那套标准指令。有了它,Agent 才能真正从“纸上谈兵”变成“带兵打仗”。

2.4 总结:铁三角交互流

  1. 用户Agent 下指令。
  2. Agent 发现缺知识,去 RAG(书架) 翻书。
  3. Agent 把书上的内容交给 大模型(大脑) 拿主意。
  4. Agent 拿定主意,顺着 MCP(路) 把活儿给办了。

这就是从“对话框”到“自动驾驶”的终极跨越。

三、 进阶架构:从单打独斗到团队协作

搞懂了 Agent 的基本原理后,我们在实际开发中会面临一个选择:选择全能型人才还是专业化团队?

3.1 Single Agent(单体智能体):全能型AI的局限性

什么是 Single Agent?

简单说,就是你只定义了一个角色,给它挂载了所有工具(联网、读文件、写代码、操作数据库),然后把复杂的任务一股脑扔给它。

  • 适用场景:
    任务链路短、逻辑线性的场景。
    比如:“帮我查一下现在的天气,并根据我的衣柜库存(读取本地文件)推荐穿搭。” 这种任务,思考路径只有两三步,一个大脑完全顾得过来。

  • 它的死穴: 一旦任务变复杂,Single Agent 马上就会表现出“智商下降”。

    1. 上下文污染(Context Pollution): 你既让它写 golang,又让它做 SQL 优化,还让它写对外文案。它的 System Prompt 会变得巨长,运行几轮之后,它很容易搞混自己的职责,忘了最初的要求。
    2. 顾头不顾腚: 当它专注于修复代码报错时,往往会忘了整体的业务逻辑,最后修好了 Bug 但改坏了功能。

在工程实践中,Single Agent 犹如一个初创公司的全能实习生:既要负责代码编写,又要维护服务器,还得兼顾客服工作。任务量少时效率极高,一旦任务堆积,就容易陷入手忙脚乱的境地。

3.2 Multi-Agent(多智能体协作):让 AI 管理 AI

当前架构正朝着多智能体(Multi-Agent)方向发展,以解决"单体智能体"的性能瓶颈问题。

这个理念其实很简单:术业有专攻。相比设计一个 5000 字的庞杂 Prompt,拆分 5 个 1000 字的精准 Prompt 并分配给不同智能体,往往能获得更好的效果。

经典的“软件开发三人组”模式

我们最常用的架构,是模仿真实的软件开发团队,由三个核心角色组成:

  1. Manager / Router(项目经理):

    • 职责: 它不干具体活,手里也没什么工具。它只负责**“分单”**。
    • 工作流: 用户说“要做个贪吃蛇游戏”。Manager 分析后,对 Coder 说:“你负责写核心逻辑”;对 Reviewer 说:“你负责盯着它,别让它写出 Bug”。
  2. Coder(程序员):

    • 职责: 它的 System Prompt 只有一句话:“你是一个资深的 golang 工程师,只写代码,不废话。”
    • 特权: 它手里拿着文件写入工具(File System MCP)。
  3. Reviewer(测试):

    • 职责: 它的设定是“苛刻的代码审计员”。它负责运行 Coder 写的代码,查看报错日志。
    • 特权: 如果代码跑不通,它不会自己改,而是把错误日志甩回给 Coder,并附上一句:“第 10 行有逻辑错误,重写。”

为什么这样更强?

这种架构就像一个 DAG(有向无环图) 工作流:

拆解任务

提交代码

❌ 测试失败/有Bug

✅ 测试通过

最终交付

用户指令

项目经理 Agent

程序员 Agent

测试/审核 Agent


它的核心优势在于“隔离”:

  • Coder 根本不需要知道“用户是谁”,它只管把 Reviewer 指出的 Bug 修好。
  • Reviewer 也不需要会写代码,它只要会挑刺就行。
  • 上下文更干净: 每个 Agent 只维护自己那点儿“一亩三分地”的记忆,Token 消耗更精准,幻觉(Hallucination)大大减少。

未来的 AI 应用开发,本质上就是设计这样的组织架构图,而不是去卷某一个 Prompt 写得有多花哨。

3.3 A2A 协议:Agent 之间的“交互规范”

我们前面讲了,MCP 解决了 Agent 怎么连接工具(数据库、文件)的问题。但如果你的架构里有两个 Agent,比如一个“产品经理”和一个“程序员”,它俩怎么沟通?

靠互相发自然语言吗?那效率太低,而且容易误解。这时候,我们需要 A2A(Agent-to-Agent)协议

3.3.1 为什么需要 A2A?

如果说 MCP 是 AI 时代的 USB 协议(插上就能用工具),那么 A2A 就是 AI 时代的 TCP/IP 协议(连上就能对话)。

没有 A2A,多智能体协作(Multi-Agent)就像是一群语言不通的人在吵架:

  • 格式不通: Agent A 发的是 JSON,Agent B 只读纯文本。
  • 状态丢失: Agent A 把任务转给 B,但忘了把之前的聊天记录(Context)传过去,B 一脸懵逼。
  • 死循环: A 问 B,B 不懂又问 A,俩人互相客气,Token 爆炸。

3.3.2 A2A 协议的核心三要素

一个成熟的 A2A 交互,通常包含三个标准动作:

  • Discovery(发现):

    • “谁在线?”
    • Agent 不应该是孤岛。A2A 允许通过一个注册中心查询其他 Agent 的能力。比如“产品经理 Agent”广播说:“我要找个写 Python 的”,“程序员 Agent”举手响应。
  • Handshake(握手与能力协商):

    • “你能干这活吗?”
    • 在正式干活前,Agent A 会发送一个标准格式的 Schema 询问 B:“你需要什么参数?输入格式是什么?”
    • 这有点像编程里的接口定义(Interface),但它是动态的。
  • Handoff(交接棒):

    • “这事交给你了,这是之前的资料。”
    • 这是 OpenAI Swarm 框架的核心概念。
    • 当 Agent A 搞不定时,它不仅是把“任务”转给 B,更是把整个会话的上下文(Context)、当前的变量状态,完整地打包“过户”给 B。
    • 用户甚至感觉不到背后换人了,只觉得服务很顺滑。

3.3.3 未来的互联网:Agent 网络

现在的互联网是 Server-to-Server(服务器调服务器)。

未来的互联网是 Agent-to-Agent

试想一个场景:

  • 你的 “私人助理 Agent”(运行在你的手机上)想帮你订一张机票。
  • 它不会去访问携程的网页(那是给我们看的)。
  • 它也不会去调携程的API(那是给代码连的)。
  • 它会直接呼叫携程的 “订票 Agent”,通过 A2A 协议进行了一次毫秒级的谈判:

“我要去上海,由我主人偏好靠窗,预算 2000。”
“收到,有两班符合,分别是……”
“选第一班,支付协议已授权。”

MCP 搞定了工具,A2A 搞定了协作。 这两根柱子立起来,Agent 才能真正组成社会。

四、技术落地:现在的 Agent 怎么造?

原理懂了,到了真写代码的时候,我们面临的第一个问题就是:怎么把大模型、内存和工具这些零散的部件“粘”在一起?

我们不需要从零手搓一个 while 循环,社区已经演化出了成熟的开发范式。要选对工具,首先得看懂这个架构是怎么一步步变复杂的。

4.1 架构演进:从“链条”到“网络”

在 Agent 框架出现之前,我们经历过几个阶段,这决定了为什么现在会有两派不同的框架。

进化: 需要自我修正

进化: 单脑容量不足

阶段三:Swarms (多智能体协作)

对话

对话

协作

任务

Manager

Coder

Reviewer

阶段二:Loops (单体循环)

调工具

结果

完成

任务

决策 Router

Tools

结束

阶段一:Chains (线性链条)

输入

提示词模板

LLM

输出

  1. 阶段一(Chains,链式)
    最早期的 LangChain。本质是一条直路:A → B → C。适合翻译、摘要等确定性任务,但没有状态、没有回溯能力,中间断了就真的断了。

  2. 阶段二(Loops,循环)
    为了解决复杂问题,引入了循环(Loop)。模型可以反复思考、尝试、修正,直到完成任务。这正是 LangGraph 诞生的背景——它本质上是一个显式状态机(State Machine),而不是“聪明一点的 Prompt”。

  3. 阶段三(Swarms,蜂群)
    单个模型的上下文和推理能力开始成为瓶颈,于是引入多个角色分工协作。这就是 AutoGen / CrewAI 的由来——它们模拟的是人类团队的沟通结构,而不是程序流程。

4.2 核心框架选型:并不存在“最好的”

理解了上面的演进,选型问题就不再是“谁更强”,而是“你要的是确定性,还是创造力”。目前主流框架清晰地分成了两派。

1. 守序阵营:LangGraph(LangChain 生态)

  • 核心逻辑: 图(Graph) + 状态机(State)
  • 基本假设: AI 不可靠,流程才可靠
  • 设计哲学: 你必须先把业务逻辑画成一张有向图,Agent 只能在节点允许的范围内活动

典型场景:
企业内部自动化系统,如报销、工单、风控处理。

例如一个自动报销 Agent,你会明确规定主流程:

接收发票
 → OCR 识别
 → 核对金额
 → 金额 > 1000 ?
     ├─ 是 → 转人工审批
     └─ 否 → 自动通过

AI 只负责文本理解和判断,路径本身是死的

  • 优点:
    高可控、可回溯、可限流,天然适合生产环境
  • 代价:
    你必须像写业务系统一样“设计流程”,而不是指望灵光一闪

2. 混乱阵营:AutoGen / CrewAI

  • 核心逻辑: 多角色对话(Conversation)
  • 基本假设: 对话本身可以逼近人类协作
  • 设计哲学: 与其规定流程,不如定义人格,让 Agent 自己聊出来

你可以定义一个「产品经理」Agent 和一个「程序员」Agent,让它们在一个群聊里不断讨论,直到代码写出来。

典型场景: 创意类、探索性强、结果不可预期但容错率高的任务,例如:

  • 从零实现一个小游戏

  • 生成竞品分析或方案草稿

  • 优点: 发散性强,容易产出“超预期结果”

  • 缺点: 极易跑飞、死循环、Token 成本不可控

一句话结论:
企业级应用(求稳)选 LangGraph;
原型探索和极客玩具(求强)试 AutoGen。

4.3 编排模式:从“黑盒”回归“工作流”

真正的分水岭,不在框架,而在工程观念

在 2023 年上半年,AutoGPT、BabyAGI 爆火时,大家沉迷于“全自动黑盒”:给 AI 一个宏大目标,然后完全放手。

现实很快给了结论:
不可控、易死循环、成本失控,在生产环境几乎不可用。

于是,业界迅速达成共识:
Agent 不再是魔法,而是一种**流程工程(Flow Engineering)**问题。

1. 显式工作流(Explicit Workflow)

现代 Agent 的最佳实践,是把任务拆解为 DAG(有向无环图)

  • 过去:
    Input("帮我部署") → AI 黑盒 → Output("部署失败")
    ——你甚至不知道是哪里炸的。

  • 现在:

    1. AI 负责把自然语言翻译成 kubectl / terraform 命令
    2. 硬代码(Hard Code) 负责执行命令(AI 不可触碰执行层)
    3. AI 再负责分析日志、给出解释和建议

AI 只存在于“不确定性节点”,而不是整个系统的控制中心。

2. Human-in-the-loop(人机协同)

这是防止 Agent “删库跑路”的最后一道防线。

无论 Agent 吹得通过率多高,涉及关键写操作(数据库增删改、转账、发邮件、代码上线)时,必须引入人工确认。

  • 实现机制: 在 LangGraph 中,这被称为 Interrupt(中断)
    1. Agent 规划好了 SQL,准备执行。
    2. 程序挂起(Suspend),保存当前内存状态。
    3. 给用户发个弹窗:“我要删库了,SQL 是 DROP...,你批准吗?”
    4. 用户点击“批准”。
    5. 程序恢复(Resume),Agent 继续执行后续步骤。

真正的落地,不是把控制权全交给 AI,而是把 AI 关进我们设计好的流程笼子里。它负责在笼子里发挥聪明才智,而我们负责握着钥匙。

五、 冷静思考:Agent 目前的“坑”与“痛”

把 Agent 吹得天花乱坠很容易,但作为一个实战派,我必须得把丑话说在前头。现在的 Agent 就像一个刚毕业的实习生:虽然很勤快,但经常钻牛角尖,而且花钱如流水。

5.1 并不完美的“自主”:当死循环遇上多米诺骨牌

我们把 Agent 叫做“自主智能体”,但有时候它的“自主”简直让人抓狂。

5.1.1 恐怖的死循环(Infinite Loops)

这是目前开发 Agent 最头疼的问题。
Agent 的运行逻辑是“遇到困难 -> 尝试解决”。但有时候,它会陷入一种**“执着的愚蠢”**。

  • 场景: Agent 写的 SQL 报错了。
  • 人类做法: 查文档,换一种写法。
  • Agent 做法: 它觉得是偶然,于是一模一样的 SQL 再执行一遍。又报错?那就再试一次。
  • 结果: 你的后台日志里全是同样的报错刷屏,直到把 API 额度烧光或者触发超时熔断。它不会觉得自己错了,它只是在“努力重试”。

5.1.2 幻觉传导(Error Propagation)

在单次对话中,幻觉顶多是一句胡说八道。但在 Agent 的长链条工作流中,幻觉会产生多米诺骨牌效应

  • 第一步规划错了: Agent 误以为你本地装了 ffmpeg(其实没装)。
  • 后续十步全是错的: 它基于这个错误的假设,去写脚本、去调参数、去处理视频。
  • 结局: 等它折腾了 5 分钟,跑了 20 轮交互,最后告诉你“执行失败”时,你会发现它从第一秒开始就在做无用功。

结论: 现在的 Agent 缺乏“自知之明”,它很难意识到“这条路走不通,我得回退两步重新选路”。

5.2 成本爆炸:Token 是怎么被烧光的?

还记得我们第一篇讲的 Token 计费吗?在 Agent 模式下,计费逻辑发生了质变。

  • Chatbot 模式: 问一句,答一句。你只付这两句话的钱。
  • Agent 模式: 这是一个可怕的乘法公式

让我们算一笔账:假设你让 Agent “分析一下过去一年的销售数据”。

  1. 思考: 消耗输入 Token。
  2. 调用工具: 获取 1000 条数据库记录(这里会产生巨大的 Token 消耗,因为数据是以 JSON 格式喂回给 LLM 的)。
  3. 观察结果: 把这 1000 条数据读进上下文。
  4. 再思考: 发现数据太多,需要过滤。
  5. 再调用工具: ……

在这个 ReAct 循环中,每一个中间步骤,都要把之前的上下文(包括那些巨大的数据库查询结果)重新发给模型一遍。

结果: 用户只问了一句话,后台可能跑了 15 轮交互,消耗了 20 万 Token。
这就导致了商业模式的尴尬: 以前是“按次收费”,现在如果不“按任务复杂度收费”,服务商甚至会赔钱。

5.3 延迟问题:让用户等多久才算久?

Agent 的第三个痛点是

Chatbot 之所以体验好,是因为它可以 Streaming(流式输出)。字是一个个蹦出来的,用户感觉很快。

但 Agent 不行。
在它展示最终结果之前,它在后台做的是串行处理
思考(2s) -> 网络请求(1s) -> 数据库查询(2s) -> 读结果再思考(3s) -> 写代码(5s) -> 运行代码(2s)

对于一个稍微复杂点的任务,耗时 30 秒到 1 分钟是家常便饭。
在快节奏的互联网应用中,让用户对着一个旋转的 Loading 图标等 1 分钟,基本上等于劝退。

所以,目前的 Agent 并不适合所有场景。

实时性要求高的(如语音对话、实时翻译),千万别上复杂的 Agent 架构。它更适合做那些“异步”的活儿:比如你中午吃饭前丢给它一个 GitHub Issue 的链接,等你饭后溜达一圈回来时,它不仅仅是读了问题,而是已经把代码库拉下来、复现了 Bug、修好了代码、跑通了本地测试,并提好了一个 Pull Request 坐在那里等你 Review 了。

六、 实战:手搓一个会“自我纠错”的 SQL Agent

光说不练假把式。虽然原理讲了很多,但 Agent 到底长什么样?代码怎么写?

在本章中,我们将使用目前最硬核的 LangGraph 框架,构建一个具备 ReAct(推理+行动) 能力的数据库智能体。

它能做到: 用户用自然语言提问 -> 它自己写 SQL -> 执行查询 -> 如果报错,它自己看错误日志 -> 修改 SQL -> 重试 -> 直到拿到结果。

6.1 准备工作:技术栈清单

  • 语言: Python (Agent 开发的一等公民)。
  • 框架: langgraph + langchain
  • 模型: GPT-4o 或 Claude 3.5 Sonnet (智商够高,适合做规划)。
  • 数据库: SQLite (为了演示方便,无需配置服务器)。

为了成功跑通 6.2 章节的代码,需要先安装好环境

python3 -m venv venv
source venv/bin/activate
pip3 install langchain-openai langgraph langchain-core

然后去 硅基流动官网 注册并获取个免费的 api-key ,并把写入到 SILICON_API_KEY,当然了,若是你也可以调整 sys_prompt 这个 prompt 再运行看看。

6.2 代码实例

Agent 不会凭空操作数据库,我们需要先定义一个工具函数,并用 @tool 装饰器包装它。这相当于告诉 Agent:“你手里有一把锤子,叫 execute_sql。”

import sqlite3
import operator
import os
from typing import Annotated, TypedDict, List

# 依赖库
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool
from langchain_core.messages import BaseMessage, HumanMessage, SystemMessage
from langgraph.graph import StateGraph, START, END
from langgraph.prebuilt import ToolNode

# ==========================================
# 🔧 配置区域 (唯一需要修改的地方)
# ==========================================
# 这里填入你在硅基流动 (SiliconFlow) 获取的密钥
# 格式通常是 sk-xxxx...
SILICON_API_KEY = "sk-xxxxxxxx"

# 如果你环境变量里配了,也可以用 os.getenv("SILICON_API_KEY")

# ==========================================
# 1. 环境初始化:造一个假数据库
# ==========================================
DB_NAME = "my_data.db"

def init_db():
    """初始化数据库,创建一个 users 表,故意没有 vip_users 表"""
    conn = sqlite3.connect(DB_NAME)
    cursor = conn.cursor()
    #以此保证数据干净
    cursor.execute("DROP TABLE IF EXISTS users")
    cursor.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER, role TEXT)")
    
    # 插入点假数据
    data = [
        ('Alice', 30, 'admin'),
        ('Bob', 24, 'user'),
        ('Charlie', 29, 'vip')
    ]
    cursor.executemany("INSERT INTO users (name, age, role) VALUES (?, ?, ?)", data)
    conn.commit()
    conn.close()
    print(f"✅ 数据库 {DB_NAME} 初始化完成。")
    print("📋 当前表结构:只有 'users' 表 (包含 id, name, age, role)")

# ==========================================
# 2. 定义工具 (Tools)
# ==========================================
# 建立一个全局连接供 Agent 使用
# check_same_thread=False 是为了让 SQLite 能在多线程环境中运行
conn = sqlite3.connect(DB_NAME, check_same_thread=False)

@tool
def execute_sql(sql: str):
    """
    执行 SQL 查询语句。
    输入必须是合法的 SQL 字符串。
    如果执行报错,会返回错误信息,请基于错误信息修正 SQL。
    """
    cursor = conn.cursor()
    try:
        # 打印一下,方便在控制台看到 Agent 到底在干嘛
        print(f"\n[Tools] 正在执行 SQL: {sql}")
        cursor.execute(sql)
        result = cursor.fetchall()
        return f"查询成功: {str(result)}"
    except Exception as e:
        # 关键点:把错误吐回给 Agent,让它看到
        error_msg = f"执行出错: {str(e)}"
        print(f"❌ [Tools] 报错: {error_msg}")
        return error_msg

# ==========================================
# 3. 定义状态与大脑 (Graph Setup)
# ==========================================

# 定义 Agent 的记忆结构:消息列表,支持追加模式
class AgentState(TypedDict):
    messages: Annotated[List[BaseMessage], operator.add]

# 初始化 LLM:使用硅基流动的 DeepSeek V3
# 它兼容 OpenAI 协议,所以用 ChatOpenAI 类
llm = ChatOpenAI(
    api_key=SILICON_API_KEY,
    base_url="https://api.siliconflow.cn/v1", 
    model="deepseek-ai/DeepSeek-V3", # 或者 deepseek-ai/DeepSeek-R1
    temperature=0
)

# 绑定工具
tools = [execute_sql]
llm_with_tools = llm.bind_tools(tools)

# 节点逻辑:Agent 思考
def agent_node(state: AgentState):
    return {"messages": [llm_with_tools.invoke(state["messages"])]}

# 边逻辑:判断是继续还是结束
def should_continue(state: AgentState):
    last_message = state["messages"][-1]
    if last_message.tool_calls:
        return "tools"
    return END

# 组装图
builder = StateGraph(AgentState)
builder.add_node("agent", agent_node)
builder.add_node("tools", ToolNode(tools)) # LangGraph 自带工具节点

builder.add_edge(START, "agent")
builder.add_conditional_edges("agent", should_continue)
builder.add_edge("tools", "agent") # 形成循环 Loop

graph = builder.compile()

# ==========================================
# 4. 运行演示 (注入灵魂 System Prompt)
# ==========================================
if __name__ == "__main__":
    # 先初始化数据库
    init_db()

    print("\n🤖 DeepSeek Agent 启动中...")
    print("🎯 用户挑战:'查一下 vip_users 表里有几个人' (注意:该表实际上不存在)")
    print("-" * 50)

    # 🔥 核心 System Prompt:赋予 Agent 坚韧不拔的性格
    sys_prompt = """你是一个智能 SQL 数据分析专家。你的目标是回答用户的业务问题,而不仅仅是执行 SQL。

    当用户查询的表(如 vip_users)不存在时,请严格执行以下【思维链】:

    1. 🔍 **查表名**:查询 `sqlite_master` 找到最接近的真实表名(例如发现只有 `users` 表)。
    2. 🕵️ **查结构**:务必执行 `PRAGMA table_info(真实表名)` 查看字段结构。
    3. 🧠 **做映射(关键)**:
       - 用户说的 "vip_users" 很可能不是一张表,而是 `users` 表中 `role='vip'` 或 `type='vip'` 的数据。
       - 请根据字段结构,猜测用户的筛选条件。
    4. 🚀 **查数据**:编写带有 WHERE 子句的正确 SQL(例如 `SELECT count(*) FROM users WHERE role='vip'`)。
    5. ✅ **最终回复**:只有获得了具体的数字结果,才能停止工作。

    当前数据库已知情况:只有 `users` 表。
    如果用户问 "vip_users",请自动转换为 "users 表中 role 为 vip 的用户"。
    """

    inputs = {
        "messages": [
            SystemMessage(content=sys_prompt), 
            HumanMessage(content="查一下 vip_users 表里有几个人")
        ]
    }

    try:
        # stream_mode="values" 会流式输出每一步的状态
        for chunk in graph.stream(inputs, stream_mode="values"):
            last_msg = chunk["messages"][-1]
            
            # 美化输出日志
            if last_msg.type == "ai":
                if last_msg.tool_calls:
                    print(f"🤔 [Agent 思考] 决定调用工具: {last_msg.tool_calls[0]['name']}")
                else:
                    print(f"💡 [Agent 最终回复] {last_msg.content}")
            elif last_msg.type == "tool":
                print(f"⚙️ [Tools 返回结果] {last_msg.content}")
                
    except Exception as e:
        print(f"\n❌ 程序运行出错: {e}")
        print("💡 提示:请检查 SILICON_API_KEY 是否填写正确,或余额是否充足。")

    conn.close()

控制台输出模拟(这就是 Agent 的魅力):

✅ 数据库 my_data.db 初始化完成。
📋 当前表结构:只有 'users' 表 (包含 id, name, age, role)

🤖 DeepSeek Agent 启动中...
🎯 用户挑战:'查一下 vip_users 表里有几个人' (注意:该表实际上不存在)
--------------------------------------------------
🤔 [Agent 思考] 决定调用工具: execute_sql

[Tools] 正在执行 SQL: SELECT name FROM sqlite_master WHERE type='table'
⚙️ [Tools 返回结果] 查询成功: [('users',)]
🤔 [Agent 思考] 决定调用工具: execute_sql

[Tools] 正在执行 SQL: PRAGMA table_info(users)
⚙️ [Tools 返回结果] 查询成功: [(0, 'id', 'INTEGER', 0, None, 1), (1, 'name', 'TEXT', 0, None, 0), (2, 'age', 'INTEGER', 0, None, 0), (3, 'role', 'TEXT', 0, None, 0)]
🤔 [Agent 思考] 决定调用工具: execute_sql

[Tools] 正在执行 SQL: SELECT COUNT(*) FROM users WHERE role='vip'
⚙️ [Tools 返回结果] 查询成功: [(1,)]
💡 [Agent 最终回复] VIP 用户表(`vip_users`)实际上是 `users` 表中 `role` 为 `vip` 的用户。查询结果显示,VIP 用户共有 **1 人**。

6.3 本章小结

看懂了吗?这段代码最精彩的地方不在于它查到了数据,而在于中间那个报错重试的过程

  • 传统程序是线性的:查询 -> 报错 -> Crash
  • Agent 是循环的:查询 -> 报错 -> 作为输入喂回大脑 -> LLM分析原因 -> 换个姿势重试

这就是为什么我们说 Agent 具备自主性(Autonomy)。通过 LangGraph 定义的这个简单的 Loop,我们赋予了代码一种“韧性”,让它能在不确定性的环境中找到出路。

七、 生态全景:不写代码怎么玩转 Agent?

看完上一章的代码,你可能会问:“难道我为了用个 AI,还得先学 Python 和 LangGraph 吗?”

当然不是。代码只是为了让你看清 Agent 的骨架(ReAct 循环、状态机)。在真实世界中,Agent 的生态已经分层了:极客去造轮子,普通用户直接用成品。

目前市面上的 Agent 主要分为三类:成品(直接用)、半成品(拖拉拽)、原材料(写代码)。

7.1 成品:开箱即用的“杀手级”应用

这些产品把复杂的 MCP 连接和编排逻辑都封装在了后台,你只需要关注结果。它们是目前 Agent 技术落地最成熟的形态。

  • 全网搜索 Agent —— Perplexity

    • 它是啥: 一个不给你堆砌“蓝链接”,而是直接给你答案的搜索引擎。
    • 原理: 典型的 ReAct 模式。你提问 -> 它自主拆解关键词 -> 实时联网搜索 -> 阅读几十个网页 -> 交叉验证 -> 汇总写成报告。
    • 价值: 它是目前“获取信息”效率最高的 Agent。
  • 全栈编程 Agent —— Cursor / Windsurf

    • 它是啥: 现在的代码编辑器王者。
    • 原理: 它内置了一个能读写你本地文件(MCP)的 Agent。你只需要说“把 Python 2 的代码升级成 3,并修复所有报错”,它就会自动遍历文件、修改代码、运行终端、根据报错自我修正。
    • 价值: 它让“自然语言编程”第一次变成了现实。

7.2 平台:像搭积木一样“捏”一个 Agent

如果你觉得成品不满足需求,想自己做一个“周报生成器”或“私有知识库助手”,但又不想写代码,可以使用 低代码/无代码 (Low-Code) 平台。

  • Coze (扣子) / Dify
    • 定位: 可视化的 Agent 编排平台。
    • 怎么玩: 它们把我们第六章代码里的 LLMToolsLoop 全部变成了可视化组件
      • 需要查新闻?拖入一个“头条搜索”插件(本质是 MCP Tool)。
      • 需要逻辑判断?拖入一个“条件分支”节点(本质是 should_continue 函数)。
    • 适用: 企业内部搭建工作流,或者个人DIY效率工具。

7.3 总结:AI 的完全体

最后,让我们跳出具体的工具,用一个全局视角来结束这三篇文章的旅程。

从 Token 到 MCP,再到 Agent,我们其实是在见证 AI 从“大脑”长出“手脚”,最后学会“开车”的全过程。

  • Token 是燃料: 它代表了算力和成本。没有它,AI 只是废铁。
  • MCP 是底盘: 它是标准化的连接协议。它打破了数据的孤岛,让 AI 能连上数据库、连上代码库、连上世界。
  • Skills 是驾驶技术: 它是封装好的业务能力(如“财务审计”、“代码重构”),连接了底层工具与上层智能。
  • Agent 是自动驾驶汽车: 它是最终的实体。它整合了上述所有能力,能够自主感知、规划、行动、纠错。

眼下,我们正处于 L2 辅助驾驶 阶段(Copilot),还需要人类在关键时刻握住方向盘(Human-in-the-loop)。但随着 MCP 生态的普及和编排技术的成熟,L4 自动驾驶(Autopilot)的时代就在不远的将来。

届时,软件交互将简化为一个输入框:
你只需下达目标,剩下的交给 Agent。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐