LangChain 目前支持三种类型模型
LLMs(大语言模型):技术范畴统称,指大量参数、海量文本训练的 Transformer 架构模型。核心能力是理解和生成自然语言。
聊天模型:应用范畴的细分,专为对话场景优化的 LLMs。核心能力是模拟人类对话的轮次交互,主要服务于聊天场景。
文本嵌入模型:接受文本作为输入,输出文本的向量。
from langchain_community.llms.tongyi import Tongyi
# 不用qwen3-max,因为qwen3-max是聊天模型,qwen-max是大语言模型
# 这里的内容可能过时了,先学着
model = Tongyi(model="qwen-max")
# 调用invoke方法向模型提问,这会一次性输出完整结果
res = model.invoke(input="你好")
print(res)
# 调用stream方法向模型提问,逐段返回结果,流失输出
res = model.stream(input="hi")
for chunk in res:
# print 默认结尾加一个换行符 \n,为了改成字符串拼接所以end=""
# print() 默认先把内容存缓冲区,等缓冲区满了再吐出来
# flush=True 的意思是强制立即输出,不让它攒,来一个字就显示一个字。
print(chunk, end="", flush=True)model = ChatTongyi(model="qwen3-max")
# 现在角色更推荐用 system user assistant
# 而非 system human ai
messages = [
("system", "你是一个边塞诗人"),
("human", "写一首唐诗"),
("ai","锄禾日当午,汗滴禾下土"),
("human","按照上一个回复的格式,再写一首唐诗")
]
for chunk in model.stream(input = message):
print(chunk.content, end="", flush=True)
类似于 TypeScript 里的模板字符串。分为 one-shot 提示词模板和 few-shot 提示词模板。
from langchain_core.prompt import PromptTemplate
from langchain_community.lls.tongyi import Tongyi
# 为了加入chain,所以不只是模版字符串
# one-shot
promtp_template = PromptTemplate.from_template(
"我的邻居姓{lastname},刚生了{gender},你帮我取个名字"
)
# 注入提示词
pompt_text = promtp_template.format(lastname="张", gender="女儿")
# few-shot
example_template = PromptTemplate.from_template("单词:{word},反义词:{antonym}")
example_data = [
{"word": "大", "antonym": “小”},
{"word": "上", "antonym": "下"}
]
few_shot_prompt = FewShotPromptTemplate(
example_prompt=example_template,
examples=example_data,
prefix="给出给定词的反义词,有如下实例",
suffix="基于示例告诉我:{input_word}的反义词是?",
input_variables=['input_word']
)
# 最终提示词
prompt_text=few_shot_prompt.invoke(input={"input_word":"左"}).to_string()
model = Tongyi("qwen-max")
res = model.invoke(input = promp_text)
# PromptTemplate可以加入chain
chain = prompt_template | model
chain.invoke(input = {"lastname": "张" , "gender": "女儿"})Q:Python 调用异步函数不需要 await 吗?
A: model.invoke(...) 是同步调用,不需要 await,底层已经帮你处理了。但如果用的是异步接口,那就得 await。
Q:Python 传参要显式声明参数名吗?
A:不需要。Python 支持位置参数和关键字参数两种。同一个函数两种混着传也行。社区推荐的做法反而是越多用关键字参数越好,因为可读性好。
def greet(greeting, name):
print(f"{greeting}, {name}")
# 位置传参
greet("你好", "丽") # 你好, 丽
# 关键字传参
greet(name="丽", greeting="你好")
# 混着来(位置必须在关键字前面)
greet("你好", name="丽")Q:Python 的 from module import something 和 TypeScript 的 import something from module 正好相反。社区如何看待这件事?
A:有人调侃说"TypeScript 程序员第一周写 Python 时一定会写错方向",但认真说,Python 社区觉得 from module import something 的语序更符合自然语言——"从 module 拿 something"。两边的设计哲学不同,没有对错。
Q:Python 里注释要怎么写?我看到有的用 # 有的用 """,有什么区别?循环里的注释也要前置空格吗?
A:# 是真正的注释。 解释器完全忽略它。""" 是字符串字面量,不是注释。它本质上是创建了一个没赋值给任何变量的字符串。只是因为它"写了但不影响执行",看起来像注释而已,通常用来写多行文档。""" 写的文档——可以用 .__doc__ 取出来。循环/函数内部的注释要前置空格,因为 Python 用缩进确定代码块。注释跟着代码走,缩进要和所在代码块对齐。
def greet(name):
"""向某人打招呼"""
return f"你好{name}"
print(greet.__doc__) # 输出: 向某人打招呼
for i in range(5):
# 没有缩进 → 报错 IndentationError: unexpected indent
print(i)Q:Python 声明变量直接写变量名就行吗?不区分变量/常量吗?
A:不区分。 Python 没有真正的常量。社区用全大写命名表示常量,但只是约定。
Q:Python 的 True 要大写吗?
A:Python 把 True 和 False 当成了关键字(严格来说是内置常量),大小写敏感。这两个内置常量其实是 int 的子类,True == 1、False == 0,甚至可以当数字用。
print(True + True) # 2Q:中括号是数组吗?数组对类型敏感吗?里面的小括号是什么
A:是数组。Python 里叫列表(list)。列表对类型不敏感,可以随便放东西。比如:
my_list = [42, "hello", True, 3.14, None, [1, 2, 3]]A:小括号是元组,可以理解成是一旦创建就不能改的数组。messages 里面用元组是因为想规定消息格式,语义上表示"这两个东西是绑定在一起的,不应该分开修改"。
Q:Python 字符串引号敏感吗?模板字符串有哪些特性
A:Python 里 'hello' 和 "hello" 完全等价。在字符串前加 f 或 F,大括号 {} 里可以直接写 Python 表达式,运行时求值并嵌入。模板字符串有很多特性,比如任意表达式/格式化控制/字典访问/调试模式等,以后再说。
name = "明日香"
age = 14
print(f"我是{name},{age}岁。")
# 输出: 我是明日香,14岁。