langgraph构建基于数据库的RAG智能体

        一般情况下构建RAG都是基于向量库构建,如果可以直接访问业务数据库构建智能体,就可以基于结构化的数据直接进行问答,而不必进行繁琐的分块和向量化。本文基于一个简单的有两张表的数据库构建一个RAG智能体。首先基于langgraph预构构建一个单体智能体,然后基于图对单体智能体进行重构,对于智能体进行更细粒度的控制。

      1.基于预构件构建

      1.1连接数据库

from langchain_community.utilities import SQLDatabase
db = SQLDatabase.from_uri("sqlite:///myseal.db")

print(f"Dialect: {db.dialect}") #数据库方言
print(f"Available tables: {db.get_usable_table_names()}") #数据库中的所有表
print(f'Sample output: {db.run("SELECT * FROM seal LIMIT 2;")}')#从表查询最多两条数据

        运行结果如下:

Dialect: sqlite
Available tables: ['dept', 'seal']
Sample output: [('page00000011', '易门六街佳欣健康信息咨询服务部法定名称章', '51178100000026141', '51178100000026141', 33, 0, 0, '四川省达州市电子印章管理系统', 0, 1, '2024-08-24 15:31:12', '2025-08-24 15:31:12', '2024-08-24 15:31:13', '法定名称章', '(null)', '(null)', 1, png', 42, 42, 530425199611041316, '要离', '15198846923', 1011220574707519488, '易门六街佳欣健康信息咨询服务部', '1011220574195814400', '92530425MA6P7B1M5E', '股份有限公司', 12, '四川省', 510000, '达州市', 511700, '万源市', 511781, '(null)', '(null)', '(null)', 1011220574707519488, '2024-08-29 15:57:59', '(null)', '2024-08-22 13:36:29'), ('page00000081', '易门六街佳欣健康信息咨询服务部合同专用章', '51178100000041448', '51178100000041448', 33, 0, 0, '四川省达州市电子印章管理系统', 0, 1, '2024-08-24 15:31:32', '2025-08-24 15:31:32', '2024-08-24 15:31:32', '合同专用章', '(null)', '(null)', 4,  'png', 42, 42, 530425199611041316, '要离'', '15198846923', 1011220574707519488, '易门六街佳欣健康信息咨询服务部', '1011220574195814400', '92530425MA6P7B1M5E', '股份有限公司', 12, '四川省', 510000, '达州市', 511700, '万源市', 511781, '(null)', '(null)', '(null)', 1011220574707519488, '2024-08-24 15:31:32', '(null)', '2024-08-24 15:31:28')]

      1.2创建大模型和工具

        先创建大模型,然后设置工具列表,具体代码如下:

from langchain_community.agent_toolkits import SQLDatabaseToolkit
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model = 'qwen-plus',
    api_key = "sk-*",
    base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1")
toolkit = SQLDatabaseToolkit(db=db, llm=llm) 

tools = toolkit.get_tools()#获取所有可用的数据库工具

for tool in tools:
    print(f"{tool.name}: {tool.description}\n")

        输出如下:

sql_db_query: Input to this tool is a detailed and correct SQL query, output is a result from the database. If the query is not correct, an error message will be returned. If an error is returned, rewrite the query, check the query, and try again. If you encounter an issue with Unknown column 'xxxx' in 'field list', use sql_db_schema to query the correct table fields.

sql_db_schema: Input to this tool is a comma-separated list of tables, output is the schema and sample rows for those tables. Be sure that the tables actually exist by calling sql_db_list_tables first! Example Input: table1, table2, table3

sql_db_list_tables: Input is an empty string, output is a comma-separated list of tables in the database.

sql_db_query_checker: Use this tool to double check if your query is correct before executing it. Always use this tool before executing a query with sql_db_query!

        从输出可见有四个工具,其中:

        1)sql_db_query:是查询执行工具,参数为查询SQL

        2)sql_db_schema:表模式工具。输入为表的数组,输出为表中的抽样数据

        3)sql_db_list_tables:可用列表工具。获取所有的表。输入为空,返回为库中所有的表

        4)sql_db_query_checker:SQL检查工具。用于检查SQL语法是否正确

      1.3创建RAG智能体

        基于预构件create_react_agent创建智能体:

