LangChain工作流


开源项目 https://github.com/langchain-ai/langchain
官方文档 https://python.langchain.com/docs/tutorials/
方法参考 https://python.langchain.com/api_reference/community/index.html
语雀教程 https://www.yuque.com/aaron-wecc3/dhluml/oaxisgo4f903i3xc
密码 ghkq

如果使用非openai第三方例如ollama通常要安装第三方包:
uv pip install langchain-ollama
from langchain_ollama import OllamaEmbeddings

安装前确保在虚拟环境中
pip install langchain-openai #如果不需要编排很多时候这个就够了

pip install langchain langchain-community sentence-transformers -i https://mirrors.aliyun.com/pypi/simple/

可选库:langchain-chroma langchain-postgres

如果要使用langchain封装的pg数据库方法则还需系统执行
sudo apt-get install libpq-dev

基础常识

链式调用

链式拼接:chain = prompt | llm
拼接后chain变量就是一个Runnable对象

调用:

python
# 返回是一个对象
res = chain.invoke({
            "input": user_input,  # 当前用户输入
            "history": chat_history  # 之前的对话历史
})
# 取模型回复
print(res.content)

将函数转Runnable对象

python
from langchain_core.runnables import RunnableLambda

# 自定义函数
def extract_key_info(text: str) -> str:
    return text

# 将函数转为runnables
process_fn = RunnableLambda(extract_key_info)

# 构造总链,这里的lambda相当于一个格式化程序,左边x是要传递给下一层的变量,右边x是上个链传递下来的变量,右边是要传递给下一层的转换
full_chain = chain | (lambda x: x.content) | process_fn | (lambda x: {"text": x}) | chain2

# 下面这个方法就是直接提取AI回复对象中的内容的,因此上面的(lambda x: x.content)可以用StrOutputParser()替代
from langchain.output_parsers import StrOutputParser

条件分支RunnableBranch+分类器

python
from langchain_openai import ChatOpenAI  # 使用 ChatOpenAI
from langchain_core.runnables import RunnableLambda, RunnableBranch
from pydantic import BaseModel, Field
from typing import Literal

# 分类器模型
question_llm = ChatOpenAI(
    model_name="qwen3:32b",
    temperature=0.2, # 设置一个较低的温度值,使模型更倾向于输出更确定性的结果
    top_p=0.3, # 0.3 表示只考虑前30%的token
    max_tokens=300
)

# 聊天模型
answer_llm = ChatOpenAI(
    model_name="qwen3:32b",
    temperature=0.7,
    top_p=0.95,
    max_tokens=5000
)

# 定义分类结构
class QuestionClassifier(BaseModel):
    """问题分类器输出结构"""
    category: Literal["计算机相关","闲聊"] = Field(
        description="问题的类别")
    confidence: float = Field(
        description="分类的置信度,范围从0到1", ge=0, le=1)
    keyword: str = Field(
        description="问题中的关键词")

# 定义一个问题分类器函数
def question_classifier(user_input) -> QuestionClassifier:
    # 创建一个带结构化输出的问题分类器
    classifier = question_llm.with_structured_output(QuestionClassifier)
    # # 初始化系统提示,如果效果不好可以额外添加系统提示
    # history_messages = [
    #     SystemMessage(content="你是一个专业的问题分类助手,能够准确识别用户问题的类别。")
    # ]
    # # 添加当前用户消息到历史
    # history_messages.append(HumanMessage(content=f"请分析这个问题:\n{user_input}"))
    # result = classifier.invoke(history_messages)
    result = classifier.invoke(user_input) # 大多数时候不用写提示词
    print(f"分类信息:{result}")
    return result.category

# 创建条件分支
branch_chain = RunnableBranch(
    (lambda x: x == "闲聊", RunnableLambda(lambda x: "你好,我是李坤朋开发的AI助手,有什么可以帮你的吗?")),
    # 如果不是闲聊,则直接调用answer_llm
    RunnableLambda(lambda x: answer_llm.invoke(x).content)
)

# 完整处理链
chat_chain = RunnableLambda(question_classifier) | branch_chain
print(chat_chain.invoke("你好呀"))

调试模式

python
import langchain
langchain.debug = True # 开启调试模式

基础示范

python
# 导入ChatOpenAI类,这是与OpenAI API通信的接口
from langchain_openai import ChatOpenAI
# 导入提示模板相关组件,用于构建消息模板
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
# 导入消息类型,用于构建对话历史
from langchain_core.messages import HumanMessage, AIMessage
# 导入操作系统模块,用于设置环境变量
import os

