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. 多角色消息列表

聊天模型更擅长理解“谁在说话”。把输入拆成 SystemMessageHumanMessageAIMessage 等不同角色,模型更容易正确理解上下文结构,而不是把所有东西都当成一大段平铺文本。

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 工具执行结果消息 把外部工具/函数的返回结果回传给模型
  1. LangChain 的类名叫 HumanMessage,但很多平台的角色字段写的是 user这不是冲突,而是不同层的命名习惯。你可以把它们理解成同一个角色。

  2. 旧版本资料里可能会看到 FunctionMessage在 LangChain 1.x 语境下,更常见的是 ToolMessage
  • SystemMessage 负责定义系统层规则.属于“长期规则”,而不是某一轮具体问题
  • HumanMessage 负责承载当前用户问题

 

posted @ 2026-04-29 16:39  幻影之舞  阅读(4)  评论(0)    收藏  举报