news 2026/9/24 22:55:59

AI Agent开发实战:从LLM基础到LangGraph工程落地

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI Agent开发实战:从LLM基础到LangGraph工程落地

做AI Agent这一年多,我最大的感受是:网上的教程和真实能落地的项目之间,隔着一整条“工程实践”的河。我看过几十个视频、买过好几个专栏、把别人的开源项目反复部署又推倒,才慢慢摸清楚智能体到底是怎么一回事。如果你现在正处在“看了概念但写不出代码,照着抄又跑不通”的阶段,这篇从入门到实战的记录应该能帮你省下大量试错时间。我尽量不讲废话,全部按真实开发链路来梳理,覆盖核心技术点、代码实现、部署避坑和职业规划,读完你会对着“AI Agent、智能体、AI大模型”这几个关键词形成一套完整的、能落地的认知框架。

1. 先认识清楚:Agent、LLM、AI大模型到底谁是谁

1.1 大模型、LLM和智能体的层级关系

市面上很多资料把AI Agent、大模型、LLM混着用,这是新手第一道坎。最简单的一句话:大模型是一个底层能力池,LLM是池子里负责文本理解和生成的那部分,而Agent是“用LLM当大脑,再加上感知、记忆、行动能力”的完整系统。

我常跟后端转行的朋友打比方:LLM像一个刚毕业的高材生,知识面很广、反应很快,但你让他独立去完成一个涉及多个环节的任务,他应对不了,因为他没有工具、没有记事本、也没有一个推进任务的执行框架。而Agent就是“给这个高材生配上电脑、搜索引擎、数据库、操作手册,并制定一套工作流程”的组织。所以Agent不是一种模型,而是一种系统架构。

明确这个层级关系之后,很多概念就通透多了。比如常有人问“ChatGPT是Agent吗”,答案是ChatGPT的网页版有Agent能力(能联网、能画图、能执行代码),但它作为纯聊天模型时不是Agent。这也是为什么后面讲开发时,要把工具调用放在核心位置——没有工具,就没有Agent。

1.2 DeepSeek、Hermes这类模型,和Agent开发之间的关系

这里必须回应一个高频困惑:DeepSeek到底属于哪一类。DeepSeek本身是大模型、是LLM,它提供的是语言能力的基础底座。你可以用它的API去开发智能体,也可以本地部署它的开源版本做私有化Agent,但DeepSeek并不等于Agent。它更像你的发动机,Agent则是整辆能上路跑的车。

至于Hermes这类开源模型,走的是完全相同的逻辑。Hermes系列以“对齐好、支持工具调用、适合做助手微调”出名,它也是LLM,优点是很多版本可以直接跑在本地,特别适合隐私要求高的Agent项目。理解这一点很关键:无论你选DeepSeek、Qwen还是Hermes,只要它们支持Function Calling或Tool Use,就具备了当Agent大脑的基本条件

所以别被“某某智能体”的命名带偏。你真正要学的是:如何选一个LLM、如何给它配置技能和工具、如何设计工作流、如何对外提供接口。这套能力才是Agent开发的核心,模型本身只是在换不同的“发动机”而已。

2. 搭建第一条Agent链路:从技术选型到跑通你的第一个“带工具的聊天机器人”

2.1 两条主流路线:低代码平台与代码开发框架的取舍

动手之前,先解决“用什么做”的问题。目前主流路线就两条:低代码平台和代码开发框架。

低代码平台里,Coze和Dify是最典型的两类代表。Coze适合快速在现成平台上拖拽完成Agent,内置大量插件、工作流、知识库和发布渠道,对不写代码或只想快速验证玩法的人极其友好。Dify则更偏“工具型”,强调私有化部署、数据集管理、工作流编排,另外还提供完整的API,方便你把它嵌入自己的系统里。

代码开发框架这边,LangChain和LangGraph两件套基本是事实标准。LangChain负责组件抽象和工具链封装,LangGraph负责把Agent的多个环节建模成图状工作流,支持条件分支、循环、人工介入等高级控制。比它俩底层的,就是直接调大模型API、自己维护消息和工具元信息的“手写Agent”方案,这个我个人非常推荐新手走一遍,因为只有手写过循环,你才能真正理解框架替你解决了什么。

