当前位置: 首页 > news >正文

Day 6:LangChain 入门——框架是双刃剑

🤖系列:Java工程师转AI Agent 3个月学习计划
👤作者:宸丶一| 28岁Java程序员,规划狂魔,正在被AI Agent按头学习
🎯今日目标:用 LangChain 框架重写 Day 5 的 Agent,对比手写 vs 框架
💬个人格言:代码改不改变世界我不知道,但先让我准时下班。


前言

大家好,我是宸一,一个28岁的Java程序员。

今天是第6天,主题是:LangChain 入门

昨天我们花了一整天手写了一个完整 Agent(Day 5),踩了 tool_call_id 的坑,理解了工具调用的底层流程。

今天换个思路:用 LangChain 框架重写同一个 Agent,看看框架帮我们省了多少事,又带来了什么代价。

有个意外收获:我们亲历了 LangChain 0.x → 1.3 的 Breaking Change,旧教程全部失效。这恰好验证了我们的学习路线——先手写理解原理,框架变了也不慌。


一、今日学习路线

01_langchain_basics.py
LangChain 基础

02_langchain_agent.py
用框架实现 Agent

03_comparison.py
手写 vs 框架对比

核心对比:

Day 5 手写 Agent = OpenAI + TOOLS_DEFINITION + FullAgent 类(~300行) LangChain Agent = ChatOpenAI + @tool + create_agent()(~100行)

二、LangChain 四大组件

2.1 用后端思维理解

1. Model
ChatOpenAI
= FeignClient

2. Tool
@tool 装饰器
= Strategy 策略模式

3. Chain
prompt | llm
= Pipeline 流水线

4. Agent
create_agent
= Controller 控制器

LangChain 概念Java 对应作用
ChatOpenAIFeignClient调用大模型 API
@tool@Component注册可调用的工具
ChainPipeline把多个步骤串起来
AgentController决策:用哪个工具、怎么回答

2.2 @tool 装饰器做了什么?

# LangChain 方式(约 10 行/工具)@tooldefget_weather(city:str)->str:"""获取指定城市的天气信息。 Args: city: 城市名称,如"北京"、"上海" """returnf"{city}今天晴天,25°C"

@tool 做了三件事:

1. 注册 —— 告诉框架"这个函数是个可调用的工具" 2. 提取 —— 自动从函数名、docstring、类型注解生成工具描述 3. 包装 —— 把普通函数包装成框架能识别的 Tool 对象

对比 Day 5 手写(约 30 行/工具):

# Day 5 手写方式TOOLS_DEFINITION=[{"type":"function","function":{"name":"get_weather","description":"获取指定城市的天气信息","parameters":{"type":"object","properties":{"city":{"type":"string","description":"城市名称"}},"required":["city"]}}}]

三、用 LangChain 重写 Agent

3.1 核心代码

fromlangchain_openaiimportChatOpenAIfromlangchain_core.toolsimporttoolfromlangchain.agentsimportcreate_agentfromlangchain_core.messagesimportHumanMessage# 1. 定义工具@tooldefget_weather(city:str)->str:"""获取指定城市的天气信息。"""returnf"{city}今天晴天,25°C"@tooldefcalculate(expression:str)->str:"""计算数学表达式。"""returnstr(eval(expression))# 2. 创建 Modelllm=ChatOpenAI(model="mimo-v2-flash",api_key=API_KEY,base_url=BASE_URL)# 3. 创建 Agent(一行搞定)agent=create_agent(model=llm,tools=[get_weather,calculate],system_prompt="你是一个友好的AI助手。使用工具来回答问题。",)# 4. 调用 Agent(一行搞定)result=agent.invoke({"messages":[HumanMessage(content="北京天气怎么样?")]})

对比 Day 5 的 FullAgent 类(~200行):

  • Day 5:手写_execute_tool()_build_messages()chat()等方法
  • LangChain:create_agent()一行创建,agent.invoke()一行调用

3.2 运行效果

📌 测试1:查天气 回答:北京今天晴天,温度25°C,适合出行!☀️ 📌 测试2:算数学 回答:(15+27)*3 = 126 📌 测试3:查时间 回答:现在是2026年6月5日下午2点07分。 📌 测试4:搜索知识 回答:Python 是一种高级编程语言,特点是简洁易读。

四、重点:@tool 和 tool_call_id 的区别

4.1 我的理解偏差

随堂检测 Q2 问:@tool 怎么解决 tool_call_id 问题的?

我的错误回答:

“我感觉就是在 @tool 注册时给到了 tool_call_id,然后给到大模型,大模型就可以调用到了。”

这个理解是错的。我把两个不同的环节混在一起了。

4.2 正确理解:三个阶段,三个主角

整个工具调用流程,分三个阶段: 阶段1:注册(你写代码时做的事) ← @tool 在这里 阶段2:决策(大模型做的事) ← tool_call_id 在这里生成 阶段3:执行(框架帮你做的事) ← tool_call_id 在这里传递

阶段1:注册 —— @tool 在这里起作用

