LangChain中Prompt的Context占位符未更新问题及修改方法求助
问题:LangChain中Prompt的{context}占位符未被检索结果替换
问题描述
我基于LangChain编写了代码,期望通过检索操作更新Prompt中的{context}占位符,但实际运行后Prompt并未更新。注:我需要通过特定逻辑选择系统Prompt,因此使用占位符进行定义(示例未包含该逻辑)。
原代码
template = """Answer the question based only on the following context: {context} Question: """ prompt = ChatPromptTemplate.from_messages( [ MessagesPlaceholder(variable_name="system"), ("user", "{question}") ] ) chain = ( RunnablePassthrough.assign(system=lambda x: [SystemMessage(content=template)]) | RunnablePassthrough.assign(context=lambda x: retriever.invoke(x["question"])) | prompt ) chain.invoke({"question": "What I need to do to run FOSS scan?"})
运行结果
ChatPromptValue(messages=[SystemMessage(content='Answer the question based only on the following context:\n{context}\n\nQuestion:\n'), HumanMessage(content='What I need to do in order to run FOSS scan?')])
问题原因
- 执行顺序错误:先创建了包含未渲染模板的system消息,之后才获取context,此时system消息已固定,无法再替换{context}占位符。
- 模板未渲染:直接将原始template字符串传入SystemMessage,没有注入context变量完成格式化。
解决方案
核心调整
- 调换执行顺序:先获取检索到的context,再用它渲染system模板。
- 正确渲染模板:通过字符串格式化或LangChain的PromptTemplate,将context填充到模板中。
修正后代码
方式一:直接字符串格式化
template = """Answer the question based only on the following context: {context} Question: """ prompt = ChatPromptTemplate.from_messages( [ MessagesPlaceholder(variable_name="system"), ("user", "{question}") ] ) chain = ( # 先获取检索结果context RunnablePassthrough.assign(context=lambda x: retriever.invoke(x["question"])) # 用context渲染模板,生成SystemMessage | RunnablePassthrough.assign( system=lambda x: [SystemMessage(content=template.format(context=x["context"]))] ) | prompt ) chain.invoke({"question": "What I need to do to run FOSS scan?"})
方式二:使用LangChain PromptTemplate管理模板(更规范)
# 用PromptTemplate定义系统模板 system_prompt = PromptTemplate.from_template("""Answer the question based only on the following context: {context} Question:""") prompt = ChatPromptTemplate.from_messages( [ MessagesPlaceholder(variable_name="system"), ("user", "{question}") ] ) chain = ( RunnablePassthrough.assign(context=lambda x: retriever.invoke(x["question"])) | RunnablePassthrough.assign( system=lambda x: [SystemMessage(content=system_prompt.format(context=x["context"]))] ) | prompt )
内容的提问来源于stack exchange,提问作者Shurik
相关产品推荐
相关产品推荐