下面是选型判断表,方便你对号入座:

场景推荐方案理由
不做代码开发,只做业务验证Coze上手最快,插件丰富
企业私有化知识库+对话AgentDify数据接入、RAG、API完整
严谨的、可干预的多步骤任务LangGraph图形化状态机,可控性强
学习底层原理、面试手撕手写Agent循环最透明,最锻炼能力
移动端/边缘设备集成llama.cpp / litert-lm可在手机和嵌入式设备跑小模型

2.2 我的入门选型建议:先Coze/Dify验证逻辑,再LangGraph落地正式服务

我从一开始就直接上LangChain,结果被概念绕晕,最痛苦的时候连“Chain和Agent有什么区别”都解释不清楚。后来换了个顺序,效果好了很多:先用Dify把需求快速做成原型,验证清楚业务逻辑;再用LangGraph从零搭正式服务

具体路径是这样走的:假设你老板要求“做一个能自动查天气、还能根据天气给穿衣建议的智能体”。第一步,在Dify里创建Agent,填上天气查询工具,连上一个大模型API,简单输入几个Prompt,十分钟就能得到一个能跑的原型。这一步的意义不是交付,而是验证“工具调用的数据链路是否通畅、大模型能否正确地把用户意图映射到工具参数上”。

确认可行后,第二步才是打开IDE,用代码重新实现一遍。你会发现,待实现的其实就几件事:调用大模型接口、解析模型是否要求调用工具、执行工具函数、把结果回传给模型、继续循环直到模型给出最终回答。这就是Agent循环的骨架,也是一切Agent框架的底座。把这个骨架写透,再去看LangGraph的Node、Edge、State就完全不虚了。

3. 手写一个最小可用Agent:拆解“规划-工具-执行”的完整闭环

3.1 最简Agent循环:LLM的Function Calling就是地基

要理解Agent闭环,最好的办法是手写一个极简版本。我习惯用Python的伪代码来解释这个流程,因为所有概念都能映射到实际代码上,而不是停留在PPT里。

第一步,定义工具元信息。大模型并不知道你系统里有哪些函数,所以你要用JSON Schema描述工具名、用途、参数。下面是一个查询天气工具的元信息:

# tools.py import json def get_weather(city: str) -> str: """查询指定城市的实时天气(示例实现)""" return json.dumps({"city": city, "weather": "晴", "temp": 26}) TOOLS = [ { "name": "get_weather", "description": "获取指定城市的实时天气,入参为城市名", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "城市名,例如:北京"} }, "required": ["city"], }, } ]

工具描述的作用很直接:让LLM知道“有哪些能力可用、什么时候该用、参数该填什么”。很多新手忽略description的精写,结果模型经常在该调用工具时选择瞎编,或者在不该调用时乱调。工具描述写得好,智能体表现立刻提升一截。

第二步,实现循环逻辑。核心代码如下:

import json def run_agent(user_task: str, llm_chat, call_tool): messages = [{"role": "user", "content": user_task}] for step in range(10): # 设置最大轮数,防止死循环 resp = llm_chat(messages, tools=TOOLS) msg = resp.choices[0].message messages.append(msg) if not getattr(msg, "tool_calls", None): return msg.content # 模型没有调用工具,说明任务完成 for tool_call in msg.tool_calls: result = call_tool( tool_call.function.name, json.loads(tool_call.function.arguments), ) messages.append({ "role": "tool", "tool_call_id": tool_call.id, "content": result, })

这段代码就是整个智能体的“心脏”。它做的事情很朴素:把用户问题交给模型,模型决定是直接回答还是调用工具;如果调用工具,就执行真实函数并把结果作为新消息传回模型;模型看到工具结果后,要么继续调用下一个工具,要么给出最终答案。就这么一个循环,反复执行,直到产生最终回答。

为什么要设最大轮数?因为真实环境里LLM可能陷入“反复调用同一个工具但拿不到预期结果”的怪圈。不设上限,一个简单的查询任务可能烧掉你几十次API调用。设10轮是比较常见的做法,关卡在10轮跳到兜底回答即可。