# 设置OpenAI API密钥,这是访问OpenAI服务的必要凭证
os.environ["OPENAI_API_KEY"] = "sk-6LsZB5NLIfnIfrb30tPCRUBOh61sdRkiFRH500ukWf9hEl6w"
# 设置自定义的API基础URL,将请求重定向到指定服务器
os.environ["OPENAI_BASE_URL"] = "https://newapi.ipzu.com/v1"

def main():
    """
    主函数:创建一个具有记忆功能的对话链
    """
    # 初始化大语言模型,可以设置多种参数控制输出特性
    llm = ChatOpenAI(
        model="gpt-4o-mini",  # 指定使用的模型
        temperature=0.7,      # 控制输出的随机性,范围0-2,越高越随机创新,越低越确定
        top_p=0.9,            # 采样率,控制token的采样范围,范围0-1
        max_tokens=2000,      # 限制生成文本的最大token数
        # frequency_penalty=0,  # 频率惩罚,减少重复,范围-2.0到2.0
        # presence_penalty=0,   # 存在惩罚,增加话题多样性,范围-2.0到2.0
        # timeout=30,           # API调用超时时间(秒)
        # streaming=True       # 是否启用流式输出
    )
    
    # 创建聊天提示模板,定义AI的行为和对话格式
    prompt = ChatPromptTemplate.from_messages([
        # 系统消息,定义AI的角色和行为准则
        ("system", """你是一个乐于助人、有创意、聪明且非常友好的AI助手。"""),
        # 消息占位符,用于插入历史对话记录
        MessagesPlaceholder(variable_name="history"),
        # 人类消息模板,用于插入用户的当前输入
        ("human", "{input}")
    ])
    
    # 创建聊天链,使用管道操作符将提示模板和LLM连接起来
    chain = prompt | llm
    
    # 初始化空的对话历史列表,用于存储所有交互
    chat_history = []
    
    # 打印欢迎信息
    print("开始与AI对话(输入'退出'结束对话)")
    # 开始无限循环,直到用户选择退出
    while True:
        # 获取用户输入
        user_input = input("你: ")
        # 检查用户是否输入了退出命令
        if user_input.lower() in ["退出", "exit"]:
            # 如果是退出命令,则跳出循环
            break
        
        # 调用聊天链处理用户输入,同时传入历史记录
        response = chain.invoke({
            "input": user_input,  # 当前用户输入
            "history": chat_history  # 之前的对话历史
        })
        
        # 将用户的当前消息添加到历史记录中
        chat_history.append(HumanMessage(content=user_input))
        # 将AI的响应添加到历史记录中
        chat_history.append(AIMessage(content=response.content))
        
        # 打印AI的回复
        print(f"AI: {response.content}")

# 程序入口点,当脚本直接运行时执行main函数
if __name__ == "__main__":
    main()

使用系统提示对话

python
import os  # 导入操作系统模块
from langchain_openai import ChatOpenAI  # 使用 ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage, AIMessage

# ---------------- 环境与模型配置 ----------------
os.environ['OPENAI_API_KEY'] = 'ollama'
os.environ['OPENAI_API_BASE'] = 'http://192.168.1.163:11434/v1'

llm = ChatOpenAI(
    model_name="qwen3:32b",
    temperature=0.7
)

# 初始化历史消息列表,包含系统提示
history_messages = [
    SystemMessage(content="你是一个有帮助的AI助手,请根据历史对话回答用户的问题。请简洁、清晰地回答。")
]

def main():
    while True:
        # 获取用户输入
        user_input = input("用户:")
        if user_input.lower() in ('exit', 'quit'):
            print("退出演示。")
            break
        
        # 添加当前用户消息到历史
        user_message = HumanMessage(content=user_input)
        history_messages.append(user_message)
        print(f"发送的消息: {history_messages}")
        # 发送整个历史记录
        response = llm.invoke(history_messages)
        print(f"AI: {response.content}")
        
        # 将AI回复添加到历史记录中
        history_messages.append(AIMessage(content=response.content))
        
if __name__ == '__main__':
    main()

流式输出

将上面的代码设置streaming=True,并修改while True部分

