primefaces做网站,宁波做网站软件,的推网站模板,自己做网站需要固定ip吗基于之前的本地知识库问答系统#xff0c;组长说RAG以后迁移到更大的数据库上面会特别慢#xff0c;建议我用Text2SQL检索更加快。整体流程#xff1a;Text2SQL#xff1a;大脑SQLExecutor#xff1a;手ORM#xff1a;骨架与内脏自然语言提问被大模型解析为SQL语句#…基于之前的本地知识库问答系统组长说RAG以后迁移到更大的数据库上面会特别慢建议我用Text2SQL检索更加快。整体流程Text2SQL大脑SQLExecutor手ORM骨架与内脏自然语言提问被大模型解析为SQL语句Text2SQL)之后进入PostgreSQL查询返回JSON技术栈FastAPIAPI 服务DeepSeekText2SQLPostgreSQL业务数据SQLModelORMpgvector向量字段预留 RAG 扩展一、SQLModel的作用1、定义表格在db_models.py中完整定义了fourth_census表class FourthCensus(SQLModel, tableTrue): 序号: Optional[int] Field(primary_keyTrue) 名称: Optional[str] 编号: Optional[str] 调查结果: Optional[str] ...模型生成 SQL 的前提是人类先搞清楚字段世界Text2SQL 才能更好的理解数据表格结构查询更加准确。2、中文字段与特殊符号处理时间的列名为面积平方米产权单位人损毁原因-自然因素这些在SQL语句里面无法直接使用需要经过转化定义全部字段合法性面积_平方米_: Optional[str] Field( sa_columnColumn(面积平方米, String) )3、预留pgvector相似检索select(FourthCensus).order_by( FourthCensus.vector.cosine_distance(query_vec) )4、ORM 负责连接、事务与稳定性with Session(engine) as session: result session.execute(text(sql))管理数据库连接自动关闭连接异常安全可控事务边界二、text2SQL主要利用大模型自然语言理解能力转化为SQL语句以下为提示词也请大家给我更好的提示词写法。prompt f 你是 PostgreSQL 专家。 数据库表名fourth_census 可用字段及说明 {FIELD_DESCRIPTION} 用户问题 {question} 请仅生成 SQL 查询返回前 {limit} 条记录带 LIMIT。不要解释。当查询中文分类字段时请优先使用 LIKE 而不是等号 我将表格说明表也写进提示词方便大模型更快的对应到所需要的列。## 一、基础识别字段 序号表内顺序编号用于记录排序不作为业务唯一标识 名称不可移动文物的名称 编号文物普查或登记使用的唯一编号 调查结果本次调查相较前次调查的总体结论如无变更、发生变更等 ## 二、行政区划与人员信息 省文物所在地所属省级行政区 市文物所在地所属地级市 县文物所在地所属县级行政区 调查人本次实地调查的人员 调查日期实地调查开展的日期 审定人对调查结果进行审定的人员 审定日期审定工作的完成日期 抽查人实施抽查复核的人员 抽查日期抽查复核的日期 ## 三、位置与空间信息 地址及位置文物的详细地址及具体方位描述 高程海拔文物所在地的海拔高度如有记录表格一些表头也告诉大模型SCHEMA_PROMPT 序号, 名称, 编号, 调查结果, 省, 市, 县, 调查人, 调查日期, 审定人, 审定日期, 抽查人, 抽查日期, 地址及位置, 高程海拔,系统提示词为SYSTEM_PROMPT 你是 PostgreSQL Text2SQL 引擎。 只生成 SQL不解释、不补充数据。 表名为 fourth_census字段必须严格按照 schema 使用。 不使用 RAG 或向量检索。 有了这些提示词可以更好的约束SQL的生成。三、项目代码# -*- coding: utf-8 -*- 文件名db_models.py 功能 配置 PostgreSQL 数据库连接 定义文物普查表 ORMFourthCensus 技术栈 - SQLModel ORM - pgvector 说明 - FourthCensus 含向量字段 vector用于 pgvector 检索 from typing import Optional, List from sqlmodel import SQLModel, Field, create_engine from sqlalchemy import Column, String from pgvector.sqlalchemy import Vector # ---------- 数据库配置 ---------- DB_HOST localhost DB_PORT 5432 DB_NAME data DB_USER postgres DB_PASSWORD 12345 DATABASE_URL fpostgresqlpsycopg2://{DB_USER}:{DB_PASSWORD}{DB_HOST}:{DB_PORT}/{DB_NAME} engine create_engine(DATABASE_URL, echoFalse) # ---------- 文物普查表 ---------- class FourthCensus(SQLModel, tableTrue): __tablename__ fourth_census 序号: Optional[int] Field(defaultNone, primary_keyTrue) 名称: Optional[str] None 编号: Optional[str] None 调查结果: Optional[str] None 省: Optional[str] None 市: Optional[str] None 县: Optional[str] None 调查人: Optional[str] None 调查日期: Optional[str] None 审定人: Optional[str] None 审定日期: Optional[str] None 抽查人: Optional[str] None 面积_平方米_: Optional[str] Field(defaultNone, sa_columnColumn(面积平方米, String)) 年代: Optional[str] None 统计年代: Optional[str] None 大类: Optional[str] None 小类: Optional[str] None 所有权: Optional[str] None 产权单位_人_: Optional[str] Field(defaultNone, sa_columnColumn(产权单位人, String)) 使用单位_人_: Optional[str] Field(defaultNone, sa_columnColumn(使用单位人, String)) 损毁原因_自然因素: Optional[str] Field(defaultNone, sa_columnColumn(损毁原因-自然因素, String)) 损毁原因_人为风险: Optional[str] Field(defaultNone, sa_columnColumn(损毁原因-人为风险, String))# -*- coding: utf-8 -*- 文件名deepseek_client.py 功能 调用 DeepSeek API 生成 SQL import requests API_URL https://ark.cn-beijing.volces.com/api/v3/chat/completions MODEL deepseek-v3-250324 API_KEY 9b6b8bd0- -4e53-ae63-91f89dbbddb8 def call_deepseek(messages): headers { Authorization: fBearer {API_KEY}, Content-Type: application/json } payload { model: MODEL, messages: messages, temperature: 0 } resp requests.post(API_URL, jsonpayload, headersheaders, timeout30) resp.raise_for_status() data resp.json() return data[choices][0][message][content].strip()# -*- coding: utf-8 -*- 文件名system_prompt.py 功能 Text2SQL 系统约束 SYSTEM_PROMPT 你是 PostgreSQL Text2SQL 引擎。 只生成 SQL不解释、不补充数据。 表名为 fourth_census字段必须严格按照 schema 使用。 不使用 RAG 或向量检索。 # -*- coding: utf-8 -*- 文件名schema_prompt.py 功能 fourth_census 字段说明用于 Text2SQL SCHEMA_PROMPT 序号, 名称, 编号, 调查结果, 省, 市, 县, 调查人, 调查日期, 审定人, 审定日期, 抽查人, 抽查日期, 地址及位置, 高程海拔, 是否整体迁移并在新迁址并在新迁址地域范围内, 变更消失情况, 变更消失情况2, 是否已公布保护范围, 是否公布建设控制地带, 文物级别, 面积平方米, 年代, 统计年代, 大类, 小类, 所有权, 产权单位人, 使用单位人, 上级管理机构, 使用用途, 所属行业, 是否开放, 现状评估, 保护措施, 影响因素, 文物构成, 简介, 专题类别, 损毁原因的风险描述, 损毁原因-自然因素, 损毁原因-人为风险, 备注, 其他名录, 审核意见, 抽查结论, 所属文物保护单位名称 # -*- coding: utf-8 -*- 文件名text2sql.py 功能 调用 DeepSeek API 将自然语言问题生成 SQL import requests import os DEEPSEEK_API_URL https://ark.cn-beijing.volces.com/api/v3/chat/completions DEEPSEEK_MODEL deepseek-v3-250324 DEEPSEEK_API_KEY os.getenv(DEEPSEEK_API_KEY, 9b6b8bd0- -4e53-ae63-91f89dbbddb8) # 完整字段说明表 FIELD_DESCRIPTION ## 一、基础识别字段 序号表内顺序编号用于记录排序不作为业务唯一标识 名称不可移动文物的名称 编号文物普查或登记使用的唯一编号 调查结果本次调查相较前次调查的总体结论如无变更、发生变更等 ## 二、行政区划与人员信息 省文物所在地所属省级行政区 市文物所在地所属地级市 县文物所在地所属县级行政区 调查人本次实地调查的人员 调查日期实地调查开展的日期 审定人对调查结果进行审定的人员 审定日期审定工作的完成日期 抽查人实施抽查复核的人员 抽查日期抽查复核的日期 ## 三、位置与空间信息 地址及位置文物的详细地址及具体方位描述 高程海拔文物所在地的海拔高度如有记录 def generate_sql(question: str, limit: int 4000) - str: if not DEEPSEEK_API_KEY: return DeepSeek API Key 未配置 prompt f 你是 PostgreSQL 专家。 数据库表名fourth_census 可用字段及说明 {FIELD_DESCRIPTION} 用户问题 {question} 请仅生成 SQL 查询返回前 {limit} 条记录带 LIMIT。不要解释。当查询中文分类字段时请优先使用 LIKE 而不是等号 headers { Authorization: fBearer {DEEPSEEK_API_KEY}, Content-Type: application/json } payload { model: DEEPSEEK_MODEL, messages: [{role: user, content: prompt}] } try: resp requests.post(DEEPSEEK_API_URL, jsonpayload, headersheaders, timeout30) if resp.status_code ! 200: return fDeepSeek API Error ({resp.status_code}): {resp.text} data resp.json() sql data.get(choices, [{}])[0].get(message, {}).get(content, ) return sql.strip() except Exception as e: return fDeepSeek API Exception: {str(e)}from sqlmodel import Session from sqlalchemy import text from db_models import engine def run_sql(sql: str): 执行 SQL 并返回列名和 Row 对象列表 支持 text(sql) 查询 try: with Session(engine) as session: result session.execute(text(sql)) rows result.mappings().all() # 使用 mappings() 返回字典形式 if not rows: return [], [] columns list(rows[0].keys()) return columns, rows except Exception as e: print(SQL 执行异常:, e) return [], []# -*- coding: utf-8 -*- 文件名response_formatter.py 功能 格式化 SQL 查询结果为 JSON def format_result(columns, rows): 将 SQL 查询结果Row 对象转换为字典列表 formatted [] for r in rows: record {c: r[c] for c in columns if c ! vector} # Row 对象可以用列名访问 formatted.append(record) return formatted# -*- coding: utf-8 -*- 文件名app.py 功能 FastAPI 服务入口 支持 Text2SQL 问题 - SQL - 查询数据库 - 返回完整字段 增加启动和请求报错提示 from fastapi import FastAPI, Request from fastapi.responses import JSONResponse from pydantic import BaseModel from text2sql import generate_sql from sql_executor import run_sql from response_formatter import format_result import traceback app FastAPI(title四普 Text2SQL API) class QueryRequest(BaseModel): question: str app.post(/query) def query(req: QueryRequest): try: print(收到请求:, req.question) # 1. 生成 SQL sql generate_sql(req.question) print(原始 SQL 输出:, sql) if not sql: return {error: 模型未生成 SQL} # 2. 清洗 Markdown SQL核心修复 sql sql.strip() if sql.startswith(): sql ( sql.replace(sql, ) .replace(, ) .strip() ) print(清洗后 SQL:, sql) # 3. 校验 SQL if not sql.lower().startswith(select): return { error: 生成 SQL 失败非 SELECT, content: sql } # 4. 执行 SQL columns, rows run_sql(sql) # 5. 格式化返回 answer format_result(columns, rows) return { sql: sql, answer: answer } except Exception as e: print(查询处理异常:\n, traceback.format_exc()) return { error: 查询处理异常, detail: str(e) } app.get(/) def root(): return {status: ok, service: 四普 Text2SQL API} # 全局异常捕获 app.exception_handler(Exception) async def all_exception_handler(request: Request, exc: Exception): print(f全局异常: {request.url}\n{traceback.format_exc()}) return JSONResponse( status_code500, content{ error: 服务器内部异常, detail: str(exc) }, )requestments.txtfastapi uvicorn sqlmodel sqlalchemy psycopg2-binary requests pgvector