3.2 记忆管理与上下文窗口:单轮助手变成多轮智能体的关键

能理解天气查询之后,下一步要解决记忆。Agent和普通问答最大的区别在于:它要在多轮对话中记住目标、约束、历史事实,并在后续决策里用到这些信息。

LLM的上下文窗口是有限的,你不可能把全部历史都塞进去。所以工程上常用的记忆方案是分层的:短期记忆直接放在messages里,长期记忆存进向量数据库或KV数据库,需要时检索出来再注入上下文。

这里有个常见误区:“把全部历史都当作上下文”等于记忆好。恰恰相反,塞太多无关历史会显著拉低模型专注度,并且推高Token成本。合理的做法是每次请求前做一次筛选:保留系统Prompt、保留最近几轮对话、检索出与当前问题相关的长期记忆片段,然后拼接成一个精简上下文。

举个例子,一个销售智能体需要记忆“客户A上周提到预算收紧”这个事实。正确做法是把它写入长期记忆表,本周客户再次咨询时,通过语义检索把这条记忆捞出来,拼进System Prompt。而不是在每次请求时都重放一遍完整聊天记录。这也是为什么Agent开发经常要和向量检索(RAG)配合的原因——记忆不只是一种存储,更是一种检索能力。

3.3 从单一调用到图编排:LangGraph的Harness架构怎么理解

手写过循环之后,再看LangGraph就会觉得它其实不神秘。LangGraph的核心思想是把Agent流程抽象成一个状态图:不同Node负责不同环节,Edge定义流转条件,State保存全局数据。

一个最常见的Agent图长这样:一个Node负责“调LLM做决策”,另一个Node负责“执行工具”,两者之间有一个条件边——如果LLM返回了工具调用请求,就走工具执行分支;否则直接走结束。这和上面手写的循环本质是一回事,只不过LangGraph把循环改成了图遍历,把if逻辑改成了Edge的Condition。

这就是所谓Harness架构:LangGraph本身不替代LLM,它只是你给智能体设计的执行框架、行动滑轨。你在一条滑轨上装好模型、工具、记忆模块,接下来模型就在这个框架内自行规划路径。这里我要给大家一个实操建议:不要把流程写死在代码里,尽量把可变更的分支配置化。因为Agent运行时的行为非常依赖模型判断,线上总会冒出你预料之外的分支,过度写死的流程改起来代价极高。

LangGraph里,我喜欢把AgentState定义成一个TypedDict,里面保存messages、当前步骤、中间变量。Flow清晰后,无论是加一个检索步骤、还是加一个人工审批节点,都只是往图里插两个Node,比传统的并发协作方式灵活得多。

4. 多智能体与工作流:什么时候该编排,什么时候该放开让Agent自由跑

4.1 多Agent是营销概念还是工程现实?

“多智能体协作”现在被讲得玄乎其玄,但工程上几乎不会为了多Agent而多Agent。真实原因是:一个Agent同时承担太多角色时,Prompt互相干扰,行为不稳定。所以把“研究员Agent”“写作Agent”“审核Agent”拆开,每个Agent拿一套独立的Prompt、技能和记忆,各自干好一件事,再通过上一层编排去协调,反而稳定。

多智能体目前的落地方式主要有两种。一种是角色分层,比如一个主管Agent负责拆任务,下面几个专家Agent分别执行,最后汇总;另一种是流水线协作,上游Agent产出中间结果,下游Agent基于这个结果继续加工。我建议新手第一版先别碰多Agent,老老实实把单Agent调到稳定。你连一个Agent的边界都管不住,拆成十个只会得到十个不可控因素。

还有一点必须提醒:多Agent不是免费的午餐。每引入一个子Agent,就多至少一次LLM调用,意味着更多延迟和更高成本。真正适合多Agent的,是那些任务类型差异大、确实需要不同上下文角色隔离的场景。最简单的判断标准是:如果单个Agent加一个工具就能搞定,就千万不要拆分。

4.2 Human-in-the-Loop:不要让智能体自己决定重要动作

