一个Javaer的AI转型笔记(1):入坑LangChain,我的第一个hello world

文章目录

大家好,我是大煊,作为一个干了几年的javaer,最近终于决定把脚伸进了 AI agent开发。

第一脚踩的是 LangChain。跑通之后我愣了一下:不得不感慨python封装的确实很便捷。

但这不代表它简单。LangChain 背后那套组件、版本、包装层,跟当年从 JDBC 摸到 Spring 的感觉有点像------表面一行 invoke,底下好几层抽象。

这篇是我转型笔记的 第 1 篇只做到 hello worldinvoke("你是谁")),Agent、RAG 那些先不装懂。咱一步一步来。


我学新东西的「三板斧」

每碰一个新的知识点,我基本都按这个顺序:

能干嘛?

LangChain 是什么?一句话:开源的 Agent 工程积木盒

官方在 Docs by LangChain 里把它定位成 agent engineering 平台------不光有 LangChain 本身,还有 LangGraph(编排)、Deep Agents(快速搭 Agent)、LangSmith(观测、评测、部署)。Clay、Cloudflare 这些公司都在用这套东西搞生产级 Agent。

对我这种 Javaer 来说,它像啥?像 Spring AI 的 Python 老大哥 ------帮你把各家 LLM 的调用方式统一起来,后面还能拼 Prompt、Chain、Tool、Memory。本篇我只碰最底层那一刀:调模型

有啥用?

  • 不用自己撸 HTTP 调 OpenAI 兼容接口(虽然底层还是 HTTP)
  • 切换模型或更换厂商时,只需调整几个参数即可
  • 后面做 RAG、Agent,都在这套积木上叠

官方文档

资源 链接
LangChain 主站 https://docs.langchain.com/
Python 组件架构 Component architecture
1.0 迁移指南 Migrate to LangChain v1
开源社区 github

LangChain 六大组件:先认地图

老教程里常讲 LangChain 六大组件 。跟官网 1.0 的 Component architecture 不完全一一对应,但作为入门地图够用了:

经典六大 干啥的 本篇用到?
Models 跟 LLM / Chat 模型对话 是,全文核心
Prompts 模板化提示词
Chains 多步串成流水线,像责任链 / 管道
Memory 多轮对话上下文
Agents 模型自己决定调哪个 Tool
Indexes 文档加载、切分、向量库、检索(RAG 地基)