python
while True:
        # 获取用户输入
        user_input = input("你: ")
        # 检查用户是否输入了退出命令
        if user_input.lower() in ["退出", "exit"]:
            # 如果是退出命令,则跳出循环
            break
        
        # 使用流式调用处理用户输入
        print("AI: ", end="", flush=True)  # 打印前缀,不换行
        ai_response_content = ""  # 用于收集完整回复
        
        # 使用stream方法获取流式响应
        for chunk in chain.stream({
            "input": user_input,  # 当前用户输入
            "history": chat_history  # 之前的对话历史
        }):
            # 从流式响应中获取内容增量
            chunk_content = chunk.content
            # 打印内容增量,不换行
            print(chunk_content, end="", flush=True)
            # 累积完整回复
            ai_response_content += chunk_content
        
        # 流式输出完成后换行
        print()
        
        # 将用户的当前消息添加到历史记录中
        chat_history.append(HumanMessage(content=user_input))
        # 将完整的AI响应添加到历史记录中
        chat_history.append(AIMessage(content=ai_response_content))

使用xinference模块,不推荐

更推荐直接使用openai 连接,因为xinference也兼容oepanai

python
from langchain_xinference import Xinference

# 创建XInference模型客户端
llm = Xinference(
    server_url="http://localhost:9997", # XInference服务地址
    model_uid="your_model_id", # 模型ID
    model_type="LLM",  # 指定模型类型为LLM
    stop=["\n\n"],  # 可选:设置停止生成的标记
    temperature=0.7,  # 控制输出的随机性
    top_p=0.9,  # 采样率参数
    max_tokens=2000,  # 最大输出token数
    streaming=True  # 启用流式输出
)

文本转向量,openai兼容,推荐

python
def openai_text_to_embedding(text: str) -> list:
    """
    使用 OpenAI 的 Embedding API 将文本转换为向量
    """
    # 1. 调用 OpenAI Embedding API
    embed_url = f"{OPENAI_BASE_URL}/embeddings"
    embed_headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {OPENAI_API_KEY}",
    }
    embed_payload = {"input": text, "model": "text-embedding-3-small"}

    try:
        embed_resp = requests.post(embed_url, headers=embed_headers, json=embed_payload)
        embed_resp.raise_for_status()
        embed_result = embed_resp.json()
        embedding = embed_result.get("data", [])[0].get("embedding")
        return embedding
    except Exception as e:
        print(f"Embedding API 调用失败: {e}")
        return None

RAG示范+XinferenceEmbeddings

python
from langchain_openai import ChatOpenAI
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain_chroma import Chroma
from langchain.schema.runnable import RunnablePassthrough
from langchain.prompts import ChatPromptTemplate
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_community.embeddings import XinferenceEmbeddings
import os
import traceback

# 配置环境变量
os.environ["OPENAI_API_KEY"] = "12121" 
os.environ["OPENAI_BASE_URL"] = "http://120.240.236.157:7997/v1"

# 创建LLM和Embedding模型
llm = ChatOpenAI(model_name="qwen25", temperature=0.7)
xinference_embedding = XinferenceEmbeddings(
    server_url="http://120.240.236.157:8997",
    model_uid="bge-large-zh-v1.5"
)

# 创建一个嵌入式模型
#embed_model  = OllamaEmbeddings(
#    base_url=OPENAI_BASE_URL,
#    model="bge-m3:latest"
#)

def create_vectorstore(docs_dir="./docs", collection_name="my_documents", force_reload=False):
    """创建或加载向量存储"""
    persist_directory = f"./chroma_db/{collection_name}"
    
    # 如果存在则加载
    if os.path.exists(persist_directory) and not force_reload:
        print(f"加载已有向量存储")
        return Chroma(persist_directory=persist_directory, embedding_function=xinference_embedding)
    
    # 如果不存在尝试创建一个测试文档
    if not os.path.exists(docs_dir):
        os.makedirs(docs_dir)
        # 创建简单示例文档
        with open(f"{docs_dir}/sample.txt", "w", encoding="utf-8") as f:
            f.write("""
            人工智能(AI)是计算机科学的一个分支,致力于创建能够模拟人类智能的系统。
            
            机器学习是AI的一个子领域,专注于让系统从数据中学习。深度学习是机器学习的一种技术,使用神经网络进行学习。
            
            大语言模型(LLM)如GPT、Claude和LLaMA都是基于Transformer架构的深度学习模型,它们通过预训练和微调来完成各种NLP任务。
            
            检索增强生成(RAG)是一种结合检索和生成优势的方法,它先从知识库中检索相关信息,然后利用LLM生成答案。
            这种方式可以有效减少模型编造信息,增强事实准确性。
            """)
        print(f"已创建示例文档")
    
    # 加载和处理文档
    try:
        loader = DirectoryLoader(docs_dir, glob="**/*.txt", loader_cls=TextLoader, loader_kwargs={"encoding": "utf-8"})
        documents = loader.load()
        
        if not documents:
            raise ValueError(f"未找到文档")
            
        # 分割文档
        text_splitter = RecursiveCharacterTextSplitter(
            chunk_size=400, chunk_overlap=50,
            separators=["\n\n", "\n", "。", "!", "?", ".", " ", ""]
        )
        texts = text_splitter.split_documents(documents)
        
        # 创建向量存储
        vectorstore = Chroma.from_documents(
            documents=texts,
            embedding=xinference_embedding,
            persist_directory=persist_directory
        )
        return vectorstore
    
    except Exception as e:
        print(f"创建向量存储出错: {e}")
        raise