Agent自动化的边界问题,是实际项目里翻车最多的地方。我的经验是:收益越大的动作,越要设人工确认关卡

比如一个智能体拥有发送邮件的权限,你让它自动发出“正式合同版本”给客户,结果它从记忆里捞出一份过期版本发出去,这个锅谁背?所以生产级Agent系统一定要有人工介入机制,英文叫Human-in-the-Loop,简称HITL。在LangGraph里,可以通过一个interrupt机制在关键Node执行前暂停流程,等用户确认后才继续运行。

除了主动暂停,我还会在关键工具外面包一层“语义校验”。工具执行前,让模型先输出一个JSON说明“我要做什么、为什么做、影响范围是什么”,系统根据规则判断是否放行。这种防御性设计,能帮你拦住大部分低级但后果严重的错误。智能体不是用来完全替代人的,把重复劳动接过去、把关键决策交回给人,这才是工程上正确的姿势。

5. 生产接入层的必备姿势:SSE实时渲染与中断控制

5.1 为什么聊天效果“一个字一个字蹦出来”不是炫技

大模型生成耗时长,如果等全部生成完再一次性返回,用户体验会非常差。几秒钟的白屏会让人下意识以为服务挂了。所以生产级Agent几乎都会采用流式输出,也就是后端边生成边推送,前端逐字渲染。

SSE(Server-Sent Events)是我最推荐的方案。相比WebSocket,SSE基于普通HTTP,实现简单、自动重连、兼容性好,天然适合“服务器单向推送文本片段”的场景。你不需要建立双向通道,因为用户请求本来就通过普通POST发给后端了。

一个完整的SSE输出链路是这样的:LLM生成一个Token,后端立刻包装成SSE事件推送,前端用fetch或EventSource接收并追加到页面。聊天消息不是一次性出炉,而是打字机一样“吐”出来。现在你看到的所有正经Agent产品,包括ChatGPT,本质都在做这件事。

5.2 FastAPI流式接口与前端AbortController的完整配合

后端的实现方法很简单。用FastAPI的话,SSE响应就是一个生成器函数和StreamingResponse的组合:

# server.py from fastapi import FastAPI from fastapi.responses import StreamingResponse import json app = FastAPI() def stream_llm(messages): # 这里假装是调用deepseek/qwen等模型,得到chunk for chunk in llm_stream_response(messages): data = {"delta": chunk} yield f"data: {json.dumps(data, ensure_ascii=False)}\n\n" @app.post("/api/chat") async def chat(request: dict): messages = request["messages"] return StreamingResponse( stream_llm(messages), media_type="text/event-stream", headers={"Cache-Control": "no-cache", "X-Accel-Buffering": "no"}, )

有两个细节容易被新手忽视。第一,X-Accel-Buffering: no是给Nginx看的,不加上它,Nginx会把SSE切片缓冲起来,你前端看到的仍然是“攒了很久忽然全刷出来”。第二,SSE格式必须以data:开头,以\n\n结尾,字段顺序也不能乱,否则浏览器解析不了。

前端这边,强烈建议用fetchReadableStream而不是EventSource,原因是EventSource没法发送自定义请求头和终止请求。终止请求能力是刚需,用户点了“停止生成”,前端必须立刻掐断连接,同时告诉后端“别再调LLM了”。这个中断能力来自AbortController