#mermaid-svg-OZFBD8IRCiF8vsWY{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-OZFBD8IRCiF8vsWY .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OZFBD8IRCiF8vsWY .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OZFBD8IRCiF8vsWY .error-icon{fill:#552222;}#mermaid-svg-OZFBD8IRCiF8vsWY .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OZFBD8IRCiF8vsWY .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OZFBD8IRCiF8vsWY .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OZFBD8IRCiF8vsWY .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OZFBD8IRCiF8vsWY .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OZFBD8IRCiF8vsWY .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OZFBD8IRCiF8vsWY .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OZFBD8IRCiF8vsWY .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OZFBD8IRCiF8vsWY .marker.cross{stroke:#333333;}#mermaid-svg-OZFBD8IRCiF8vsWY svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OZFBD8IRCiF8vsWY p{margin:0;}#mermaid-svg-OZFBD8IRCiF8vsWY .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-OZFBD8IRCiF8vsWY .cluster-label text{fill:#333;}#mermaid-svg-OZFBD8IRCiF8vsWY .cluster-label span{color:#333;}#mermaid-svg-OZFBD8IRCiF8vsWY .cluster-label span p{background-color:transparent;}#mermaid-svg-OZFBD8IRCiF8vsWY .label text,#mermaid-svg-OZFBD8IRCiF8vsWY span{fill:#333;color:#333;}#mermaid-svg-OZFBD8IRCiF8vsWY .node rect,#mermaid-svg-OZFBD8IRCiF8vsWY .node circle,#mermaid-svg-OZFBD8IRCiF8vsWY .node ellipse,#mermaid-svg-OZFBD8IRCiF8vsWY .node polygon,#mermaid-svg-OZFBD8IRCiF8vsWY .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-OZFBD8IRCiF8vsWY .rough-node .label text,#mermaid-svg-OZFBD8IRCiF8vsWY .node .label text,#mermaid-svg-OZFBD8IRCiF8vsWY .image-shape .label,#mermaid-svg-OZFBD8IRCiF8vsWY .icon-shape .label{text-anchor:middle;}#mermaid-svg-OZFBD8IRCiF8vsWY .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-OZFBD8IRCiF8vsWY .rough-node .label,#mermaid-svg-OZFBD8IRCiF8vsWY .node .label,#mermaid-svg-OZFBD8IRCiF8vsWY .image-shape .label,#mermaid-svg-OZFBD8IRCiF8vsWY .icon-shape .label{text-align:center;}#mermaid-svg-OZFBD8IRCiF8vsWY .node.clickable{cursor:pointer;}#mermaid-svg-OZFBD8IRCiF8vsWY .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-OZFBD8IRCiF8vsWY .arrowheadPath{fill:#333333;}#mermaid-svg-OZFBD8IRCiF8vsWY .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-OZFBD8IRCiF8vsWY .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-OZFBD8IRCiF8vsWY .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OZFBD8IRCiF8vsWY .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-OZFBD8IRCiF8vsWY .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OZFBD8IRCiF8vsWY .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-OZFBD8IRCiF8vsWY .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-OZFBD8IRCiF8vsWY .cluster text{fill:#333;}#mermaid-svg-OZFBD8IRCiF8vsWY .cluster span{color:#333;}#mermaid-svg-OZFBD8IRCiF8vsWY div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-OZFBD8IRCiF8vsWY .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-OZFBD8IRCiF8vsWY rect.text{fill:none;stroke-width:0;}#mermaid-svg-OZFBD8IRCiF8vsWY .icon-shape,#mermaid-svg-OZFBD8IRCiF8vsWY .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OZFBD8IRCiF8vsWY .icon-shape p,#mermaid-svg-OZFBD8IRCiF8vsWY .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-OZFBD8IRCiF8vsWY .icon-shape .label rect,#mermaid-svg-OZFBD8IRCiF8vsWY .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OZFBD8IRCiF8vsWY .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-OZFBD8IRCiF8vsWY .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-OZFBD8IRCiF8vsWY :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} LangChain 经典六大组件
本篇只点亮这块
Models
Prompts
Chains
Memory
Agents
Indexes
hello world


0.3 vs 1.0版本

这里为什么要单独写0.3和1.0版本的LangChain, 因为调研了解到现在主流的企业级写法大多是这两种,1.0版本差不多是2025年底才发版的,2026年开始大量投入到企业级项目中

LangChain 这套玩法,感觉和 Spring 的心路历程类似------不是推倒重来,而是一层一层往外包,把底层细节往后推

Spring 演进 你在干啥 LangChain 对应
Spring 3 / 4 XML 或 @Configuration 手写 DataSourceJdbcTemplate,哪个库一目了然 0.3 风格ChatOpenAI(model=..., api_key=..., base_url=...),厂商和参数写死在初始化里
Spring Boot @SpringBootApplication 一把梭,自动配置帮你选实现,你只关心业务 LangChain 1.0init_chat_model(model=..., model_provider="openai", ...),统一入口屏蔽各家差异

代码对比:同一句话,两种写法

维度 0.3 风格 LangChainV0.3.py 1.0 LangChainV1.0.py
导入 from langchain_openai import ChatOpenAI from langchain.chat_models import init_chat_model
初始化 llm = ChatOpenAI(model=..., api_key=..., base_url=...) model = init_chat_model(model=..., model_provider="openai", ...)
调用 llm.invoke("你是谁").content model.invoke("你是谁").content

LangChainV0.3.py 里还藏了段「配置演进史」,跟 Java 项目从写死常量到配置中心的路子一模一样:


确认环境

Javaer 类比:java -version 再加个 mvn dependency:tree。先确认装的是 LangChain 1.0,别跑错环境。

python 复制代码
import sys

import langchain
import langchain_community