def create_rag_chain(vectorstore):
    """创建简化的RAG链"""
    # 获取文档数量并设置检索数
    try:
        doc_count = vectorstore._collection.count()
        k = min(3, doc_count) if doc_count > 0 else 1
    except:
        k = 1
    
    # 创建检索器和提示模板
    retriever = vectorstore.as_retriever(search_type="similarity", search_kwargs={"k": k})
    prompt = ChatPromptTemplate.from_template("""
    根据以下参考信息回答问题。如果参考信息中没有相关内容,请回答不知道。
    
    参考信息: {context}
    问题: {question}
    """)
    
    # 创建RAG链
    document_chain = create_stuff_documents_chain(llm, prompt)
    return {"context": retriever, "question": RunnablePassthrough()} | document_chain

def main():
    try:
        # 创建向量存储和RAG链
        vectorstore = create_vectorstore()
        rag_chain = create_rag_chain(vectorstore)
        
        print("\n=== RAG检索增强生成示例 ===")
        print("输入问题进行查询,输入'q'退出\n")
        
        while True:
            question = input("\n请输入问题: ").strip()
            if question.lower() in ['quit', 'exit', 'q']:
                break
            if not question:
                continue
                
            try:
                # 执行RAG查询
                answer = rag_chain.invoke(question)
                # 输出答案
                if hasattr(answer, 'content'):
                    print(f"\n回答: {answer.content}\n")
                else:
                    print(f"\n回答: {answer}\n")
            except Exception as e:
                print(f"查询出错: {e}")
                
    except Exception as e:
        print(f"程序出错: {e}")

if __name__ == "__main__":
    main()

纯模板cli

python
import os  # 导入操作系统模块
from langchain_openai import ChatOpenAI  # 使用 ChatOpenAI
from langchain_core.prompts import PromptTemplate  # PromptTemplate
import re

# ---------------- 环境与模型配置 ----------------
os.environ['OPENAI_API_KEY'] = 'ollama'
os.environ['OPENAI_API_BASE'] = 'http://192.168.1.163:11434/v1'

llm = ChatOpenAI(model_name='qwen3:32b', temperature=0.7)

qa_template = PromptTemplate(
    input_variables=['question'],
    template='你是一个助人为乐的小助手,请帮助用户回答问题。\n用户问:{question}\n'
)

# 对有思考行为的回答,去除think标签
def clean_think(response_text):
    # 使用正则表达式删除<think>...</think>部分
    clean_text = re.sub(r'<think>.*?</think>', '', response_text, flags=re.DOTALL)
    return clean_text.strip()

def main():
    while True:
        user_input = input('用户:')
        if user_input.lower() in ('exit','quit'):
            print('退出。')
            break
        qa_out = (qa_template | llm).invoke({'question': user_input})
        # 对思考模型,去除think标签
        qa_out2 = clean_think(qa_out.content)
        print(f'AI:{qa_out2}')

if __name__ == '__main__':
    main()

agent

python
import os  # 导入操作系统模块
from langchain_openai import ChatOpenAI  # 使用 ChatOpenAI
from langchain_core.prompts import PromptTemplate  # PromptTemplate
from langchain.memory import ConversationBufferMemory  # 对话记忆
from langchain.tools import Tool  # 工具接口
from langchain_community.tools.convert_to_openai import format_tool_to_openai_function

# ---------------- 环境与模型配置 ----------------
os.environ['OPENAI_API_KEY'] = 'ollama'
os.environ['OPENAI_API_BASE'] = 'http://192.168.1.163:11434/v1'
llm = ChatOpenAI(model_name='qwen3:32b', temperature=0.5)