时间点:程序启动时 主角:你 + @tool 目的:告诉大模型"我有哪些工具" @tool 做了什么: ┌─────────────────────────────────────────────┐ │ 函数名 get_weather → 工具的 name │ │ docstring → 工具的 description │ │ 类型注解 city: str → 参数的 JSON schema │ └─────────────────────────────────────────────┘ 这时候大模型知道了:我有一个叫 get_weather 的工具可以用。 但还没有人调用它。tool_call_id 还不存在。

阶段2:决策 —— 大模型在这里起作用

时间点:用户发消息"北京天气怎么样" 主角:大模型 目的:判断要不要调用工具 大模型返回: tool_calls = [{ "id": "call_abc123", ← 这就是 tool_call_id! "function": { "name": "get_weather", "arguments": {"city": "北京"} } }] 注意: - id: "call_abc123" ← 大模型自动生成的唯一 ID - 这个 ID 和 @tool 没有任何关系! - @tool 是你注册工具时用的 - tool_call_id 是大模型决定调用工具时生成的

阶段3:执行 —— 框架在这里起作用

时间点:收到大模型的 tool_calls 主角:create_agent 背后的框架 目的:执行工具,把结果正确返回给大模型 框架做的三步: 第一步:找到工具 tool_calls[0].function.name = "get_weather" → 框架在 @tool 注册的工具列表里找到它 第二步:执行工具 get_weather(city="北京") → 得到结果:"北京今天晴天,25°C" 第三步:回传结果(关键!) { "role": "tool", "tool_call_id": "call_abc123", ← 必须带上这个 ID "content": "北京今天晴天,25°C" }

4.3 为什么 tool_call_id 很重要?

因为大模型可能一次返回多个 tool_calls: call_abc → get_weather("北京") call_def → get_weather("上海") call_ghi → calculate("1+1") 三个结果各自带着自己的 key 回去: call_abc → "北京晴天 25°C" call_def → "上海多云 28°C" call_ghi → "2" 没有 tool_call_id,大模型分不清谁是谁。 就像 Java 里异步调用要关联 requestId 一样。

4.4 总结

阶段 主角 做什么 和 tool_call_id 的关系 ───────────────────────────────────────────────────────────────── 注册 @tool 生成工具描述 无关 决策 大模型 决定调用哪个工具 它生成 tool_call_id 执行 框架 执行+回传结果 它传递 tool_call_id Day 5 踩的坑:阶段3回传结果时漏了 tool_call_id → 报错 LangChain 帮你做的事:阶段3完全自动化,你不用管 tool_call_id

五、手写 vs 框架对比

5.1 代码量对比

+-------------------+-------------------------+-------------------------+ | 对比项 | Day 5 手写 | LangChain 框架 | +-------------------+-------------------------+-------------------------+ | 工具定义 | 手写 JSON schema (30行) | @tool 装饰器 (10行) | | 工具调用 | 手写 tool_call_id (50行) | 框架自动处理 (0行) | | Agent 创建 | 自己写类 (200行) | create_agent() (1行) | | 对话历史 | deque + JSON 文件 | Messages 列表 | | 错误处理 | 自己实现重试 | 内置重试机制 | | 代码量 | ~300 行 | ~100 行 | +-------------------+-------------------------+-------------------------+

5.2 框架的代价

今天我们亲历了 LangChain 的 Breaking Change:

旧版(0.x): from langchain.agents import create_tool_calling_agent, AgentExecutor agent = create_tool_calling_agent(llm, tools, prompt) executor = AgentExecutor(agent=agent, tools=tools) 新版(1.3+): from langchain.agents import create_agent agent = create_agent(model=llm, tools=tools, system_prompt="...") 变化: - AgentExecutor 没了 → 底层换成了 LangGraph - input/chat_history → 统一用 messages 列表 - 更简洁,但旧教程全部失效

框架的三个代价:

1. 黑盒(相对的) 闭源产品 → 完全看不到代码,出问题只能等官方 开源框架 → 能看源码,但要花时间理解 自己写的代码 → 100% 透明 2. Breaking Change 版本更新可能不兼容,旧教程失效 3. 灵活性受限 自定义需求可能被框架限制

5.3 什么时候用框架,什么时候手写?

+-----------------------+-----------------------------------------------+ | 场景 | 建议 | +-----------------------+-----------------------------------------------+ | 快速原型验证 | 用 LangChain(快速出活) | | 学习原理 | 先手写再用框架(我们就是这么做的) | | 生产环境 - 标准功能 | 用 LangChain(社区维护) | | 生产环境 - 高度定制 | 手写核心逻辑(完全可控) | | 生产环境 - 性能敏感 | 手写(减少框架开销) | | 团队协作 | 用 LangChain(统一标准) | | 个人项目 | 手写(更灵活) | +-----------------------+-----------------------------------------------+

六、用后端思维总结

LangChain 概念Java 对应本例实现
ChatOpenAIFeignClient调用小米 MiMo API
@tool 装饰器@Component + 接口注册 4 个工具函数
ChatPromptTemplateString.format定义系统提示
create_agent@Bean 工厂方法一行创建 Agent
agent.invoke()controller.method()调用 Agent 处理请求
tool_call_idrequestId工具调用的唯一标识

七、今日收获

