LangChain实战:利用LangChain SQL Agent和GPT进行文档分析和交互

img

我最近接触到一个非常有趣的挑战,涉及到人工智能数字化大量文件的能力,并使用户可以在这些文件上提出复杂的与数据相关的问题,比如:

  • 数据检索问题: 涉及从数据库中获取特定数据点或数据集,例如“电子产品类别中有多少产品?” 或 “2021年第四季度总销售额是多少?”
  • 汇总查询: 需要对数据进行总结的问题,如计算平均值、求和、计数等,例如“所有已上架产品的平均价格是多少?”或“每个地区客户的总人数是多少?”
  • 数据关系探索: 探究不同数据实体之间关系的问题,比如"哪些客户购买了三种以上不同的产品?" 或 “列出上个月没有交付任何产品的所有供应商。”
  • 条件查询: 涉及条件或筛选器,比如“列出2022年发生在超过500美元交易额以上的所有交易” 或 “展示所有缺货商品。”

这些不是你可以仅通过使用RAG来解决的典型问题。相反,我们将利用LangChainSQLAgent从人类文本中生成复杂的数据库查询。

文档应包含具有大量规格说明的数据,以及更多流畅、自然语言描述等。

我们将执行以下步骤,最终能够提出关于大量文档的复杂问题:

  • 阅读所有PDF文档
  • 使用GPT分析每个文档的内容,将其解析为JSON对象。
  • 将这些对象写入SQLite获取其他数据库中,分布在多个表中。
  • 使用LangChain SQL代理程序通过自动生成SQL语句来提出问题。

备注:本文涵盖了涉及人工智能和数据处理的概念。为了获得最大价值,您应具备对Python编程能力、GPT模型接入能力、嵌入式技术了解、向量搜索和SQL数据库的基础理解以及使用能力。

使用 Python、LangChain 和 GPT 分析文档

我们将使用PythonLangChain来读取和分析PDF文档。我使用的 PythonPython 3.11

首先,我们安装环境所需要的依赖包:

shell复制代码 %pip install pypdf
 %pip install langchain
 %pip install langchain_openai
 %pip install sqlite3
python复制代码 # 导入 pdf 阅读器
 from pypdf import PdfReader
 # 导入langchain 的消息类型
 from langchain_core.messages import HumanMessage, SystemMessage
 # 导入 openAI
 from langchain_openai import ChatOpenAI

现在,让我们来深入研究 PDF 解析。我们的目标是使用 visitor_text 提取有意义的内容,同时忽略不太有用的信息,例如空行、页眉和页脚。

python复制代码 document_content = None
 
 def visitor_body(text, cm, tm, fontDict, fontSize):
     y = tm[5]
     if text and 35 < y < 770:
         page_contents.append(text)
 
 with open(f'./documents/ZMP_55852_XBO_1000_W_HS_OFR.pdf', 'rb') as file:
     pdf_reader = PdfReader(file)
     page_contents = []
     for page in pdf_reader.pages:
        # 提取PDF每页文本的内容
         page.extract_text(visitor_text=visitor_body)
     document_content = "\n".join(page_contents)
 
 print(document_content)

让我们查看解析后的文档:

python复制代码 Product family benefits
 _
 Short arc with very high luminance for brighter screen illumination
 _
 Constant color temperature of 6,000 K throughout the entire lamp lifetime
 _
 Easy to maintain
 _
 High arc stability
 _
 Instant light on screen thanks to hot restart function
 _
 Wide dimming range
 Product family features
 _
 Color temperature: approx. 6,000 K (Daylight)
 _
 Wattage: 45010,000 W
 _
 Very good color rendering index: Ra >
 Product datasheet
 
 
  
 XBO 1000 W/HS OFR
 XBO for cinema projection | Xenon short-arc lamps 45010,000 W
 
 [..] 
 
 Packaging unit
 
 (Pieces/Unit)
 Dimensions (length
 
 x width x height)
 Volume
 Gross weight
 4008321082114
 XBO 1000 W/HS OFR
 Shipping carton box
 
 1
 410 mm x 184 mm x
 
 180 mm
 13.58 dm³
 819.00 g
 
 [..]

