langchain简单对话demo

前言

前面安装了langchain,发现了自由线程不支持其中的部分包,切为传统的python,其实做poc的能力,python特别方便,各种功能齐全,尤其是报表统计,代码量真少。先用langchain简单开发一个对话示例demo。

demo

demo根据最常用的对话模板分类,先准备模型,笔者本地的模型,使用gemma4比较慢,mac的配置是丐中丐,所以切换qwen3.5试试,实测速度快很多。

准备

模型:Qwen3.5-4B-MLX-4bit

反正示例demo,对效果不要求,另外还是使用openai的标准api,本身所有建立在llm上的能力,其实就是api的调用,和生态的建设,主要有2大类:llm的交互控制(调用和测试);工具的使用(让大模型使用工具)

字符串对话模板

其实也很简单,主要是2点:链式调用,debug设置

python 复制代码
from langchain_core.globals import set_debug, set_verbose
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate
from langchain_core.tracers import langchain
from langchain_openai import ChatOpenAI

# langchain.debug = True
set_debug(True) #只有这个有效
# set_verbose(True)

def init_openai_chat():
    # return ChatOpenAI(api_key='xxx', base_url='http://127.0.0.1:8000/v1', model='gemma-4-e4b-it-4bit')
    return ChatOpenAI(api_key='xxx', base_url='http://127.0.0.1:8000/v1', model='Qwen3.5-4B-MLX-4bit')


def init_prompt_template():
    return PromptTemplate(template='你是专业的翻译人才,翻译:{content} 这块文本成{language},除了翻译的内容,其他信息使用中文回答',
                          input_variables=['content', 'language']) # 变量占位符,可能其他框架也可以使用{{}},类似freemarker 其实就是模板,langchain这里只能使用{},两个不识别


if __name__ == '__main__':
    client = init_openai_chat()
    prompt_template = init_prompt_template()
    # cn_prompt = prompt_template.format_prompt(content='hello world', language='中文')
    # en_prompt = prompt_template.format_prompt(content='统计信息结果报表', language='英文')
    #
    # hello = prompt_template.format(content='打个招呼', language='英文')
    # resp = client.invoke(hello)
    out_parser = StrOutputParser()
    # 链式调用,这个写法简单,其实问题也不少,不能发现过程出现的问题,需要开启debug模式
    chain = prompt_template | client | out_parser
    print(chain.invoke({'content':'打个招呼', 'language':'英文'}))
    # resp = client.invoke(cn_prompt)
    # print(resp)
    # resp = client.invoke(en_prompt)
    # print(resp)

这里的链式调用,其实对于promptTemplate而言,与直接调用函数的方式,使用的函数是不一样的,使用的是invoke函数,继承自BasePromptTemplate,Python有了面向对象的能力,当然命名也可以驼峰式,以前Python主要是下划线的方式。

查看结果:

关于链式调用:

  1. 整条链条使用同一个函数,比如invoke

  2. 开始的对象执行输入参数,需要传入,然后把输出的结果作为下一个对象函数的输入,返回最终结果

  3. 调试困难,需要代码开启debug调试,当然可以使用langsmith langfuse之类的监控平台能力(类似美团开源的CAT监控,埋点上报)

聊天模板

前面试了最简单的模板,其实实际上使用的是聊天模板,需要区分上下文,上下文会形成记忆体agent,这个上下文一般会被llm上层agent存储,然后使用比如前3轮的对话,或者根据权重区分,当然也可以不使用,毕竟场景不一样需求不一样

python 复制代码
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate, ChatPromptTemplate, SystemMessagePromptTemplate, \
    ChatMessagePromptTemplate, HumanMessagePromptTemplate, AIMessagePromptTemplate
from langchain_openai import ChatOpenAI


def init_openai_chat():
    return ChatOpenAI(api_key='xxx', base_url='http://127.0.0.1:8000/v1', model='Qwen3.5-4B-MLX-4bit')

def init_prompt_template():
    # ChatMessagePromptTemplate.from_template()
    return ChatPromptTemplate.from_messages([
        SystemMessagePromptTemplate.from_template(template='你是专业的翻译人才,请按用户的要求翻译,除了翻译的内容,其他信息使用中文回答'),
        HumanMessagePromptTemplate.from_template(template='除了翻译的内容,其他信息使用中文回答,翻译如下内容为{language}:{content}'),
        # HumanMessagePromptTemplate.from_template(template='翻译如下内容为{language}:{content}'),
        # AIMessagePromptTemplate.from_template('{content}'), #收集上下文,形成记忆体,经常使用的时候,出现用户前面提问xxx,根据xxx之类的就是这个实现的,也可以一键清除
    ])

if __name__ == '__main__':
    client = init_openai_chat()
    prompt_template = init_prompt_template()
    out_parser = StrOutputParser()
    chain = prompt_template | client | out_parser
    print(chain.invoke({'content': '打个招呼', 'language': '英文'}))

试试效果

这里有个系统提示词,发现继承的很不好,比如用户提示词,如果不说使用中文作答

显得系统提示词鸡肋,当然可能是笔者的模型比较小,能力较差

示例模板

为了解决上面的问题,有时候我们可以给出示例给大模型参考,给出步骤之类的,其实就是skills的雏形,使用示例模板,我们给出示例和步骤内容,然后让大模型执行工具,这就是herness agent的能力,先看示例模板