def main() -> None:
    try:
        from importlib.metadata import version as pkg_version
        openai_pkg_version = pkg_version("langchain-openai")
    except Exception:
        openai_pkg_version = "(not installed)"

    lc_version = langchain.__version__
    print("langchain version:        " + lc_version)
    print("langchain_community:      " + langchain_community.__version__)
    print("langchain_openai:         " + openai_pkg_version)
    print("langchain file:           " + langchain.__file__)
    print()
    print("Python: " + sys.version)


if __name__ == "__main__":
    main()

0.3 风格

python 复制代码
from langchain_openai import ChatOpenAI

import config

llm = ChatOpenAI(
    model="MiniMax-M2.7",
    api_key=config.require_api_key(),
    base_url="https://api.minimaxi.com/v1",
    temperature=1.0,
)

response = llm.invoke("你是谁")

print(response)
print()
print(response.content)

可以看到返回值有 total_tokens,描述了当前一次交互消耗的总token

1.0 写法 --- LangChainV1.0.py

全文就 17 行,我直接贴:

python 复制代码
# LangChain 1.0+ 使用方式(init_chat_model + MiniMax)
# 需在 .venv(requirements.txt)中运行

from langchain.chat_models import init_chat_model

import config

model = init_chat_model(
    model="MiniMax-M2.7",
    model_provider="openai",
    api_key=config.require_api_key(),
    base_url="https://api.minimaxi.com/v1",
    temperature=1.0,
)

print(model.invoke("你是谁").content)

踩坑笔记

依赖安装

我之前有一点 Python 基础,知道默认的 pip 源在国外,速度较慢,需要换成清华源。在 AI 时代,直接让 AI 助手帮忙完成了安装。

为了方便学习各类框架,依赖隔离,不污染系统 Python,选择把依赖装到项目里面

shell 复制代码
- 创建新的虚拟环境
python -m venv .venv  
- 激活
.venv\Scripts\activate
- 安装所有依赖
pip install -r requirements.txt -i

requirements.txt

python 复制代码
langchain==1.0.0
langchain-openai==1.0.0
langchain-community==0.4.0
python-dotenv==1.0.1
openai==1.109.1

PyCharm 使用

我使用的是PyCharm 2025.1.2版本,依赖安装好过后,让AI执行命令行已经可以跑程序,但是在Pycharm里面几个依赖一直爆红,还研究了好一会儿,最后发现可以通过下面两种入口去选择执行器(感觉像同时选了jdk版本和maven仓库地址一样)

  • 方式一 右上角的设置图标

  • 方式二 右下角的python版本

关键字参数语法

在翻阅python源码的时候 看见*就代表着后续的参数可以通过关键字的形式传值,也是 model_provider="openai"

如果直接写 "openai" 是会报错的(这和java只要位置顺序对了就可以有点区别),而 **则表示 接收任意数量的额外关键字参数 ,

**kwargs 指的是 keyword arguments ,kwargs 替换成其他值也是可以的

相关推荐
元气少女小圆丶3 小时前
SenseGlove Nova 2+Unity开发笔记1
笔记·学习·unity
冰暮流星3 小时前
javascript之history对象介绍
前端·笔记
Mr.Daozhi4 小时前
RAG 进阶实战:跑通 Demo 后我连续翻了 6 次车,逐一修复才真正可用(含 Gradio Web 版)
前端·数据库·langchain·大模型·gradio·rag·科研工具
jialiguo5 小时前
博客摘录「 尚硅谷Vue3入门到实战,最新版Vue3+TypeScript前端开发教程」2024年8月7日
笔记
風清掦5 小时前
【STM32学习笔记-14】WDG看门狗 - 14.2 WWDG窗口看门狗
笔记·stm32·单片机·嵌入式硬件·学习·fpga开发
swipe6 小时前
混合检索 RAG 的工程化实践:不是多查几路,而是把召回、重排和上下文预算管好
后端·langchain·llm
晓梦林6 小时前
bughush靶场学习笔记
笔记·学习
sakiko_7 小时前
Swift学习笔记34-MVC架构,SwiftUI与UIkit混编练习
笔记·学习·swiftui·mvc·swift
Afans_fire7 小时前
多渠道广告归因:3种逻辑解决效果分配难题
笔记·内容运营·广告投放·广告营销·徐州巨量星河