Python中LangChain适配Ollama多LLM模型的系统提示实现方案
解决LangChain+Ollama跨模型提示格式适配问题,构建嘲讽型AI聊天机器人
问题场景
你需要用LangChain结合Ollama构建嘲讽用户的AI聊天机器人,要求无需修改核心逻辑即可切换Ollama中的LLM模型,但遇到了模型格式不兼容的问题:
- 使用mistral-7b-instruct时,AI重复生成"AI: "前缀,甚至自动续写Human角色的对话
- 使用mistral-7b-openorca时,AI输出额外的
<|im_end|>标记 - 手动在提示末尾添加"AI: "试图规避问题,反而加剧了重复前缀的生成
问题根源
核心问题在于未利用Ollama内置的模型提示模板,而是手动构建了不符合模型预期的提示结构:
- Ollama为每个模型预设了专属提示格式(角色前缀、终止标记等),终端交互时会自动套用,但当前代码手动拼接
Human:/AI:前缀,破坏了模型的格式预期 - 未设置对应模型的
stop参数,导致模型无法识别对话终止点,进而自动续写后续对话 - 手动添加的"AI: "前缀被模型视为生成内容的一部分,触发了重复生成逻辑
解决方案
1. 复用Ollama内置模板,放弃手动拼接提示
Ollama的Ollama类默认会使用模型自带的提示模板(template=None为默认值),无需手动构建Human:/AI:前缀。只需通过LangChain的标准聊天消息格式传递内容,LangChain会自动适配Ollama的模板要求。
2. 配置标准ChatPromptTemplate与对话记忆
使用SystemMessagePromptTemplate定义系统提示,结合MessagesPlaceholder维护对话历史,无需手动添加角色前缀。
3. 动态设置模型对应的stop参数
不同模型的终止标记不同,需根据当前使用的模型动态配置stop参数,让模型在生成完AI回复后停止:
- mistral-7b-instruct:终止标记为
["Human:"] - mistral-7b-openorca:终止标记为
["<|im_end|>", "Human:"]
完整代码示例
import os from langchain.callbacks.manager import CallbackManager from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler from langchain.llms import Ollama from langchain.prompts import ( ChatPromptTemplate, MessagesPlaceholder, SystemMessagePromptTemplate, HumanMessagePromptTemplate, ) from langchain.chains import LLMChain from langchain.memory import ConversationBufferMemory # 环境变量配置 BASE_URL = os.getenv("OLLAMA_BASE_URL", "http://localhost:11434") MODEL = os.getenv("OLLAMA_MODEL", "mistral:latest") SYSTEM_PROMPT = "You are an unhelpful and sarcastic AI that enjoys making fun of humans." AI_NAME = "SarcasticAI" # 模型对应的stop参数映射,可扩展更多模型 MODEL_STOP_TOKENS = { "mistral:latest": ["Human:"], "mistral-instruct:latest": ["Human:"], "mistral-openorca:latest": ["<|im_end|>", "Human:"], } # 获取当前模型的终止标记,默认用Human:兜底 stop_tokens = MODEL_STOP_TOKENS.get(MODEL, ["Human:"]) # 初始化Ollama LLM,复用内置模板并设置stop参数 llm = Ollama( base_url=BASE_URL, model=MODEL, system=SYSTEM_PROMPT, callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]), stop=stop_tokens ) # 构建标准聊天提示模板 prompt = ChatPromptTemplate( messages=[ SystemMessagePromptTemplate.from_template(SYSTEM_PROMPT), MessagesPlaceholder(variable_name="chat_history"), HumanMessagePromptTemplate.from_template("{text}") ] ) # 配置对话记忆,自动维护符合模型格式的历史记录 memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) # 创建对话链 conversation_chain = LLMChain( llm=llm, prompt=prompt, memory=memory, verbose=False ) # 交互式对话示例 while True: user_input = input("\nHuman: ") if user_input.lower() in ["exit", "quit"]: break print(f"\n{AI_NAME}:") conversation_chain.run(text=user_input)
效果说明
修改后的代码会:
- 自动适配Ollama内置的模型提示格式,无需手动处理角色前缀
- 通过
stop参数阻止模型自动续写Human对话或输出多余标记 - 对话记忆会自动维护符合模型格式的历史记录,不会出现"AI: AI: "的重复前缀
内容的提问来源于stack exchange,提问作者Tim Chiu
相关产品推荐
相关产品推荐