const controller = new AbortController(); const resp = await fetch('/api/chat', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({messages: conversation}), signal: controller.signal }); const reader = resp.body.getReader(); const decoder = new TextDecoder(); let text = ''; while (true) { const {done, value} = await reader.read(); if (done) break; text += decoder.decode(value, {stream: true}); renderStreamText(text); // 增量渲染 } // 用户点击“停止”按钮时调用 stopBtn.onclick = () => controller.abort();

这个组合我实测非常稳。AbortController触发后,fetch连接会被断开,浏览器不会继续读取数据。后端侧也应有响应:当检测到请求断开时,主动取消LLM的生成任务,避免白白烧Token。也就是说,中断不是一个前端动作,而是一条“前端->后端->LLM”的完整链路。

6. 本地部署、模型量化与AI Agent运维中的真实坑

6.1 本地跑大模型:GGUF量化到底怎么选,凭什么显存/内存决定一切

由于数据隐私或成本原因,很多人会考虑本地部署大模型来做Agent后端。本地部署最主流的格式就是GGUF。GGUF是llama.cpp家族支持的模型格式,把模型权重量化成不同精度,对应不同资源需求。

量化精度和资源的关系,我总结成这么一张表:

量化精度模型体积效果损失推荐配置
FP16最大多张专业显卡或大内存服务器
Q8_0较小极小16G左右显存/内存
Q5_K_M较小8G~16G推荐
Q4_K_M很小可感知但可用8G内存/显存也能跑
Q2_K最小明显尽量别用于生产

选型逻辑很简单:能跑更大参数模型,优先选大模型的量化版,而不是小模型的完整版。比如8G显存在7B的Q8和14B的Q4之间,我实测多数场景14B Q4的效果反而更好,因为参数规模带来智力优势,能部分抵消量化损失。

还有一点特别容易踩:很多人以为部署大模型只吃显存,其实CPU内存、内存带宽、散热都重要。本地部署大模型时的延迟大部分花在显存和内存之间的搬运上,你换了更好的CPU,推理速度往往比换显卡提升还明显。想要跑16B以上模型做Agent,16G内存和16G显存几乎是底线。

6.2 智能体运维的经验:Token消耗、评测、兜底设计

Agent上线只是开始,运维才是大头。第一件事就是Token成本失控。一个不太复杂的任务,Agent为了搜资料可能调十几次工具,每次工具结果都是一大坨文本塞进上下文,一轮下来几千Token很正常。应对方法有几个:工具返回结果要精简、只把关键字段回传模型;对长文本工具输出做截断或摘要;增加缓存,命中缓存就直接返回结果。我见过专门给工具结果做大模型压缩处理的项目,效果好但增加一次LLM调用,要平衡着用。

第二件事是评测。Agent的行为带有随机性,无法用传统单测去断言“每次输出一致”。我的做法是建一个回归测试集,每个Case记录输入、预期工具调用序列、预期最终回答要点,每次改完Prompt或模型版本,都在这个集上跑一遍,人工抽查失败Case。没有评测体系的Agent项目,基本就是靠运气维护。

第三件事是兜底。Agent一旦遇到超出能力范围的问题,最常见的表现是反复调用工具失败,或者硬编一个看似合理的结果。这两种情况都要防。前面提到的轮数上限是一种兜底,Prompt里的边界声明也是一种兜底,再加一个外部兜底:当检测到Agent失败次数超标,直接转人工或返回预设话术。运维的本质不是让Agent永远不出错,而是让它出错时可预测、可追踪、可干预。

7. 学习路线与“薪资翻倍”的真实预期

7.1 零基础/后端转Agent开发的现实路径

经常有人问我:“大专生做AI大模型运维能学会吗?”“零基础能不能直接学Agent开发?”这类问题背后其实都是同一个焦虑:这个方向到底有多大门槛。

我的答案是:如果你本来就会Python和基本的HTTP接口开发,Agent开发的学习门槛并没有想象中高。核心要掌握的知识栈按顺序排列如下:

  1. Python基础:函数、类、装饰器、异步;
  2. HTTP与API调用:POST请求、JSON、鉴权;
  3. 大模型API的使用:对话补全、Function Calling、多轮消息格式;
  4. 提示词工程:系统Prompt设计、少样本示例、输出格式约束;
  5. 记忆与RAG:向量化、向量库、相似度检索;
  6. 编排框架:LangGraph或Dify二选一深入;
  7. 部署与运维:Docker、SSE、日志、评测、成本控制。

这套路线大概3到6个月能基本跑通。如果连Python都不熟,就先把Python基础补扎实,别一上来就啃LangChain源码。框架迭代很快,底层API基本功才是长期竞争力。

至于“AI大模型运维”方向,最近确实很热,它的重点不是算法,而是模型服务的高可用、推理成本优化、显存规划、监控告警。这和Agent开发是两个相邻但不同的方向,对数学要求较低,更适合后端或运维背景的人切入。

7.2 面试会问什么,简历写什么

“学完薪资翻倍”这个说法,我只能说别被标题党带偏,但Agent开发确实是目前大模型应用层里需求最多、薪资弹性最大的方向之一。只要你能在简历里证明自己独立完成过Agent项目,并且踩过生产环境的各种坑,市场反馈一般都不会差。

面试最常见的问题往往集中在下面这几块:Function Calling的执行流程、ReAct循环的原理、上下文窗口怎么管理、RAG召回不足怎么调、Agent输出不稳定怎么办、如何设计人工审批环节、如何评估一个Agent好不好用。

我建议简历项目这样写:不要堆砌“熟练使用LangChain”,要写清楚你用什么模型、解决什么业务问题、Agent的循环怎么设计、工具怎么接入、Token成本怎么优化、流式输出怎么做、线上踩过什么坑。项目真实性和细节深度比面经重要得多。面试官最烦的就是背出来的八股文,最想听的是你踩坑之后总结出来的为什么。

说回实操层面,我还是坚持一件事:如果你真的想入行AI Agent方向,找一个自己熟悉的业务场景,从大模型API开始手写一遍Agent循环,然后用LangGraph重构一遍,再用Dify快速搭一个原型,最后接到真实用户手里跑一两周。这套流程走完,你自然就理解了工具调用、记忆、多智能体编排、SSE流式输出、本地部署这些关键词到底意味着什么。技术迭代很快,但Agent这套“用大模型做决策、配工具去执行、靠记忆持续学习”的思路,短期内不会变,把基本功打扎实,后面换什么框架都不慌。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 22:55:00

电力系统可靠性评估:停运模型、状态解析法与Monte Carlo仿真实践

简介:《电力系统规划与可靠性:6 电力元件和系统的可靠性模型》PPT是面向电力系统规划与可靠性工程的教学课件,适合电力系统规划人员、可靠性工程师和电气专业学生学习和参考。内容首先介绍可靠性评估的三个层次——发电系统、发输电系统和整体…

作者头像 李华
网站建设 2026/9/24 22:53:09

Python import机制深度解析:从sys.path到循环导入一次讲透

写Python这些年,几乎每天都会和import打交道。你可能觉得它简单,不就是import xxx嘛,但等你在真实项目里折腾过几回,就会明白:无数报错、无数"装上了却导不进""循环引用""相对导入失败"…

作者头像 李华
网站建设 2026/9/24 22:52:36

电脑数据恢复三大方法全解析:从误删到物理损坏的完整应对指南

电脑数据恢复这件事,我踩过的坑比大多数人见过的都多。早些年帮朋友找回误删的毕业设计,后来帮同事抢救过格式化的移动硬盘,再后来自己手贱清空过回收站。说实话,数据丢失这件事,90%的情况都不是硬盘物理损坏&#xff…

作者头像 李华
网站建设 2026/9/24 22:52:26

Java代码规范实战:从命名规范到工具链落地的完整指南

在代码评审里待得久了,你会慢慢发现一个规律:能让两个Java开发者在会议室里争得面红耳赤的,往往不是复杂的并发问题,也不是高深的JVM调优,而是最简单不过的代码规范问题。“这里应该用空格还是Tab”“这个if语句到底要…

作者头像 李华
网站建设 2026/9/24 22:52:26

GitHub热榜深度解析:从趋势雷达到本地部署的实战技巧

GitHub 热榜项目这个题,其实从 2016 年前后开始就一直是开发者圈子里每天必看的东西。过去是看个热闹,今天再看日榜,更像是在观察全球开源生态的实时风向。每天都有几十个新仓库冲进 Trending,有些项目是明星团队发布的新工具&…

作者头像 李华
网站建设 2026/9/24 22:52:22

ONNX转MindSpore实战:模型转换、算子兼容与端侧部署指南

1. 模型转换这件事,为什么值得单独拿出来讲做过深度学习部署的人都有一个共识:训练框架和推理框架往往是两套生态。你在 PyTorch 里训练出来的模型,到了端侧、板端或者国产算力平台上,大概率不能直接跑。这中间的桥梁,…

作者头像 李华