0帧起手学langchain之马冬梅

🌟 一、LangChain 是什么?(一句话版)

LangChain 是一个帮你"组装 AI 应用"的工具箱。

就像你搭乐高积木:

  • 大模型(比如通义千问、ChatGPT)是"马达";
  • 数据库、网页、文件是"零件";
  • LangChain 就是连接它们的接口和框架,让你不用从零造轮子。

🧩 二、打个比方:你想做一个"智能客服"

❌ 没有 LangChain 时,你要自己:

  1. 调用大模型 API(比如 Qwen)
  2. 把用户问题拼成特定格式
  3. 解析返回结果
  4. 如果要查公司知识库,还得自己写数据库查询
  5. 如果要聊天记录,还得自己存历史
  6. 如果要流式输出(一个字一个字出),还得处理网络分块......

👉 非常麻烦,重复劳动多!

✅ 有了 LangChain 后:

它已经把上面这些事封装好了,你只需要:

复制代码
from langchain_community.chat_models import ChatQwen
llm = ChatQwen(api_key="xxx")
response = llm.invoke("你好啊!")
print(response.content)

💡 LangChain 的核心思想:让开发者专注"业务逻辑",而不是底层通信细节。

🔧 三、LangChain 的几个关键概念(小白友好版)

术语 类比解释 例子
LLM / ChatModel "会说话的大脑" 通义千问、ChatGPT
Message "对话的一句话" 你说:"你好" → HumanMessage("你好") AI回:"Hi!" → AIMessage("Hi!")
Chain(链) "做事的流程" 先查资料 → 再总结 → 最后回答
Agent(代理) "会自己想办法的AI" 你问"今天天气怎样?",它自动去查天气API
Tool(工具) "AI能用的外挂" 计算器、搜索、发邮件......

🎭 四、代码实践------马冬梅

它是在 "假装自己是一个 AI",专门用来搞笑 + 演示 LangChain 的规范写法。
数据流 :你的问题 → 包成"人话" → 传给大爷 → 大爷查计数器 → 选一句台词 → 拆成字 → 一个一个慢悠悠吐出来 → 你看到经典三连问。
langchain包下载:如果是在pycharm内,代码复制进去点击红线报错处安装即可

复制代码
# 第1行:导入 time 模块,用来让程序"暂停一下"(模拟老人说话慢)
import time

# 第2行:导入 re 模块,用来"查找文字"(比如检查有没有"马冬梅")
import re

# 第3行:导入一些类型工具,帮助代码更规范(不用深究,照抄就行)
from typing import Any, List, Iterator, Optional

# 第4行:导入 PrivateAttr,用来定义"私有变量"(比如记住问到第几句了)
from pydantic import PrivateAttr

# 第5行:导入回调管理器,用于流式输出时通知外部(比如告诉界面"新字来了")
from langchain_core.callbacks import CallbackManagerForLLMRun

# 第6行:导入 BaseChatModel,这是 LangChain 里"自定义聊天AI"的标准模板
from langchain_core.language_models.chat_models import BaseChatModel

# 第7行:导入消息类型:
#   HumanMessage = 人说的话
#   AIMessage = AI 说的话
#   BaseMessage = 所有消息的统称
#   AIMessageChunk = AI 说的一个字(用于流式输出)
from langchain_core.messages import HumanMessage, AIMessage, BaseMessage, AIMessageChunk

# 第8行:导入输出格式:
#   ChatGeneration = 一次完整的AI回答
#   ChatGenerationChunk = AI回答中的一个字
#   ChatResult = 包含所有回答的结果对象
from langchain_core.outputs import ChatGeneration, ChatGenerationChunk, ChatResult