# ---------------- PromptTemplate 模板化管理 ----------------
qa_template = PromptTemplate(
    input_variables=['history', 'question'],
    template='对话历史:{history}\n用户问:{question}\n请基于上述对话历史回答。'
)
summary_template = PromptTemplate(
    input_variables=['answer'],
    template='请对以下回答做简要总结:\n{answer}'
)

# ---------------- Memory 对话记忆 (迁移新版) ----------------
# 指定input_key和output_key
memory = ConversationBufferMemory(input_key="question", output_key="answer", memory_key='chat_history', return_messages=False)

# ---------------- Tools 自定义求和工具 ----------------
def sum_numbers(text: str) -> str:
    nums = [int(n) for n in text.split() if n.isdigit()]
    return str(sum(nums))

# 自定义求和工具
sum_tool = Tool(
    name='sum_numbers', func=sum_numbers,
    description='对空格分隔的数字求和,如"1 2 3"返回"6"'
)

openai_functions = [format_tool_to_openai_function(sum_tool)]

# ---------------- Agent 智能决策 ----------------
agent = ChatOpenAI(
    model_name='qwen3:32b', temperature=0.5,
    functions=openai_functions, function_call='auto'
)

# ---------------- 简易 CLI 对话 ----------------
def main():
    while True:
        user_input = input('用户:')
        if user_input.lower() in ('exit','quit'):
            print('退出。')
            break

        # 从 memory 中读取历史
        hist = memory.load_memory_variables({}).get('chat_history', '')
        # 1. QA 步骤
        qa_out = (qa_template | llm).invoke({'history': hist, 'question': user_input})
        # 处理AIMessage对象,提取content属性
        answer = qa_out.content if hasattr(qa_out, 'content') else str(qa_out)
        # 2. 总结步骤
        summ_out = (summary_template | llm).invoke({'answer': answer})
        # 处理AIMessage对象,提取content属性
        summary = summ_out.content if hasattr(summ_out, 'content') else str(summ_out)
        # 更新 memory - 正确设置输入和输出参数
        memory.save_context({"question": user_input}, {"answer": answer})

        print(f'模型回答:{answer}')
        print(f'简要总结:{summary}')

        # 如输入含数字,触发工具调用
        if any(ch.isdigit() for ch in user_input):
            func_resp = agent.chat([{'role':'user','content': user_input}])
            print(f'工具执行结果:{func_resp.content}')  # 同样提取content属性


if __name__ == '__main__':
    main()

postgre数据库封装和会话历史记忆

python
import os
from langchain_postgres import PostgresChatMessageHistory
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, SystemMessage
import psycopg
import uuid

# 设定 PostgreSQL 连接参数
POSTGRES_CONNECTION_STRING = "postgresql://postgres:123456@192.168.1.13:5432/langchain_test"
# ---------------- 环境与模型配置 ----------------
os.environ['OPENAI_API_KEY'] = 'ollama'
os.environ['OPENAI_API_BASE'] = 'http://192.168.1.163:11434/v1'

llm = ChatOpenAI(model_name='qwen3:32b', temperature=0.7)

# 生成一个新会话,会话ID必须是uuid
session_id = str(uuid.uuid4())

# 建立与PostgreSQL的连接
conn = psycopg.connect(POSTGRES_CONNECTION_STRING)

# 确保表存在
table_name = "message_store"
PostgresChatMessageHistory.create_tables(conn, table_name)

# 这里的会话ID要自己实现管理,如果指定会话ID则会自动读取聊天记录,如未指定会话ID则不会读聊天记录
chat_history = PostgresChatMessageHistory(
    table_name,
    session_id,
    sync_connection=conn
)

# 系统提示消息
system_message = SystemMessage(content="你是一个有帮助的AI助手,请根据历史对话回答用户的问题。请简洁、清晰地回答。")

def main():
    while True:
        # 获取用户输入
        user_input = input("用户:")
        if user_input.lower() in ('exit', 'quit'):
            print("退出演示。")
            break
        
        # 获取当前历史记录中的所有消息
        history_messages = chat_history.messages
        
        # 构建完整的消息列表
        messages = [system_message] + history_messages + [HumanMessage(content=user_input)]
        
        # 直接使用llm调用,传入消息列表
        response = llm.invoke(messages)
        
        print(f"AI: {response.content}")
        
        # 将当前用户消息和AI回复添加到历史记录中
        chat_history.add_user_message(user_input)
        chat_history.add_ai_message(response.content)
		# aadd_messages([msg_obj]) 异步方法