python 复制代码
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate, ChatPromptTemplate, SystemMessagePromptTemplate, \
    ChatMessagePromptTemplate, HumanMessagePromptTemplate, AIMessagePromptTemplate, FewShotPromptTemplate
from langchain_openai import ChatOpenAI


def init_openai_chat():
    return ChatOpenAI(api_key='xxx', base_url='http://localhost:11434/v1', model='modelscope.cn/unsloth/Qwen3.5-9B-GGUF:Q4_0')

def init_prompt_template():
    examples = [
        {'content':'打个招呼', 'language':'英文', 'result':'say hi'},
        {'content':'hello', 'language':'中文', 'result':'你好'}
    ]
    prompt = PromptTemplate.from_template(template='你是专业的翻译人才,翻译如下内容为{language}:{content}')
    return FewShotPromptTemplate(examples=examples,
                          example_prompt=prompt,
                          prefix='你是专业的翻译人才,按照示例简洁作答',
                          suffix='翻译如下内容为{language}:{content},只显示最常用的翻译内容的结果',
                          input_variables=['content', 'language'],)

if __name__ == '__main__':
    client = init_openai_chat()
    prompt_template = init_prompt_template()
    out_parser = StrOutputParser()
    chain = prompt_template | client | out_parser
    print(chain.invoke({'content': '你是谁', 'language': '英文'}))

使用NVIDIA 4060ti 8G显卡,跑了9b模型,在使用示例demo,明显效果好转

果然再怎么优化不如模型强,4b还是不太行

据说qwen 3.6 27b已经可以执行大部分生产应用了,不过笔者的显存太小,至少24G显存是需要的,或者类似苹果的统一内存,aimax 395之类的,可以自己用来做一些并发不高的应用。

实际过程可以使用流式输出stream,其实streamablehttp就是最新的技术方式,这样的好处是模型是生成式模型,生成一个token输出一个token

python 复制代码
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
from langchain_openai import ChatOpenAI


def init_openai_chat():
    return ChatOpenAI(api_key='xxx', base_url='http://localhost:11434/v1',
                      model='modelscope.cn/unsloth/Qwen3.5-9B-GGUF:Q4_0', streaming=True)


def init_prompt_template():
    examples = [
        {'content': '我要用电饭煲做饭', '步骤': '1、打开电饭煲盖子,从米袋往电饭煲加米;2、加适量水;3、盖盖子,插电,按煮饭按钮'},
        {'content': '我要公交车出行', '步骤': '1、准备出行目的地;2、打开地图软件看看适合坐那辆公交车;3、找到最近的公交站台,单车或者步行去;4、等车,上车,出发;5、目的地下车'}
    ]
    prompt = PromptTemplate.from_template(template='你是专业的计划规划师,做如下的规划:{content}')
    return FewShotPromptTemplate(examples=examples,
                                 example_prompt=prompt,
                                 prefix='你是专业的计划规划师,按照示例简洁作答',
                                 suffix='规划如下的事情{content},列出详细的步骤',
                                 input_variables=['content'], )


if __name__ == '__main__':
    client = init_openai_chat()
    prompt_template = init_prompt_template()
    out_parser = StrOutputParser()
    chain = prompt_template | client | out_parser
    for chunk in chain.stream({'content':'我要网上购物,买一个小风扇,需要多平台价格最优'}):
        print(chunk, end='', flush=True)

看结果,录屏可能效果明显

总结

其实所有的AI能力都是通过各种api交互的,最常用的是对话,本质就是提示词交互,当然对话不仅仅是每个人书写,通过写skills,可以把一些列的提示词封装,包括角色,示例,步骤,工具等,多次的对话就有了上下文,即记忆体,同事通过工作流或者循环的方式,把各个推理步骤串起来调用工具,然后使用AI分析各种数据,就是现在的主流应用方式。

相关推荐
孔汤姆1 小时前
ESP32 掌机改造全记录:WiFi 遥测、一键启动 AI 终端
人工智能
HyperAI超神经1 小时前
【vLLM 学习】Disaggregated Prefill
人工智能·深度学习·学习·vllm
我星期八休息2 小时前
网络编程—网络层
开发语言·前端·网络·人工智能·智能路由器
逻辑君2 小时前
ANNA 7.2 方块机器人实验技术报告
人工智能·深度学习·机器学习·机器人
菜鸟‍2 小时前
【论文学习】Medical Image Analysis 2024 || 医学图像分割中失败检测方法的比较基准研究:揭示置信度聚合的作用
人工智能·学习
AI导出鸭2 小时前
怎么让千问做表格?AI导出鸭苹果版将千问输出的管道表格智能解析为二维结构,一键导出为Excel或Word标准表格。
人工智能·chatgpt·word·excel·ai导出鸭
陈嘿萌2 小时前
ECCV 2026 | 南开&OPPO开源 ExpoMotion:首个大规模动态多曝光融合数据集
人工智能·计算机视觉·图像融合·南开大学·新数据集·expomotion·多曝光融合
zyplayer-doc3 小时前
zyplayer-doc企业知识库能做什么:从文档创建、权限管理到AI问答的完整能力
大数据·javascript·数据库·人工智能·pdf·word
IT_陈寒3 小时前
为什么我的Java Stream流操作会吃掉内存?
前端·人工智能·后端
babe小鑫3 小时前
人工智能专业方向梳理的实用清单
人工智能