# langchain-study **Repository Path**: learning-python_1/langchain-study ## Basic Information - **Project Name**: langchain-study - **Description**: Python的模型框架 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-01-18 - **Last Updated**: 2026-01-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # LangChain 学习笔记 ## 目录 - [ch01: 接入本地ollama、远程openai](#ch01-接入本地ollama远程openai) - [ch02: 提示词模板](#ch02-提示词模板) - [ch03: 核心机制LCEL](#ch03-核心机制lcel) - [ch04: 输出解析器](#ch04-输出解析器) - [ch05: 会话记忆](#ch05-会话记忆) - [ch06: RAG检索增强生成](#ch06-rag检索增强生成) --- ## ch01: 接入本地ollama、远程openai ### 1.1 接入Ollama - **文件**: `ch01/ollama_demo.py` - **说明**: 使用 `ChatOllama` 接入本地 Ollama 服务 - **关键点**: - 需要指定 `base_url`(默认 http://127.0.0.1:11434/) - 指定模型名称,如 `deepseek-r1:8b` - 使用 `invoke()` 方法调用模型 ### 1.2 接入OpenAI - **文件**: `ch01/openai_demo.py` - **说明**: 使用 `ChatOpenAI` 接入远程 OpenAI 兼容 API - **关键点**: - 需要配置 `base_url` 和 `api_key` - 指定模型名称,如 `gpt-5-mini-2025-08-07` - 可以设置 `temperature` 参数控制输出随机性 --- ## ch02: 提示词模板 ### 2.1 简单文本提示词模板 - **文件**: `ch02/prompt_template.py` - **说明**: 使用 `PromptTemplate` 创建简单的文本提示词 - **关键点**: - 使用 `from_template()` 方法创建模板 - 使用 `{变量名}` 定义占位符 - 使用 `format()` 方法传入参数格式化提示词 ### 2.2 聊天提示词模板 - **文件**: `ch02/chat_template.py` - **说明**: 使用 `ChatPromptTemplate` 创建多角色对话模板 - **关键点**: - 支持三种角色:`system`(系统)、`ai`(助手)、`human`(用户) - 可以使用元组方式或专门的 PromptTemplate 类创建 - 支持动态添加消息:`append()` 方法 - 使用 `format_messages()` 方法格式化消息列表 --- ## ch03: 核心机制LCEL ### 3.1 LCEL基础 - **文件**: `ch03/langchain_lcel.py` - **说明**: LCEL(LangChain Expression Language)是强大的工作流编排表达式语言 - **关键点**: - 使用 `|` 操作符连接各个组件 - 支持线性流式处理或并行处理 - 基本语法:`chain = prompt | llm` ### 3.2 流式处理 - **文件**: `ch03/stream_demo.py` - **说明**: 基于 LCEL 构建流式处理 - **关键点**: - 使用 `StrOutputParser()` 解析 chunk 数据块 - `stream()` 方法返回迭代器 - 可以实时输出 token,提升用户体验 ### 3.3 操作符重载 - **文件**: `ch03/operator_overload.py` - **说明**: LCEL 支持操作符重载,简化链式调用 --- ## ch04: 输出解析器 ### 4.1 字符输出解析器 - **文件**: `ch04/str_output.py` - **说明**: 使用 `StrOutputParser` 将模型输出解析为字符串 - **关键点**: - 用于解析大模型返回的 chunk 数据块 - 将 chunk 转换为字符串格式 - 在流式处理中特别有用 ### 4.2 JSON输出解析器 - **文件**: `ch04/json_output.py` - **说明**: 使用 `JsonOutputParser` 解析 JSON 格式输出 - **关键点**: - 可以指定 `pydantic_object` 参数,按照 Pydantic 模型解析 - 使用 `get_format_instructions()` 获取格式说明 - 在提示词模板中使用 `format_instructions` 变量 ### 4.3 XML输出解析器 - **文件**: `ch04/xml_output.py` - **说明**: 使用 `XMLOutputParser` 解析 XML 格式输出 - **关键点**: - 可以指定 `tags` 参数,设置 XML 标记层级 - 如果不指定 tags,模型会按照自己的想法输出标记 - 同样使用 `get_format_instructions()` 获取格式说明 --- ## ch05: 会话记忆 ### 5.1 内存存储 - **文件**: `ch05/message_save_monery.py` - **说明**: 将聊天记录存储在内存中 - **关键点**: - 使用 `InMemoryChatMessageHistory` 存储会话历史 - 使用 `RunnableWithMessageHistory` 创建会话历史记录运行器 - 需要定义 `get_session_history` 函数获取会话历史 - 使用 `session_id` 区分不同用户的会话 - 在提示词模板中使用 `placeholder` 占位符插入历史消息 ### 5.2 PostgreSQL存储 - **文件**: `ch05/message_save_postgre.py` - **说明**: 将聊天记录存储在 PostgreSQL 数据库中 - **关键点**: - 使用 `PostgresChatMessageHistory` 存储会话历史 - 需要安装 `psycopg` 和 `psycopg-binary` 包 - 使用 `create_tables()` 方法创建表 - 可以实现消息裁剪功能,使用滑动窗口保存最近的 N 条消息 - 使用 UUID 作为 session_id(通过 `id_utils.py` 中的 `to_uuid()` 函数) ### 5.3 工具函数 - **文件**: `ch05/id_utils.py` - **说明**: 提供 ID 转换工具函数 - **关键点**: - `to_uuid()` 函数将自定义 ID 转换为 UUID 格式 - 使用 UUID5 的命名空间生成确定性的 UUID --- ## ch06: RAG检索增强生成 ### 6.1 向量存储 - **文件**: `ch06/vectorstore_demo.py` - **说明**: 将文档加载、分割后保存到向量数据库 - **关键点**: - **文档加载**: 使用 `TextLoader` 加载文本文件,需要指定 `encoding="utf-8"` - **文档分块**: 使用 `RecursiveCharacterTextSplitter` 进行文档分割 - `chunk_size`: 分割大小,如 500 字符分割一个块 - `chunk_overlap`: 重叠字符数,如 50 字符,保证上下文的关联性 - **向量化存储**: 使用 `Chroma.from_documents()` 将文档保存到向量数据库 - `embedding`: 设置 embedding 模型,如 `OpenAIEmbeddings` - `collection_name`: 设置 Chroma 的 collection 名称 - `persist_directory`: 设置向量数据库持久化路径 - **依赖**: 需要安装 `langchain-community`、`chromadb` 等包 ### 6.2 RAG检索生成 - **文件**: `ch06/retriever_demo.py` - **说明**: RAG(Retrieval Augmented Generation)检索增强生成完整流程 - **关键点**: - **初始化向量存储**: - 使用 `Chroma` 加载已保存的向量数据库 - 需要指定相同的 `collection_name`、`embedding_function` 和 `persist_directory` - **构建检索器**: - 使用 `as_retriever()` 方法将向量存储转换为检索器 - 通过 `search_kwargs={"k": 3}` 设置检索的 top_k 数量 - **构建提示词模板**: - 包含角色定义、参考内容占位符、用户提问占位符和执行规则 - 执行规则应明确要求基于检索内容回答,避免幻觉 - **构建RAG链**: - 使用 LCEL 语法:`{"content": retriever, "question": RunnablePassthrough()} | prompt | llm | StrOutputParser()` - `RunnablePassthrough()` 用于直接传递原始输入 - `retriever` 会自动检索相关文档并填充到 `content` 变量 - **流式输出**: 使用 `stream()` 方法实现流式输出,提升用户体验 ### 6.3 RAG工作流程 1. **文档准备阶段**: - 加载文档(文本、PDF、网页等) - 文档分块(chunking) - 生成向量嵌入(embedding) - 存储到向量数据库 2. **检索阶段**: - 用户提问 - 将问题转换为向量 - 在向量数据库中检索相似文档片段 - 返回 top_k 个最相关的文档 3. **生成阶段**: - 将检索到的文档作为上下文 - 结合用户问题构建提示词 - 调用 LLM 生成答案 - 返回结果给用户 ### 6.4 RAG的优势 - **准确性**: 基于真实文档内容回答,减少幻觉 - **时效性**: 可以随时更新知识库,无需重新训练模型 - **可解释性**: 可以追溯答案来源 - **领域适应**: 可以针对特定领域构建知识库 ### 6.5 注意事项 - **文档质量**: 文档质量直接影响检索和生成效果 - **分块策略**: 需要根据文档类型和内容选择合适的 chunk_size 和 chunk_overlap - **检索数量**: top_k 的选择需要在准确性和上下文长度之间平衡 - **提示词设计**: 提示词应明确要求基于检索内容回答,避免模型编造信息 - **Embedding模型**: 选择合适的 embedding 模型对检索效果至关重要 --- ## 总结 LangChain 提供了完整的 RAG 解决方案,从文档加载、向量化存储到检索生成,都有相应的组件支持。通过 LCEL 可以轻松构建复杂的 RAG 工作流,实现基于知识库的智能问答系统。