如何确保LangChain生成稳定正确输出?解决SQL查询链结果不一致问题
问题解决:LangChain SQL查询链输出不一致及稳定性优化
问题原因
你遇到的输出不一致,核心原因是create_sql_query_chain的默认prompt专为**查询类SQL(SELECT)**设计,对DDL操作(如CREATE TABLE)的处理逻辑无明确约束。即便temperature设为0,LLM对模糊需求的理解仍可能出现偏差,导致不同响应。
解决办法
1. 自定义Prompt明确任务逻辑
修改默认prompt,让LLM清晰知晓如何处理创建表这类请求。例如明确要求:先检查表是否存在,若不存在则返回符合数据库规范的CREATE语句,若存在则提示表已存在。
示例代码:
from langchain.chains import create_sql_query_chain from langchain_core.prompts import PromptTemplate from langchain_openai import ChatOpenAI from langchain_community.utilities import SQLDatabase import os def return_query(question): db = SQLDatabase.from_uri(os.getenv("POSTGRES_URL")) llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) # 自定义Prompt custom_prompt = PromptTemplate.from_template(""" 你是PostgreSQL数据库专家,根据用户问题和数据库schema执行以下操作: 1. 如果用户要求创建表: - 先检查数据库中是否已存在该表 - 若存在,返回"该表已存在" - 若不存在,返回符合PostgreSQL规范的CREATE TABLE语句,包含常用字段(如id、name等) 2. 如果用户要求查询数据: - 根据数据库schema生成正确的SELECT查询语句 数据库schema信息:{schema} 用户问题:{question} """) chain = create_sql_query_chain(llm, db, prompt=custom_prompt) response = chain.invoke({"question": question}) return response
2. 添加意图识别前置判断
在调用SQL链之前,先识别用户意图是查询还是DDL操作,分分支处理,避免LLM模糊判断。
示例代码:
def detect_intent(question): # 规则匹配识别意图,也可使用LLM实现更精准识别 intent_keywords = {"create": "ddl", "drop": "ddl", "alter": "ddl", "select": "query", "find": "query", "get": "query"} for keyword, intent in intent_keywords.items(): if keyword.lower() in question.lower(): return intent return "unknown" def return_query(question): intent = detect_intent(question) db = SQLDatabase.from_uri(os.getenv("POSTGRES_URL")) llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) if intent == "ddl": if "create table" in question.lower(): table_name = question.lower().split("create table")[-1].strip() # 检查表是否存在 exists = db.run(f"SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = '{table_name}');") if "true" in exists.lower(): return f"表 {table_name} 已存在。" else: return f"""CREATE TABLE {table_name} ( id SERIAL PRIMARY KEY, name TEXT NOT NULL, email TEXT NOT NULL, age INTEGER, major TEXT );""" elif intent == "query": chain = create_sql_query_chain(llm, db) return chain.invoke({"question": question}) else: return "无法识别请求类型,请明确需求。"
3. 强制输出格式约束
在prompt中要求LLM必须返回指定格式内容,比如用JSON区分结果类型,减少歧义。
示例prompt片段:
请严格按照以下JSON格式返回结果: {{ "type": "query"|"ddl"|"info", "content": "对应的SQL语句或提示信息" }}
4. 输出验证与修正
对LLM返回的结果进行语法校验和逻辑验证,确保符合预期。比如用sqlparse库检查SQL语法,或执行前置校验(如检查表是否存在)。
确保输出稳定的核心思路
- 明确任务边界:将查询和DDL操作分开处理,避免LLM处理超出链设计目标的任务
- 强化prompt约束:给LLM清晰的规则和输出格式,减少模糊空间
- 前置逻辑判断:用规则或轻量LLM调用提前识别意图,避免不必要的猜测
- 输出校验:添加结果验证步骤,确保最终输出符合需求
内容的提问来源于stack exchange,提问作者user3222101
相关产品推荐
相关产品推荐