# 第11行:定义一个新类,叫 ChatWithOlderAI,它继承自 BaseChatModel
#        意思是:"我要造一个符合 LangChain 标准的聊天AI"
class ChatWithOlderAI(BaseChatModel):
    """模拟《夏洛特烦恼》里记不住"马冬梅"的老大爷"""

    # 第14行:定义一个内部计数器,用来记住这是第几次听到"马冬梅"
    #         PrivateAttr 表示这是"私有属性",不能被外面随便改
    _counter: int = PrivateAttr(default=0)

    # 第17行:告诉 LangChain 这个AI的类型名字(随便起,但要有)
    @property
    def _llm_type(self) -> str:
        return "ma-dong-mei-daddy"

    # 第20行:定义 _generate 方法 ------ 这是 LangChain 要求必须实现的
    #         它的作用是:一次性返回完整的AI回答
    def _generate(
        self,
        messages: List[BaseMessage],          # 用户发来的所有消息(列表形式)
        stop: Optional[List[str]] = None,     # 可选:遇到哪些词就停止(这里不用)
        run_manager: Optional[CallbackManagerForLLMRun] = None,  # 回调管理(流式用)
        **kwargs: Any,                        # 其他可能的参数
    ) -> ChatResult:                        # 返回值必须是 ChatResult 类型
        # 第27行:调用内部方法 _ask_remote,拿到AI的回答(是一个消息列表)
        responses = self._ask_remote(messages)
        # 第28行:把每个回答包装成 ChatGeneration(LangChain 要求的格式)
        generations = [ChatGeneration(message=msg) for msg in responses]
        # 第29行:把所有回答打包成 ChatResult 返回
        return ChatResult(generations=generations)

    # 第31行:定义 _ask_remote 方法 ------ 这是我们自己写的"大脑逻辑"
    def _ask_remote(self, messages: List[BaseMessage]) -> List[BaseMessage]:
        # 第33-37行:定义大爷的经典三连问(存成一个列表)
        replies = [
            "马什么梅?",
            "什么冬梅??",
            "马东什么??"
        ]
        
        # 第39行:取出用户最新的一条消息内容(比如"马冬梅啊!")
        user_input = messages[-1].content  # [-1] 表示"最后一个"

        # 第41行:用正则表达式检查用户是否说了"马冬梅"或"马东梅"(不区分大小写)
        if re.search(r"马冬梅|马东梅", user_input, re.IGNORECASE):
            # 第42行:根据当前计数器,选出对应的回复(比如第0次 → "马什么梅?")
            reply_text = replies[self._counter]
            # 第43行:计数器加1,并对3取余(实现循环:0→1→2→0→1...)
            self._counter = (self._counter + 1) % len(replies)
        else:
            # 第45行:如果没提到"马冬梅",就回一句敷衍的"哦..."
            reply_text = "哦..."

        # 第47行:把回复包装成 AIMessage(表示这是AI说的话),放进列表返回
        return [AIMessage(content=reply_text)]

    # 第49行:定义 _stream 方法 ------ 这是 LangChain 要求支持"流式输出"时必须实现的
    def _stream(
        self,
        messages: List[BaseMessage],          # 用户消息列表
        stop: Optional[List[str]] = None,
        run_manager: Optional[CallbackManagerForLLMRun] = None,
        **kwargs: Any,
    ) -> Iterator[ChatGenerationChunk]:     # 返回一个"字"的生成器
        # 第56行:先调用 _ask_remote 拿到完整的AI回答(取第一个)
        response = self._ask_remote(messages)[0]
        # 第57行:遍历回答中的每一个字符(比如"马"、"什"、"么"......)
        for char in response.content:
            # 第58行:每输出一个字,暂停0.08秒(模拟老人说话慢)
            time.sleep(0.08)
            # 第59行:把这个字包装成 AIMessageChunk(流式专用格式)
            chunk = ChatGenerationChunk(message=AIMessageChunk(content=char))
            # 第60-61行:如果外部有监听(比如网页界面),就通知它"新字来了"
            if run_manager:
                run_manager.on_llm_new_token(token=char, chunk=chunk)
            # 第62行:把这个字"吐出去"(yield 是 Python 的流式关键词)
            yield chunk