if __name__ == "__main__":
    main()

langchain强制模型输出json或类,qwen3和openai模型有效

python
import os  # 导入操作系统模块
from langchain_openai import ChatOpenAI  # 使用 ChatOpenAI
from langchain_core.prompts import PromptTemplate  # PromptTemplate
import re

# ---------------- 环境与模型配置 ----------------
os.environ['OPENAI_API_KEY'] = 'ollama'
os.environ['OPENAI_API_BASE'] = 'http://192.168.1.163:11434/v1'

llm = ChatOpenAI(model_name='qwen3:32b', temperature=0.7)

# from pydantic import BaseModel, Field
# class ResponseFormatter(BaseModel):
#     """始终使用此工具来构建对用户的响应。"""
#     name: str = Field(description="姓名,随机生成一个中文名字")
#     bio: str = Field(description="个人简介,不超过100字")
#     age: int = Field(description="年龄,16-60岁之间")
#     gender: str = Field(description="性别,男或女")


# model_with_structure = llm.with_structured_output(ResponseFormatter)

schema = {
    "title": "构造一个虚拟人设", 
    "description": "按用户要求构造一个虚拟人设,输出json格式",
    "type": "object",
    "properties": { # 属性
        "name": {
            "type": "string",
            "description": "随机中文姓名"
        },
        "bio": {
            "type": "string",
            "description": "个人简介,不超过100字"
        },
        "age": {
            "type": "integer",
            "description": "年龄,16-60岁之间"
        },
        "gender": {
            "type": "string",
            "description": "性别",
            "enum": ["男", "女"]
        },
        
    },
    "required": ["name", "bio", "age", "gender"] # 必填字段
}
# 将schema绑定到模型
model_with_structure = llm.with_structured_output(schema)


def main():
    while True:
        user_input = input('用户:')
        if user_input.lower() in ('exit','quit'):
            print('退出。')
            break

        qa_out = model_with_structure.invoke(user_input)
        print(f'AI:{qa_out}')

if __name__ == '__main__':
    main()

langchain 工具调用函数

这个示例会产生多次调用大模型,第一次大模型只返回函数调用参数,langchain根据返回的调用参数去执行这个函数得到结果,然后再发给大模型去组织结果

python
import os  # 导入操作系统模块
from langchain_openai import ChatOpenAI  # 使用 ChatOpenAI
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain_core.tools import tool
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

# ---------------- 环境与模型配置 ----------------
os.environ['OPENAI_API_KEY'] = 'ollama'
os.environ['OPENAI_API_BASE'] = 'http://192.168.1.163:11434/v1'

llm = ChatOpenAI(model_name='qwen3:32b', temperature=0.7)

@tool
def add(a: int, b: int) -> int:
    """计算两个整数的和.

    参数:
        a: 第一个整数
        b: 第二个整数
    """
    print(f'计算{a}和{b}的和')
    return a + b

tools = [add]

# 创建提示模板
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个有用的AI助手,可以帮助用户解决问题,包括计算数学题。"),
    MessagesPlaceholder(variable_name="chat_history", optional=True),
    ("human", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad")
])

# 创建代理和执行器
agent = create_openai_tools_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools)

def main():
    while True:
        user_input = input('用户:')
        if user_input.lower() in ('exit','quit'):
            print('退出。')
            break

        result = agent_executor.invoke({"input": user_input})
        print(f'AI:{result["output"]}')

if __name__ == '__main__':
    main()

langchain 只返回调用方法

python
llm = ChatOpenAI(model_name='qwen3:32b', temperature=0.7)
## 定义一个加法函数
def add(a: int, b: int) -> int:
    """计算两个整数的和.

    参数:
        a: 第一个整数
        b: 第二个整数
    """
    print(f'计算{a}和{b}的和')
    return a + b

tools = [add] # 定义一个工具列表

llm_with_tools = llm.bind_tools(tools) # 将工具绑定到llm

qa_out = llm_with_tools.invoke("计算8和9的和").tool_calls[0]
print(f'{qa_out}')
# 打印结果:{'name': 'add', 'args': {'a': 8, 'b': 9}, 'id': 'call_4cxpkbth', 'type': 'tool_call'}
# 自己根据这个结果去调用这个函数