Langchain SQL聊天机器人:如何缓存初始提示词避免重复发送数据库Schema
解决Langchain+Ollama+Gemma2b重复发送数据库Schema的优化方案
以下是几种实用的优化方案,直接针对你遇到的重复发送Schema的问题:
1. 自定义Ollama模型嵌入固定Schema
把数据库Schema直接嵌入到Ollama模型的系统提示词中,生成专属自定义模型,后续调用无需再传递Schema:
- 创建
Modelfile文件,内容如下:
FROM gemma:2b SYSTEM """你是专业的数据库查询助手,需严格遵循以下数据库Schema生成SQL: [这里粘贴你的完整数据库Schema内容] 处理用户问题时,无需额外询问Schema细节,直接基于上述Schema生成正确查询。"""
- 执行命令创建自定义模型:
ollama create gemma-db-assistant -f Modelfile
- 在Langchain中调用这个自定义模型即可,后续请求只需传递用户问题和示例,无需携带Schema。
2. 预加载Schema到Langchain Prompt模板
在代码中一次性加载Schema,创建固定前缀的Prompt模板,避免每次请求重复拼接:
from langchain.prompts import PromptTemplate from langchain_community.utilities import SQLDatabase # 预加载数据库与Schema(仅执行一次) db = SQLDatabase.from_uri("你的数据库连接URI") fixed_schema = db.get_table_info() fixed_examples = """[这里粘贴你的固定示例内容]""" # 创建复用的Prompt模板 db_prompt = PromptTemplate( input_variables=["user_question"], template=f"""数据库Schema: {fixed_schema} 参考示例: {fixed_examples} 用户问题:{{user_question}} 请生成符合Schema的SQL查询。""" ) # 每次请求仅需传入用户问题 final_prompt = db_prompt.format(user_question="用户的具体问题")
3. 缓存固定Prompt前缀
利用Langchain的缓存机制,把包含Schema和示例的固定前缀缓存起来,每次请求仅拼接用户问题:
from langchain.cache import InMemoryCache from langchain.globals import set_llm_cache # 初始化缓存 set_llm_cache(InMemoryCache()) # 预生成固定前缀(仅执行一次) fixed_prefix = f"""数据库Schema: {fixed_schema} 参考示例: {fixed_examples}""" # 每次请求仅拼接用户问题 full_prompt = f"{fixed_prefix}\n用户问题:{user_question}"
4. 微调Gemma2b注入Schema知识(长期优化)
如果你的Schema相对稳定,可以用少量包含Schema和SQL查询的样本微调Gemma2b,让模型直接记住Schema细节,彻底避免每次传递:
- 准备微调数据集(JSON格式),每条数据包含用户问题和正确SQL:
[ {"question": "查询所有用户的姓名", "answer": "SELECT name FROM users;"}, {"question": "统计每个分类的商品数量", "answer": "SELECT category, COUNT(*) FROM products GROUP BY category;"} ]
- 执行Ollama微调命令:
ollama fine-tune gemma-db-finetuned -d dataset.json
- 微调完成后,调用这个模型时无需再传递Schema,模型会直接基于记忆中的Schema生成查询。
注意事项
如果你的数据库Schema非常庞大,超出Gemma2b的上下文窗口(2b版本通常为8k上下文),建议先对Schema进行精简:
- 只保留用户高频访问的表和字段
- 使用
SQLDatabase.get_table_info(tables=["table1", "table2"])指定需要加载的表
内容的提问来源于stack exchange,提问作者anekix
相关产品推荐
相关产品推荐