from langgraph.prebuilt import create_react_agent

"""

以下是直接用deepseek对于提示词进行翻译。提示如何使用上面的四个工具。

-------------------------------------------------------------------------------------------------------------------------

您是一个专用于与SQL数据库交互的智能体。
当接收到输入问题时,请按照以下流程操作:首先构建符合语法规范的{dialect}方言查询语句,
随后执行查询并分析返回结果,最终给出答案。除非用户明确指定获取记录的数量,
否则查询结果请始终限制在最多{top_k}条记录。

您可以通过对相关列进行排序,返回数据库中最具价值的数据样本。切勿查询特定表的所有列,
仅获取与问题相关的列信息。

在执行查询前,您必须对查询语句进行双重校验。若执行过程中出现错误,
请重新编写查询语句并再次尝试。

严禁对数据库执行任何数据操作语言语句(如增删改插、更新、删除、移除表等操作)。

开始操作时,请务必先查看数据库中的表结构以确定可查询内容,切勿跳过此步骤。

随后,您应查询最相关数据表的架构信息。

"""
system_prompt = """
You are an agent designed to interact with a SQL database.
Given an input question, create a syntactically correct {dialect} query to run,
then look at the results of the query and return the answer. Unless the user
specifies a specific number of examples they wish to obtain, always limit your
query to at most {top_k} results.

You can order the results by a relevant column to return the most interesting
examples in the database. Never query for all the columns from a specific table,
only ask for the relevant columns given the question.

You MUST double check your query before executing it. If you get an error while
executing a query, rewrite the query and try again.

DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the
database.

To start you should ALWAYS look at the tables in the database to see what you
can query. Do NOT skip this step.

Then you should query the schema of the most relevant tables.
""".format(
    dialect=db.dialect,
    top_k=5,
)

agent = create_react_agent(
    llm,
    tools,
    prompt=system_prompt,
)

        测试一下该智能体:

question = "共有几种印章类型?"

for chunk in agent.stream(
    {"messages": [{"role": "user", "content": question}]},
    stream_mode="values",
):
    chunk["messages"][-1].pretty_print()

        运行结果如下:

#用户提问

================================ Human Message =================================

共有几种印章类型?

#大模型返回工具调用信息,调用工具名为sql_db_list_tables
================================== Ai Message ==================================
Tool Calls:
  sql_db_list_tables (call_96b9624c542e4755b0c944)
 Call ID: call_96b9624c542e4755b0c944
  Args:

#调用sql_db_list_tables工具,得到两个表名
================================= Tool Message =================================
Name: sql_db_list_tables

dept, seal

#再次function calling,得到需调用的工具为sql_db_schema,参数为[seal]
================================== Ai Message ==================================
Tool Calls:
  sql_db_schema (call_4e143d03442c43caa230e6)
 Call ID: call_4e143d03442c43caa230e6
  Args:
    table_names: seal

#调用工具得到表结构和几条抽样记录
================================= Tool Message =================================
Name: sql_db_schema


