prompt笔记
prompt 不只是把一句话写漂亮,而是把模型输入组织清楚。
在真实项目中,Prompt 通常承担几件事:
- 告诉模型它是谁,要扮演什么角色。
- 告诉模型当前任务是什么,回答边界是什么。
- 告诉模型输出格式应该长什么样。
- 把用户问题、历史对话、检索结果、工具结果组合成一次完整输入。
import asyncio
import os
from dotenv import load_dotenv
from langchain.chat_models import init_chat_model
from langchain_core.messages import HunmanMessage,SystemMessage
load_dotenv()
model = init_chat_model(
model="qwen-plus",
model_provider="openai",
api_key=os.getenv("aliQwen-api"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
# 推荐写法。 显式 Message 对象,角色与字段最清晰
def demo_message_object():
messages = [
SystemMessage(content="你是一个专业的数学助手,回答要简短" ),
HumanMessage(content="你好,你是谁?"),
]
resp = model.invoke(messages)
print(type(resp), resp.content[:80] if resp.content else "")
# 字典列表:与 OpenAI Chat Completions 等 API 的请求体形状接近。
def demo_dict_list():
messages = [
{"role": "system", "content": "你是一个专业的数学助手,回答要简短"},
{"role": "user", "content": "你好,你是谁?"}
]
resp = model.invoke(messages)
print(type(resp), resp.content[:80] if resp.content else "")
# 元组列表:与 ChatPromptTemplate.from_messages 的写法一致。
def demo_tuple_list():
messages = [
("system", "你是一个专业的数学助手,回答要简短。"),
("human", "你好,你是谁?"),
]
resp = model.invoke(messages)
print(type(resp), resp.content[:80] if resp.content else "")
if __name__ == "__main__":
print("--- Message 对象列表 ---")
demo_message_objects()
print("--- 元组列表 ---")
demo_tuple_list()
print("--- 字典列表 ---")
demo_dict_list()
print("--- ainvoke + 元组 ---")
Prompt写法
1.纯字符串
resp = model.invoke("用一句话解释什么是 LangChain")
print(resp.content)
2. 模板+占位符
from langchain_core.prompts import PromptTemplate
template = PromptTemplate.from_template(
"用不超过 50 字介绍:{topic} 是什么?"
)
prompt_str = template.format(topic="LangChain")
resp = model.invoke(prompt_str)
print(resp.content)
3. 多角色消息列表
聊天模型更擅长理解“谁在说话”。把输入拆成 SystemMessage、HumanMessage、AIMessage 等不同角色,模型更容易正确理解上下文结构,而不是把所有东西都当成一大段平铺文本。
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
messages = [
SystemMessage(content="你是只回答技术问题的助手,回答要简短。"),
HumanMessage(content="什么是 LangChain?"),
# 多轮示例:
# AIMessage(content="LangChain 是用于编排 LLM 应用的框架……"),
# HumanMessage(content="它和直接调 API 有什么区别?"),
]
resp = model.invoke(messages)
print(resp.content)
在实际项目里,这种写法特别常见:
- 系统提示词放在
SystemMessage - 用户问题放在
HumanMessage - 历史回复可放回
AIMessage - 工具执行结果后续可用
ToolMessage
4. 元组列表和字典列表
- 元组列表:每项写成
(role, content) - 字典列表:每项写成
{"role": "...", "content": "..."}
import os
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0.0,
base_url=os.getenv("OPENAI_BASE_URL"),
api_key=os.getenv("OPENAI_API_KEY"),
)
messages_as_tuples = [
("system", "你是一个专业的数学助手"),
("user", "你好,你是谁"),
]
messages_as_dicts = [
{"role": "system", "content": "你是一个专业的数学助手"},
{"role": "user", "content": "你好,你是谁"},
]
resp = llm.invoke(messages_as_tuples)
print(type(resp))
print(resp.content)
resp2 = llm.invoke(messages_as_dicts)
print(resp2.content)
关于选择策略,可按下面的思路理解:
- 想学得最清楚:优先用
Message类 - 想写得最简洁:可以用元组列表
- 想和 OpenAI 风格请求体对齐:可以用字典列表
四类核心消息:
| 类型 | 说明 | 用途 |
| SystemMessage | 系统消息,通常用于规定角色、风格、边界、输出格式 | 设定人设、回答规则、拒答策略 |
| HumanMessage | 用户消息,对应用户当前输入 | 放用户问题、补充条件、后续追问 |
| AIMessage | 模型回复消息 | 保存上一轮回复,支持多轮上下文 |
| ToolMessage | 工具执行结果消息 | 把外部工具/函数的返回结果回传给模型 |
-
LangChain 的类名叫
HumanMessage,但很多平台的角色字段写的是user。这不是冲突,而是不同层的命名习惯。你可以把它们理解成同一个角色。 - 旧版本资料里可能会看到
FunctionMessage。在 LangChain 1.x 语境下,更常见的是ToolMessage
- SystemMessage 负责定义系统层规则.属于“长期规则”,而不是某一轮具体问题
- HumanMessage 负责承载当前用户问题

浙公网安备 33010602011771号