7.1 核心公式

LangChain Agent = ChatOpenAI + @tool + create_agent() 对比 Day 5: Day 5 Agent = OpenAI + TOOLS_DEFINITION + FullAgent 类(300行) LangChain Agent = ChatOpenAI + @tool + create_agent()(100行)

7.2 最大的收获

不是学会了 LangChain,而是理解了框架的本质。

框架 = 把重复的样板代码封装起来,让你专注于业务逻辑 但框架不是银弹: - 版本更新可能 breaking change - 灵活性可能受限 - 出问题可能不好调试 所以: 学习原理 → 先手写 提高效率 → 再用框架 生产选型 → 看场景

7.3 学习路线的价值

Day 1-5 手写 → Day 6 学框架

✅ 好处: - 深入理解了 tool_call_id、消息格式等底层细节 - 知道框架帮你省了什么 - 框架变了也不慌,底层知识永远有用 ❌ 代价: - 花了更多时间 - 没按规划的时间节点完成 💡 结论: "跑偏"不一定是坏事。 学习路线不是直线,而是螺旋上升。

八、明日计划(Day 7)

主题:部署入门 - FastAPI + Docker 基础

- 用 FastAPI 把 Agent 包装成 HTTP 服务 - 写 Dockerfile 容器化 - 测试 API 接口 - 思考生产环境还需要什么

一句话总结

框架是双刃剑:帮你省时间,但也可能坑你。先手写理解原理,再用框架提高效率。

Day 6 最大的收获不是学会了 LangChain,而是理解了 @tool 和 tool_call_id 是两个不同的环节——注册是注册,调用是调用,别混为一谈。

http://www.jsqmd.com/news/960732/

相关文章:

  • 2026广州黄金回收TOP标杆:高价领先权威机构实力测评 - 奢侈品回收评测
  • 毕业季别只会送花!手把手教你用NT3H1101芯片DIY会发光的NFC纪念卡(附PCB文件)
  • RuoYi项目上线前,别忘了给你的Swagger接口文档加把‘锁’(安全配置指南)
  • 手把手教你:华为AP3010DN-V2从Fit刷成Fat的保姆级避坑指南(附固件下载与TFTP配置)
  • [智能体-282]:常见的中英词静态向量表以及主要参数阐述
  • C#写的经典迷宫小游戏:键盘走迷宫、自动生成地图、按空格暂停、F1显示最短路径
  • 2026 夏季上海黄金回收攻略合规机构实测名单 - 开心测评
  • 2026最新诚信优选朔州市黄金回收白银回收铂金回收彩金回收高口碑靠谱门店TOP5权威排行榜+联系方式推荐 - 前途无量YY
  • VC6.0环境下可直接运行的PMAC运动控制卡图形化调试工具
  • 2026最新诚信优选石首市黄金回收白银回收铂金回收彩金回收高口碑靠谱门店TOP5权威排行榜+联系方式推荐 - 前途无量YY
  • PRO系列重构算力形态 云尖信息发布iPRO系列6U16卡超密算力服务器
  • 免费微信投票小程序工具,功能强大,安全稳定 - 微信投票小程序
  • BigQuery原生向量搜索解决语义断层问题
  • 告别手动VL02N:5分钟教你用SAP BAPI和函数搞定交货单自动拣配与过账
  • 烟台正规黄金回收门店怎么选|6月金价973元每克 六家持证机构全拆解 - 余生黄金回收
  • ABAP里AES加密的坑我都替你踩过了:PKCS7填充、CBC模式与字符串转换避坑指南
  • Go开发技巧:如何用 Channel 平滑控制企微外部群消息的主动发送?
  • 2026最新诚信优选无锡市黄金回收白银回收铂金回收彩金回收高口碑靠谱门店TOP5权威排行榜+联系方式推荐 - 前途无量YY
  • 从负载线到开关速度:三极管深度饱和的实战设计与权衡
  • 2026最新诚信优选石嘴山市黄金回收白银回收铂金回收彩金回收高口碑靠谱门店TOP5权威排行榜+联系方式推荐 - 前途无量YY
  • 把行业难点落到实处,汪进进以日常工作稳步攻克困局
  • 从汽车电子到工业控制:STM32F1的CAN总线轮询发送实战解析
  • 广州亲子撸宠好去处!带娃打卡三家黎宥萌宠生活馆,安全干净超适合小朋友 - 润富黄金回收
  • 2026医学文献AI解读工具测评:当“循证”成为医生工作流的新标配
  • 2026手机自制证件照好用APP推荐,免费证件照制作保姆级手把手教程 - AI测评专家
  • 2026最新诚信优选芜湖市黄金回收白银回收铂金回收彩金回收高口碑靠谱门店TOP5权威排行榜+联系方式推荐 - 前途无量YY
  • 知识库系统(上) · 把个人经验变成“复利资产”!
  • 3步轻松上手:Koikatsu Sunshine终极增强补丁完全指南
  • 如何用快马平台结合豆包AI,十分钟搭建待办事项应用原型
  • 2026 新疆正规持证金牌导游 TOP8 本地人优选纯玩高评分推荐 - 盛世西域旅行