CREATE TABLE seal (
    "ID" TEXT, 
    "SEAL_NAME" TEXT, 
    "SEAL_CODE" TEXT, 
    "SEAL_AUTH_ID" TEXT, 
    "STATUS" INTEGER, 
    "RECORD_FLAG" INTEGER, 
    "PUBLISH_FLAG" INTEGER, 
    "SYS_NAME" TEXT, 
    "SYS_ID" INTEGER, 
    "VALID_YEAR" INTEGER, 
    "VALID_START_TIME" TEXT, 
    "VALID_END_TIME" TEXT, 
    "MAKE_TIME" TEXT, 
    "SEAL_TYPE_NAME" TEXT, 
    "SEAL_FORM_NAME" TEXT, 
    "SEAL_FORM" TEXT, 
    "SEAL_TYPE_CODE" INTEGER, 
    "SEAL_MODULE" TEXT, 
    "SEAL_DATA" TEXT, 
    "APPLY_TABLE_PATH" TEXT, 
    "MODULE_TYPE" TEXT, 
    "MODULE_WIDTH" INTEGER, 
    "MODULE_HEIGHT" INTEGER, 
    "OPERATOR_CARD" INTEGER, 
    "OPERATOR_NAME" TEXT, 
    "OPERATOR_PHONE" TEXT, 
    "OPERATOR_ID" INTEGER, 
    "DEPT_NAME" TEXT, 
    "DEPT_ID" TEXT, 
    "DEPT_CODE" TEXT, 
    "DEPT_TYPE_NAME" TEXT, 
    "DEPT_TYPE_CODE" INTEGER, 
    "PROVINCE_NAME" TEXT, 
    "PROVINCE_CODE" INTEGER, 
    "CITY_NAME" TEXT, 
    "CITY_CODE" INTEGER, 
    "COUNTY_NAME" TEXT, 
    "COUNTY_CODE" INTEGER, 
    "PERSON_CARD_ID" TEXT, 
    "REGISTRATION_AUTHORITY_ID" TEXT, 
    "REGISTRATION_AUTHORITY_NAME" TEXT, 
    "CREATOR_ID" INTEGER, 
    "UPDATE_TIME" TEXT, 
    "DEPT_TREE_NO" TEXT, 
    "CREATE_TIME" TEXT, 
    "LEGAL_PERSON_NAME" TEXT, 
    "DEPT_PHONE" TEXT, 
    "DEPT_ADDR" TEXT, 
    "OPERATOR_EMAIL" TEXT
)