# ===== 以下是测试代码(不是AI本身,只是用来演示怎么用)=====

# 第66行:如果直接运行这个文件(而不是被别人导入),就执行下面的测试
if __name__ == "__main__":
    # 第68-74行:定义一组用户要问的问题(模拟夏洛反复喊"马冬梅")
    user_questions = [
        "大爷,楼上322住的是马冬梅家吗?",
        "马冬梅啊!",
        "我是说马冬梅!!",
        "您歇着吧...",
        "今天吃了吗?"
    ]

    # 第76行:创建一个"马冬梅大爷"AI 实例
    llm = ChatWithOlderAI()

    # 第78行:遍历每个问题
    for q in user_questions:
        # 第79行:把问题包装成 HumanMessage(人说的话)
        human_msg = HumanMessage(content=q)
        # 第80行:打印夏洛的问题
        print(f"\n\n👴 夏洛:{q}")
        # 第81行:打印"大爷:",但不换行(后面要接逐字输出)
        print("🧓 大爷:", end="", flush=True)
        
        # 第84行:调用 .stream() 方法,传入消息列表 [human_msg]
        for chunk in llm.stream([human_msg]):
            # 第85行:打印当前这个字(end="" 表示不换行,flush=True 立刻显示)
            print(chunk.text, end="", flush=True)
        # 第86行:所有字输出完后,换行
        print()

它做了什么?

  1. 继承了 LangChain 的 BaseChatModel
    → 相当于"注册成为官方认可的聊天机器人"
  2. 实现了两个方法:
    • _generate():一次性返回整句话(比如直接说"马什么梅?")
    • _stream():一个字一个字慢慢说(模拟老人说话慢)
  3. 用了 LangChain 规定的消息格式:
    • 人说的话 → HumanMessage
    • AI说的话 → AIMessage
    • 流式输出的每个字 → AIMessageChunk

✅ 这样做的好处是:这个"假AI"可以无缝接入 LangChain 的生态!

比如你可以把它塞进一个"聊天机器人界面",或者和其他真实 AI 组合使用。

🤔 五、那我为什么要关心 LangChain?

如果你只是想调用大模型聊天,其实可以直接用通义app、文心一言、Kimi......

但如果你想要:

  • 📚 让 AI 回答基于你自己的文档(比如公司手册、产品说明书)
  • 💬 做一个带记忆的聊天机器人(记得你上次说了啥)
  • 🌐 让 AI 自动上网查资料再回答
  • 🏗️ 搭建复杂工作流(比如:收邮件 → 提取订单 → 查库存 → 回复客户)

→ 那么 LangChain 就是你的好帮手!

相关推荐
BeforeEasy16 小时前
从零搭建一个完整的ai-agent小项目
人工智能·langchain
西柚小萌新1 天前
【人工智能:Agent】--9.2.Langchain自定义中间件
langchain
Loo国昌2 天前
深入理解 FastAPI:Python高性能API框架的完整指南
开发语言·人工智能·后端·python·langchain·fastapi
Sarvartha2 天前
LangChain 入门核心知识学习笔记
笔记·学习·langchain
勇气要爆发2 天前
Docker+Ollama+LangChain:从零搭建企业级“隐私优先”本地 RAG 知识库 (附源码)
docker·容器·langchain·lora·rag·ollama·llama 3
懈尘2 天前
基于Spring Boot与LangChain4j的AI驱动新闻系统设计与工程实现
java·大数据·人工智能·spring boot·后端·langchain
西柚小萌新3 天前
【人工智能:Agent】--9.1.Langchain内置中间件
langchain
小王努力学编程3 天前
LangChain——AI应用开发框架(核心组件1)
linux·服务器·前端·数据库·c++·人工智能·langchain
小王努力学编程3 天前
LangChain——AI应用开发框架(核心组件2)
linux·服务器·c++·人工智能·python·langchain·信号