在解析的内容中,显而易见地发现它缺乏结构 — 表格不连贯,相关实体分散。

我们使用 GPT 重新帮我们整理文档的内容:

  • 我们将指示GPT将解析的数据格式化为一个结构化JSON对象。
  • 通过提供一份解析数据的示例,以及在前面加上<<<的提示,我们可以引导GPT理解并整理文档。
  • 利用OpenAI Chat API,我们将请求GPT从一组新的解析产品数据中生成一个JSON对象。

让我们构建一条深思熟虑的系统消息来启动这个过程。我们将以清晰的指令为GPT开头,接着呈现解析后的数据作为背景,并夹杂目标性提示来完善输出:

认真观察我们如何整合各种提示来塑造我们所需的精确JSON输出。

txt复制代码 你会分析产品描述,将其导出为 JSON 格式。我会向您展示一个产品数据表,并用 <<< 描述各个 JSON 对象和属性。然后您可以从另一个产品数据表中创建一个 JSON 对象。
 
 >>> Example product:
 
 Product family benefits <<< benefits (string[])
 _
 Short arc with very high luminance for brighter screen illumination <<< benefits.[*]
 _
 Constant color temperature of 6,000 K throughout the entire lamp lifetime <<< benefits.[*]
 
 [..]
 
 _
 Wide dimming range <<< benefits.[*]
 Product family features <<< product_family (object)
 _
 Color temperature: approx. 6,000 K (Daylight) <<< product_family.temperature = 6000
 _
 Wattage: 450…10,000 W <<< product_family.watts_min = 450, product_family.watts_max = 10000
 _
 Very good color rendering index: Ra >
 Product datasheet
 
 
  
 XBO 1000 W/HS OFR <<< name
 XBO for cinema projection | Xenon short-arc lamps 450…10,000 W <<< description
 
 [..]
 
 Technical data
 Electrical data <<< technical_data (object)
 Nominal current
 50 A <<< technical_data.nominal_current = 50.00
 Current control range
 30…55 A <<< technical_data.control_range = 30, technical_data.control_range = 55
 Nominal wattage
 1000.00 W <<< technical_data.nominal_wattage = 1000.00
 Nominal voltage
 19.0 V <<< technical_data.nominal_voltage = 19.0
 Dimensions & weight <<< dimensions (object)
 
 [..]
 
 Safe Use Instruction
 The identification of the Candidate List substance is <<< environmental_information.safe_use (beginning of string)
 
 sufficient to allow safe use of the article. <<< environmental_information.safe_use (end of string)
 Declaration No. in SCIP database
 22b5c075-11fc-41b0-ad60-dec034d8f30c <<< environmental_information.scip_declaration_number (single string!)
 Country specific information
 
 [..]
 
 Shipping carton box
 
 1
 410 mm x 184 mm x <<< packaging_unity.length = 410, packaging_unit.width = 184
 
 180 mm <<< packaging_unit.height = 180
 
 [..]
 """

我的 prompt 是不同方法的集合:

  • <<< benefits(字符串[])— 这里开始了一个字符串列表。
  • <<< benefits.[*] — 这行属于字符串列表。
  • <<< product_family(对象)— 这里开始了一个对象。
  • <<< product_family.temperature = 6000 — 这行是对象的整数属性
  • <<< product_family.watts_min = 450,product_family.watts_max = 1000 — 这一行是两个整数属性(例如,当有类似功率:450…10,000 W 的语句时)

在这里你可以完全发挥创意,尝试任何对你有意义的东西。而且需要多次调试 prompt 的内容以适应你的应用场景。

注意: 这里 prompt 最好还是英文的好, 最好不要中文和英文夹着来。

请将以下文本翻译成中文:

要翻译的文字:

  • <<< 将其翻译成另一种语言。
  • <<< 提供摘要或提供项目符号下的整个句子。
  • <<< 将数据拆分为名字和姓名。

测试 prompt

现在我们是时候测试一下 GPT 了,看看它是否能够完美地将我们混乱的 PDF 文本转换成一个整洁的 JSON 对象。

GPT-3.5-Turbo的0125版本在以JSON等请求格式响应时具有更高的准确性,这非常适合我们的情况! 我们已经准备好了system_message,并将其与document_content配对作为输入:

python复制代码 # 初始化 OpenAI Model
 chat = ChatOpenAI(model_name='gpt-3.5-turbo-0125', temperature=0)
 
 def convert_to_json(document_content):
     messages = [
         # 这里是系统的角色设定
         SystemMessage(
             content=system_message
         ),
         # 这里是我们的输入内容
         HumanMessage(
             content=document_content
         )
     ]
     # 构建 langchain 的链式
     answer = chat.invoke(messages)
     return answer.content
 
 json = convert_to_json(document_content)
 # json 就是 OpenAI Model 返回的内容:
 print(json)

一切就绪,我们看一下我们得到的JSON输出了:

json复制代码 {
   
     "name": "XBO 1000 W/HS OFR",
     "description": "XBO for cinema projection | Xenon short-arc lamps 450…10,000 W",
     "applications": [
         "Classic 35 mm film projection",
         "Digital film and video projection",
         "Architectural and effect light (“Light Finger”)",
         "Sunlight simulation"
     ],
     "technical_data": {
   
         "nominal_current": 50.00,
         "control_range_min": 30,
         "control_range_max": 55,
         "nominal_wattage": 1000.00,
         "nominal_voltage": 19.0
     },
     "dimensions": {
   
         "diameter": 40.0,
         "length": 235.0,
         "length_base": 205.00,
         "light_center_length": 95.0,
         "electrode_gap": 3.6,
         "weight": 255.00
     },
     "operating_conditions": {
   
         "max_temp": 230,
         "lifespan": 
<think>好的,用户现在问的是如何直接加载SQL Server中的数据交给LangChain来回答问题。首先,我需要理解用户的需求。他们可能已经熟悉了从SQL Server检索数据的基本方法,现在想要结合LangChain这个框架来进行更高级的处理,比如生成回答或分析数据。 接下来,我要回顾之前的对话历史。用户之前询问过如何从SQL Server检索数据,我介绍了基本的SQL查询、连接方法、工具推荐等。现在他们的问题更深入,涉及与LangChain的集成,所以我需要将之前的SQL知识扩展到与LangChain结合使用的场景。 我需要考虑用户可能的使用场景。用户可能是开发者或数据分析师,希望自动化处理数据库中的数据,比如自动生成报告、问答系统或数据驱动的聊天机器人。他们可能希望减少手动处理数据的时间,直接通过自然语言与数据库交互。 接下来,我需要思考如何将SQL Server的数据加载到LangChain中。LangChain通常处理文本数据,所以用户可能需要将查询结果转换成合适的格式,比如文本或文档对象。同时,需要考虑数据隐私安全,确保在传输处理过程中数据不被泄露。 可能的步骤包括:建立数据库连接、执行SQL查询、将结果转换为文本或文档、使用LangChain的组件(如链或代理)处理这些数据。此外,可能需要使用LangChain文档加载器或自定义处理流程。 用户可能还关心性能优化,比如如何处理大量数据,是否需要分页查询,或者使用缓存机制。另外,错误处理也是关键,比如数据库连接失败或查询超时等情况。 需要提到具体的工具库,比如Python中的pyodbc或SQLAlchemy来连接SQL Server,LangChainSQLDatabaseLoader或自定义Document类。还要给出代码示例,让用户更容易理解实现步骤。 还要考虑用户可能的进阶需求,比如结合大模型(如GPT)生成更自然的回答,或者使用LangChainAgent进行自动化查询生成。这时可能需要介绍如何将查询结果输入到语言模型中,并处理返回的结果。 最后,需要提醒用户注意安全措施,比如使用环境变量存储敏感信息(如数据库密码),参数化查询防止SQL注入,以及数据处理的法律合规性。此外,性能监控日志记录也是实际应用中不可忽视的部分。</think>以下是使用LangChain直接集成SQL Server数据的技术方案(含数学表达式说明): $$ \text{数据流模型}:DB \xrightarrow{\text{ODBC}} Python \xrightarrow{\text{Document转换}} LangChain \xrightarrow{\text{LLM处理}} 输出 $$ **1. 建立数据连接** ```python from langchain_community.utilities import SQLDatabase import pyodbc # 构建连接字符串(参数化更安全) conn_str = ( r'DRIVER={SQL Server};' r'SERVER=your_server;' r'DATABASE=your_db;' r'UID=your_user;' r'PWD=your_pwd;' ) # 创建LangChain SQLDatabase对象 db = SQLDatabase.from_uri(f"mssql+pyodbc:///?odbc_connect={conn_str}") ``` **2. 数据加载与向量化** ```python from langchain_community.document_loaders import SQLDatabaseLoader from langchain_openai import OpenAIEmbeddings # 执行查询并加载为文档对象 loader = SQLDatabaseLoader( db, query="SELECT TOP 100 ProductID, ProductName, UnitPrice FROM Products", metadata_columns=["ProductID"] ) docs = loader.load() # 向量化存储(假设使用余弦相似度检索) $$ \cos(\theta) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} $$ embeddings = OpenAIEmbeddings() vector_store = FAISS.from_documents(docs, embeddings) ``` **3. 构建问答链** ```python from langchain.chains import SQLDatabaseChain from langchain_openai import ChatOpenAI # 创建带SQL解释能力的链 llm = ChatOpenAI(temperature=0) db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True) # 示例自然语言查询 response = db_chain.invoke("找出价格高于平均价的前5个产品") print(response['result']) ``` **4. 高级处理模式** ```python from langchain.agents import create_sql_agent from langchain.agents.agent_toolkits import SQLDatabaseToolkit # 创建智能代理处理复杂查询 toolkit = SQLDatabaseToolkit(db=db, llm=llm) agent = create_sql_agent( llm=llm, toolkit=toolkit, verbose=True ) # 执行多步骤分析 agent.run("统计每个类别产品的平均价格,并列出高于该平均价的产品") ``` **性能优化策略**: 1. 查询缓存机制: $$ \text{缓存命中率} = \frac{\text{缓存命中次数}}{\text{总请求次数}} \times 100\% $$ ```python from langchain.cache import SQLAlchemyCache import langchain langchain.llm_cache = SQLAlchemyCache(engine) ``` 2. 分页加载策略: ```python def batch_loader(page_size=1000): offset = 0 while True: query = f"SELECT * FROM Products ORDER BY ProductID OFFSET {offset} ROWS FETCH NEXT {page_size} ROWS ONLY" docs = SQLDatabaseLoader(db, query).load() if not docs: break yield docs offset += page_size ``` **安全增强措施**: 1. 查询白名单校验: ```python ALLOWED_PATTERNS = [r"^SELECT\s.*", r"^WITH\s.*"] def validate_query(query): if not any(re.match(p, query, re.IGNORECASE) for p in ALLOWED_PATTERNS): raise ValueError("非法查询语句") ``` 2. 数据脱敏处理: ```python from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter( chunk_size=2000, chunk_overlap=200, length_function=len, is_separator_regex=False, ) sanitized_docs = text_splitter.split_documents(docs) ``` **典型应用场景**: 1. 动态报表生成: $$ \text{报表生成时间} = T_{\text{查询}} + T_{\text{处理}} + T_{\text{渲染}} $$ 2. 自然语言BI分析: ```python agent.run("对比Q3Q4的销售额增长率,用Markdown表格展示前五名产品") ``` 3. 实时决策支持: ```python response = agent.run("根据当前库存销售趋势,建议需要补货的产品") ``` **监控指标**: - 查询响应时间分布:$$ P(t \leq T) = \int_{0}^{T} f(t)dt $$ - 结果准确率:$$ \text{准确率} = \frac{\text{正确响应数}}{\text{总查询数}} \times 100\% $$ - 资源消耗比:$$ \text{资源比} = \frac{\text{CPU使用量}}{\text{返回结果数}} $$ 建议通过Azure Monitor或Prometheus监控系统运行状态,使用LangSmith进行LLM交互的跟踪分析。对于关键业务系统,建议采用Always On可用性组实现数据库高可用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值