/*
3 rows from seal table:
ID    SEAL_NAME    SEAL_CODE    SEAL_AUTH_ID    STATUS    RECORD_FLAG    PUBLISH_FLAG    SYS_NAME    SYS_ID    VALID_YEAR    VALID_START_TIME    VALID_END_TIME    MAKE_TIME    SEAL_TYPE_NAME    SEAL_FORM_NAME    SEAL_FORM    SEAL_TYPE_CODE    SEAL_MODULE    SEAL_DATA    APPLY_TABLE_PATH    MODULE_TYPE    MODULE_WIDTH    MODULE_HEIGHT    OPERATOR_CARD    OPERATOR_NAME    OPERATOR_PHONE    OPERATOR_ID    DEPT_NAME    DEPT_ID    DEPT_CODE    DEPT_TYPE_NAME    DEPT_TYPE_CODE    PROVINCE_NAME    PROVINCE_CODE    CITY_NAME    CITY_CODE    COUNTY_NAME    COUNTY_CODE    PERSON_CARD_ID    REGISTRATION_AUTHORITY_ID    REGISTRATION_AUTHORITY_NAME    CREATOR_ID    UPDATE_TIME    DEPT_TREE_NO    CREATE_TIME    LEGAL_PERSON_NAME    DEPT_PHONE    DEPT_ADDR    OPERATOR_EMAIL
page00000011    易门六街佳欣健康信息咨询服务部法定名称章    51178100000026141    51178100000026141    33    0    0    四川省达州市电子印章管理系统    0    1    2024-08-24 15:31:12    2025-08-24 15:31:12    2024-08-24 15:31:13    法定名称章    png    42    42    530425199611041316    要离    15198846923    1011220574707519488    易门六街佳欣健康信息咨询服务部    1011220574195814400    92530425MA6P7B1M5E    股份有限公司    12    四川省    510000    达州市    511700    万源市    511781    (null)    (null)    (null)    1011220574707519488    2024-08-29 15:57:59    (null)    2024-08-22 13:36:29   
page00000081    易门六街佳欣健康信息咨询服务部合同专用章    51178100000041448    51178100000041448    33    0    0    四川省达州市电子印章管理系统    0    1    2024-08-24 15:31:32    2025-08-24 15:31:32    2024-08-24 15:31:32    合同专用章     png    42    42    530425199611041316    要离    15198846923    1011220574707519488    易门六街佳欣健康信息咨询服务部    1011220574195814400    92530425MA6P7B1M5E    股份有限公司    12    四川省    510000    达州市    511700    万源市    511781    (null)    (null)    (null)    1011220574707519488    2024-08-24 15:31:32    (null)    2024-08-24 15:31:28   
page00000082    易门六街佳欣健康信息咨询服务部发票专用章    51178100000042344    51178100000042344    33    0    0    四川省达州市电子印章管理系统    0    1    2024-08-28 10:29:22    2025-08-28 10:29:22    2024-08-28 10:29:22    发票专用章    (null)    (null)    3       png    40    30    530425199611041316    要离    15198846923    1011220574707519488    易门六街佳欣健康信息咨询服务部    1011220574195814400    92530425MA6P7B1M5E    股份有限公司    12    四川省    510000    达州市    511700    万源市    511781    (null)    (null)    (null)    1011220574707519488    2024-08-28 10:29:22    (null)    2024-08-24 15:31:28    
#再次function calling,得到需调用的工具sql_db_query_checker,参数为

#SELECT COUNT(DISTINCT SEAL_TYPE_NAME) AS seal_type_count FROM seal
================================== Ai Message ==================================
Tool Calls:
  sql_db_query_checker (call_13805ebcd0f24878937901)
 Call ID: call_13805ebcd0f24878937901
  Args:#该查询语句根据印章类型名字做分组查询
    query: SELECT COUNT(DISTINCT SEAL_TYPE_NAME) AS seal_type_count FROM seal; 

#调用工具 sql_db_query_checke对sql进行检查
================================= Tool Message =================================
Name: sql_db_query_checker

SELECT COUNT(DISTINCT SEAL_TYPE_NAME) AS seal_type_count FROM seal;

#再次function calling,得到需调用的工具 sql_db_query,参数同上
================================== Ai Message ==================================
Tool Calls:
  sql_db_query (call_8f3879ca15bd4aaca7934f)
 Call ID: call_8f3879ca15bd4aaca7934f
  Args:
    query: SELECT COUNT(DISTINCT SEAL_TYPE_NAME) AS seal_type_count FROM seal;

#调用工具,结果为6
================================= Tool Message =================================
Name: sql_db_query

[(6,)]

#大模型生成应答
================================== Ai Message ==================================

共有6种印章类型。
 

      2.使用图构建RAG智能体

        上面基于预构件构建RAG应用时,在每一步大模型均需要关注所有的工具,已经当工具数量过大时大模型表现不佳,而且在某些步骤根本不需要关心关注整个工具集,比如第一步总是要查询获取所有的表名,此时可以直接调用工具。以下就使用图把以上实现的RAG应用进行拆解实现。

      2.1查询所有表

        查询所有表的逻辑是固定的,并不需要大模型的function calling功能,具体代码如下:

def list_tables(state: MessagesState):

     """

        正常情况下工具调用时,总是先调用大模型,大模型生成工具调用参数,

        然后agent再调用工具,再携带调用结果调用大模型,由大模型生成应答。

        所以在对话历史中一次工具对应着一条AIMessage(Function calling),

        一条ToolMessage(调用工具返回的结果),最后是大模型的应答。

        这里为了保持与以上通用流程一致,硬编码生成tool_call,然后根据工具调用

        结果硬编码大模型的应答(而不需要再调用大模型)

    """
    tool_call = {
        "name": "sql_db_list_tables",
        "args": {},
        "id": "abc123",
        "type": "tool_call",
    }
    tool_call_message = AIMessage(content="", tool_calls=[tool_call])

    list_tables_tool = next(tool for tool in tools if tool.name == "sql_db_list_tables")
    tool_message = list_tables_tool.invoke(tool_call)#调用工具
    response = AIMessage(f"Available tables: {tool_message.content}")

    return {"messages": [tool_call_message, tool_message, response]}

      2.2获取表模式

        获取表模式需要根据上下文去分析,所以需要大模型的介入。首先基于上下文调用绑定了工具的大模型,获取工具调用参数,然后用这些参数调用对应的工具。 

get_schema_tool = next(tool for tool in tools if tool.name == "sql_db_schema")

def call_get_schema(state: MessagesState):
    llm_with_tools = llm.bind_tools([get_schema_tool], tool_choice="any")
    response = llm_with_tools.invoke(state["messages"])#function calling

    return {"messages": [response]} #tool_call

        把get_schema_tool分装到一个节点中,此处使用ToolNode:

get_schema_node = ToolNode([get_schema_tool], name="get_schema")

      2.3生成SQL

        根据上下文,包括调用工具获取的表模式、提示词和用户问题,生成对应的SQL,代码如下:

generate_query_system_prompt = """
You are an agent designed to interact with a SQL database.
Given an input question, create a syntactically correct {dialect} query to run,
then look at the results of the query and return the answer. Unless the user
specifies a specific number of examples they wish to obtain, always limit your
query to at most {top_k} results.

You can order the results by a relevant column to return the most interesting
examples in the database. Never query for all the columns from a specific table,
only ask for the relevant columns given the question.

DO NOT make any DML statements (INSERT, UPDATE, DELETE, DROP etc.) to the database.
""".format(
    dialect=db.dialect,
    top_k=5,
)


def generate_query(state: MessagesState):
    system_message = {
        "role": "system",
        "content": generate_query_system_prompt,
    }
    llm_with_tools = llm.bind_tools([run_query_tool])
    response = llm_with_tools.invoke([system_message] + state["messages"])

    return {"messages": [response]}

      2.4检查SQL

        检查SQL和语法正确性,并避免生成DDL语句,具体代码如下:

check_query_system_prompt = """
You are a SQL expert with a strong attention to detail.
Double check the {dialect} query for common mistakes, including:
- Using NOT IN with NULL values
- Using UNION when UNION ALL should have been used
- Using BETWEEN for exclusive ranges
- Data type mismatch in predicates
- Properly quoting identifiers
- Using the correct number of arguments for functions
- Casting to the correct data type
- Using the proper columns for joins

If there are any of the above mistakes, rewrite the query. If there are no mistakes,
just reproduce the original query.

You will call the appropriate tool to execute the query after running this check.
""".format(dialect=db.dialect)


def check_query(state: MessagesState):
    system_message = {
        "role": "system",
        "content": check_query_system_prompt,
    }

    # Generate an artificial user message to check
    tool_call = state["messages"][-1].tool_calls[0]
    user_message = {"role": "user", "content": tool_call["args"]["query"]}
    llm_with_tools = llm.bind_tools([run_query_tool], tool_choice="any")
    response = llm_with_tools.invoke([system_message, user_message])
    response.id = state["messages"][-1].id

    return {"messages": [response]}

        把run_query_tool封装到节点中:

run_query_node = ToolNode([run_query_tool], name="run_query")

      2.5结束条件

        在生成SQL节点检查是否结束,如果执行了SQL那么历史消息中的最后一条不包括tool_calls ,则结束,否则检查SQL,并执行后继的执行SQL,具体代码如下:

def should_continue(state: MessagesState) -> Literal[END, "check_query"]:
    messages = state["messages"]
    last_message = messages[-1]
    if not last_message.tool_calls:
        return END
    else:
        return "check_query"

      2.6创建图

        把以上所有的节点串联起来生成工作流,具体代码如下:

graph = (
    StateGraph(MessagesState)
    .add_node(list_tables)
    .add_node(call_get_schema)
    .add_node(get_schema_node, "get_schema")
    .add_node(generate_query)
    .add_node(check_query)
    .add_node(run_query_node, "run_query")    
    .add_edge(START, "list_tables")  
    .add_edge("list_tables", "call_get_schema")     
    .add_edge("call_get_schema", "get_schema")
    .add_edge("get_schema", "generate_query")       
    .add_conditional_edges(
       "generate_query",
       should_continue,
    )
    .add_edge("check_query", "run_query")  
    .add_edge("run_query",  "generate_query")
    .compile()
)

        打印输出工作流图,检查正确性:

from IPython.display import Image, display
from langchain_core.runnables.graph import CurveStyle, MermaidDrawMethod, NodeStyles

display(Image(agent.get_graph().draw_mermaid_png()))

      2.7测试图

        调用图进行测试:

question = "共有几种印章类型?"

for chunk in graph.stream(
    {"messages": [{"role": "user", "content": question}]},
    stream_mode="values",
):
    chunk["messages"][-1].pretty_print()   

        运行结果如下:

================================ Human Message =================================

共有几种印章类型?
================================== Ai Message ==================================

Available tables: dept, seal
================================== Ai Message ==================================
Tool Calls:
  sql_db_schema (call_67bd87f74d3c4229b3725b)
 Call ID: call_67bd87f74d3c4229b3725b
  Args:
    table_names: seal
================================= Tool Message =================================
Name: sql_db_schema


CREATE TABLE seal (
    "ID" TEXT, 
    "SEAL_NAME" TEXT, 
    "SEAL_CODE" TEXT, 
    "SEAL_AUTH_ID" TEXT, 
    "STATUS" INTEGER, 
    "RECORD_FLAG" INTEGER, 
    "PUBLISH_FLAG" INTEGER, 
    "SYS_NAME" TEXT, 
    "SYS_ID" INTEGER, 
    "VALID_YEAR" INTEGER, 
    "VALID_START_TIME" TEXT, 
    "VALID_END_TIME" TEXT, 
    "MAKE_TIME" TEXT, 
    "SEAL_TYPE_NAME" TEXT, 
    "SEAL_FORM_NAME" TEXT, 
    "SEAL_FORM" TEXT, 
    "SEAL_TYPE_CODE" INTEGER, 
    "SEAL_MODULE" TEXT, 
    "SEAL_DATA" TEXT, 
    "APPLY_TABLE_PATH" TEXT, 
    "MODULE_TYPE" TEXT, 
    "MODULE_WIDTH" INTEGER, 
    "MODULE_HEIGHT" INTEGER, 
    "OPERATOR_CARD" INTEGER, 
    "OPERATOR_NAME" TEXT, 
    "OPERATOR_PHONE" TEXT, 
    "OPERATOR_ID" INTEGER, 
    "DEPT_NAME" TEXT, 
    "DEPT_ID" TEXT, 
    "DEPT_CODE" TEXT, 
    "DEPT_TYPE_NAME" TEXT, 
    "DEPT_TYPE_CODE" INTEGER, 
    "PROVINCE_NAME" TEXT, 
    "PROVINCE_CODE" INTEGER, 
    "CITY_NAME" TEXT, 
    "CITY_CODE" INTEGER, 
    "COUNTY_NAME" TEXT, 
    "COUNTY_CODE" INTEGER, 
    "PERSON_CARD_ID" TEXT, 
    "REGISTRATION_AUTHORITY_ID" TEXT, 
    "REGISTRATION_AUTHORITY_NAME" TEXT, 
    "CREATOR_ID" INTEGER, 
    "UPDATE_TIME" TEXT, 
    "DEPT_TREE_NO" TEXT, 
    "CREATE_TIME" TEXT, 
    "LEGAL_PERSON_NAME" TEXT, 
    "DEPT_PHONE" TEXT, 
    "DEPT_ADDR" TEXT, 
    "OPERATOR_EMAIL" TEXT
)

/*
3 rows from seal table:
ID    SEAL_NAME    SEAL_CODE    SEAL_AUTH_ID    STATUS    RECORD_FLAG    PUBLISH_FLAG    SYS_NAME    SYS_ID    VALID_YEAR    VALID_START_TIME    VALID_END_TIME    MAKE_TIME    SEAL_TYPE_NAME    SEAL_FORM_NAME    SEAL_FORM    SEAL_TYPE_CODE    SEAL_MODULE    SEAL_DATA    APPLY_TABLE_PATH    MODULE_TYPE    MODULE_WIDTH    MODULE_HEIGHT    OPERATOR_CARD    OPERATOR_NAME    OPERATOR_PHONE    OPERATOR_ID    DEPT_NAME    DEPT_ID    DEPT_CODE    DEPT_TYPE_NAME    DEPT_TYPE_CODE    PROVINCE_NAME    PROVINCE_CODE    CITY_NAME    CITY_CODE    COUNTY_NAME    COUNTY_CODE    PERSON_CARD_ID    REGISTRATION_AUTHORITY_ID    REGISTRATION_AUTHORITY_NAME    CREATOR_ID    UPDATE_TIME    DEPT_TREE_NO    CREATE_TIME    LEGAL_PERSON_NAME    DEPT_PHONE    DEPT_ADDR    OPERATOR_EMAIL
page00000011    易门六街佳欣健康信息咨询服务部法定名称章    51178100000026141    51178100000026141    33    0    0    四川省达州市电子印章管理系统    0    1    2024-08-24 15:31:12    2025-08-24 15:31:12    2024-08-24 15:31:13    法定名称章    (null)    (null)    1      png    42    42    530425199611041316    要离    15198846923    1011220574707519488    易门六街佳欣健康信息咨询服务部    1011220574195814400    92530425MA6P7B1M5E    股份有限公司    12    四川省    510000    达州市    511700    万源市    511781    (null)    (null)    (null)    1011220574707519488    2024-08-29 15:57:59    (null)    2024-08-22 13:36:29  
page00000081    易门六街佳欣健康信息咨询服务部合同专用章    51178100000041448    51178100000041448    33    0    0    四川省达州市电子印章管理系统    0    1    2024-08-24 15:31:32    2025-08-24 15:31:32    2024-08-24 15:31:32    合同专用章    (null)    (null)    4       png    42    42    530425199611041316    要离    15198846923    1011220574707519488    易门六街佳欣健康信息咨询服务部    1011220574195814400    92530425MA6P7B1M5E    股份有限公司    12    四川省    510000    达州市    511700    万源市    511781    (null)    (null)    (null)    1011220574707519488    2024-08-24 15:31:32    (null)    2024-08-24 15:31:28  
page00000082    易门六街佳欣健康信息咨询服务部发票专用章    51178100000042344    51178100000042344    33    0    0    四川省达州市电子印章管理系统    0    1    2024-08-28 10:29:22    2025-08-28 10:29:22    2024-08-28 10:29:22    发票专用章    (null)    (null)    3     png    40    30    530425199611041316    要离    15198846923    1011220574707519488    易门六街佳欣健康信息咨询服务部    1011220574195814400    92530425MA6P7B1M5E    股份有限公司    12    四川省    510000    达州市    511700    万源市    511781    (null)    (null)    (null)    1011220574707519488    2024-08-28 10:29:22    (null)    2024-08-24 15:31:28    
*/
================================== Ai Message ==================================
Tool Calls:
  sql_db_query (call_2f7f301b0c8942b9b4e033)
 Call ID: call_2f7f301b0c8942b9b4e033
  Args:
    query: SELECT COUNT(DISTINCT SEAL_TYPE_NAME) AS seal_type_count FROM seal
================================== Ai Message ==================================
Tool Calls:
  sql_db_query (call_d30cc6ea8a154ffcad0b22)
 Call ID: call_d30cc6ea8a154ffcad0b22
  Args:
    query: SELECT COUNT(DISTINCT SEAL_TYPE_NAME) AS seal_type_count FROM seal
================================= Tool Message =================================
Name: sql_db_query

[(6,)]
================================== Ai Message ==================================

共有6种印章类型。
 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值