smolagents-audit/docs/source/hi/examples/text_to_sql.md

9.6 KiB

Text-to-SQL

open-in-colab

рдЗрд╕ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рдореЗрдВ, рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдХреИрд╕реЗ smolagents рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдПрдЬреЗрдВрдЯ рдХреЛ SQL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдЖрдЗрдП рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкреНрд░рд╢реНрди рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ: рдЗрд╕реЗ рд╕рд╛рдзрд╛рд░рдг рдХреНрдпреЛрдВ рдирд╣реАрдВ рд░рдЦреЗрдВ рдФрд░ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп text-to-SQL рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ?

рдПрдХ рд╕рд╛рдорд╛рдиреНрдп text-to-SQL рдкрд╛рдЗрдкрд▓рд╛рдЗрди рдХрдордЬреЛрд░ рд╣реЛрддреА рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЙрддреНрдкрдиреНрди SQL рдХреНрд╡реЗрд░реА рдЧрд▓рдд рд╣реЛ рд╕рдХрддреА рд╣реИред рдЗрд╕рд╕реЗ рднреА рдмреБрд░реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдХреНрд╡реЗрд░реА рдЧрд▓рдд рд╣реЛ рд╕рдХрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдХреЛрдИ рдПрд░рд░ рдирд╣реАрдВ рджрд┐рдЦрд╛рдПрдЧреА, рдмрд▓реНрдХрд┐ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдЕрд▓рд╛рд░реНрдо рдХреЗ рдЧрд▓рдд/рдмреЗрдХрд╛рд░ рдЖрдЙрдЯрдкреБрдЯ рджреЗ рд╕рдХрддреА рд╣реИред

ЁЯСЙ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдПрдХ рдПрдЬреЗрдВрдЯ рд╕рд┐рд╕реНрдЯрдо рдЖрдЙрдЯрдкреБрдЯ рдХрд╛ рдЧрдВрднреАрд░рддрд╛ рд╕реЗ рдирд┐рд░реАрдХреНрд╖рдг рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рддрдп рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХреНрд╡реЗрд░реА рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдпрд╛ рдирд╣реАрдВ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдЗрд╕реЗ рдмреЗрд╣рддрд░ рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рдорджрдж рдорд┐рд▓рддреА рд╣реИред

рдЖрдЗрдП рдЗрд╕ рдПрдЬреЗрдВрдЯ рдХреЛ рдмрдирд╛рдПрдВ! ЁЯТк

рдкрд╣рд▓реЗ, рд╣рдо SQL рдПрдирд╡рд╛рдпрд░рдирдореЗрдВрдЯ рд╕реЗрдЯрдЕрдк рдХрд░рддреЗ рд╣реИрдВ:

from sqlalchemy import (
    create_engine,
    MetaData,
    Table,
    Column,
    String,
    Integer,
    Float,
    insert,
    inspect,
    text,
)

engine = create_engine("sqlite:///:memory:")
metadata_obj = MetaData()

# create city SQL table
table_name = "receipts"
receipts = Table(
    table_name,
    metadata_obj,
    Column("receipt_id", Integer, primary_key=True),
    Column("customer_name", String(16), primary_key=True),
    Column("price", Float),
    Column("tip", Float),
)
metadata_obj.create_all(engine)

rows = [
    {"receipt_id": 1, "customer_name": "Alan Payne", "price": 12.06, "tip": 1.20},
    {"receipt_id": 2, "customer_name": "Alex Mason", "price": 23.86, "tip": 0.24},
    {"receipt_id": 3, "customer_name": "Woodrow Wilson", "price": 53.43, "tip": 5.43},
    {"receipt_id": 4, "customer_name": "Margaret James", "price": 21.11, "tip": 1.00},
]
for row in rows:
    stmt = insert(receipts).values(**row)
    with engine.begin() as connection:
        cursor = connection.execute(stmt)

Agent рдмрдирд╛рдПрдВ

рдЕрдм рдЖрдЗрдП рд╣рдорд╛рд░реА SQL рдЯреЗрдмрд▓ рдХреЛ рдПрдХ рдЯреВрд▓ рджреНрд╡рд╛рд░рд╛ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдмрдирд╛рдПрдВред

рдЯреВрд▓ рдХрд╛ рд╡рд┐рд╡рд░рдг рд╡рд┐рд╢реЗрд╖рддрд╛ рдПрдЬреЗрдВрдЯ рд╕рд┐рд╕реНрдЯрдо рджреНрд╡рд╛рд░рд╛ LLM рдХреЗ prompt рдореЗрдВ рдПрдореНрдмреЗрдб рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛: рдпрд╣ LLM рдХреЛ рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рджреЗрддрд╛ рд╣реИред рдпрд╣реАрдВ рдкрд░ рд╣рдо SQL рдЯреЗрдмрд▓ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

inspector = inspect(engine)
columns_info = [(col["name"], col["type"]) for col in inspector.get_columns("receipts")]

table_description = "Columns:\n" + "\n".join([f"  - {name}: {col_type}" for name, col_type in columns_info])
print(table_description)
Columns:
  - receipt_id: INTEGER
  - customer_name: VARCHAR(16)
  - price: FLOAT
  - tip: FLOAT

рдЕрдм рдЖрдЗрдП рд╣рдорд╛рд░рд╛ рдЯреВрд▓ рдмрдирд╛рдПрдВред рдЗрд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: (рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП рдЯреВрд▓ doc рдкрдврд╝реЗрдВ)

  • рдПрдХ рдбреЙрдХрд╕реНрдЯреНрд░рд┐рдВрдЧ рдЬрд┐рд╕рдореЗрдВ рдЖрд░реНрдЧреНрдпреБрдореЗрдВрдЯреНрд╕ рдХреА рд╕реВрдЪреА рд╡рд╛рд▓рд╛ Args: рднрд╛рдЧ рд╣реЛред
  • рдЗрдирдкреБрдЯ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рджреЛрдиреЛрдВ рдкрд░ рдЯрд╛рдЗрдк рд╣рд┐рдВрдЯреНрд╕ред
from smolagents import tool

@tool
def sql_engine(query: str) -> str:
    """
    Allows you to perform SQL queries on the table. Returns a string representation of the result.
    The table is named 'receipts'. Its description is as follows:
        Columns:
        - receipt_id: INTEGER
        - customer_name: VARCHAR(16)
        - price: FLOAT
        - tip: FLOAT

    Args:
        query: The query to perform. This should be correct SQL.
    """
    output = ""
    with engine.connect() as con:
        rows = con.execute(text(query))
        for row in rows:
            output += "\n" + str(row)
    return output

рдЕрдм рдЖрдЗрдП рдПрдХ рдПрдЬреЗрдВрдЯ рдмрдирд╛рдПрдВ рдЬреЛ рдЗрд╕ рдЯреВрд▓ рдХрд╛ рд▓рд╛рдн рдЙрдард╛рддрд╛ рд╣реИред

рд╣рдо CodeAgent рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ smolagents рдХрд╛ рдореБрдЦреНрдп рдПрдЬреЗрдВрдЯ рдХреНрд▓рд╛рд╕ рд╣реИ: рдПрдХ рдПрдЬреЗрдВрдЯ рдЬреЛ рдХреЛрдб рдореЗрдВ рдПрдХреНрд╢рди рд▓рд┐рдЦрддрд╛ рд╣реИ рдФрд░ ReAct рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкрд┐рдЫрд▓реЗ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХрд░ рд╕рдХрддрд╛ рд╣реИред

рдореЙрдбрд▓ рд╡рд╣ LLM рд╣реИ рдЬреЛ рдПрдЬреЗрдВрдЯ рд╕рд┐рд╕реНрдЯрдо рдХреЛ рд╕рдВрдЪрд╛рд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред InferenceClientModel рдЖрдкрдХреЛ HF рдХреЗ Inference API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ LLM рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдпрд╛ рддреЛ рд╕рд░реНрд╡рд░рд▓реЗрд╕ рдпрд╛ рдбреЗрдбрд┐рдХреЗрдЯреЗрдб рдПрдВрдбрдкреЙрдЗрдВрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рд▓реЗрдХрд┐рди рдЖрдк рдХрд┐рд╕реА рднреА рдкреНрд░реЛрдкреНрд░рд╛рдЗрдЯрд░реА API рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

from smolagents import CodeAgent, InferenceClientModel

agent = CodeAgent(
    tools=[sql_engine],
    model=InferenceClientModel(model_id="meta-llama/Meta-Llama-3.1-8B-Instruct"),
)
agent.run("Can you give me the name of the client who got the most expensive receipt?")

рд▓реЗрд╡рд▓ 2: рдЯреЗрдмрд▓ рдЬреЙрдЗрдиреНрд╕

рдЕрдм рдЖрдЗрдП рдЗрд╕реЗ рдФрд░ рдЪреБрдиреМрддреАрдкреВрд░реНрдг рдмрдирд╛рдПрдВ! рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░рд╛ рдПрдЬреЗрдВрдЯ рдХрдИ рдЯреЗрдмрд▓реНрд╕ рдХреЗ рдмреАрдЪ рдЬреЙрдЗрди рдХреЛ рд╕рдВрднрд╛рд▓ рд╕рдХреЗред

рддреЛ рдЖрдЗрдП рд╣рдо рдкреНрд░рддреНрдпреЗрдХ receipt_id рдХреЗ рд▓рд┐рдП рд╡реЗрдЯрд░реНрд╕ рдХреЗ рдирд╛рдо рд░рд┐рдХреЙрд░реНрдб рдХрд░рдиреЗ рд╡рд╛рд▓реА рдПрдХ рджреВрд╕рд░реА рдЯреЗрдмрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ!

table_name = "waiters"
receipts = Table(
    table_name,
    metadata_obj,
    Column("receipt_id", Integer, primary_key=True),
    Column("waiter_name", String(16), primary_key=True),
)
metadata_obj.create_all(engine)

rows = [
    {"receipt_id": 1, "waiter_name": "Corey Johnson"},
    {"receipt_id": 2, "waiter_name": "Michael Watts"},
    {"receipt_id": 3, "waiter_name": "Michael Watts"},
    {"receipt_id": 4, "waiter_name": "Margaret James"},
]
for row in rows:
    stmt = insert(receipts).values(**row)
    with engine.begin() as connection:
        cursor = connection.execute(stmt)

рдЪреВрдВрдХрд┐ рд╣рдордиреЗ рдЯреЗрдмрд▓ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ рд╣реИ, рд╣рдо LLM рдХреЛ рдЗрд╕ рдЯреЗрдмрд▓ рдХреА рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рдЙрдЪрд┐рдд рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдЯреЗрдмрд▓ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рд╕рд╛рде SQLExecutorTool рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рддреЗ рд╣реИрдВред

updated_description = """Allows you to perform SQL queries on the table. Beware that this tool's output is a string representation of the execution output.
It can use the following tables:"""

inspector = inspect(engine)
for table in ["receipts", "waiters"]:
    columns_info = [(col["name"], col["type"]) for col in inspector.get_columns(table)]

    table_description = f"Table '{table}':\n"

    table_description += "Columns:\n" + "\n".join([f"  - {name}: {col_type}" for name, col_type in columns_info])
    updated_description += "\n\n" + table_description

print(updated_description)

рдЪреВрдВрдХрд┐ рдпрд╣ рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдкрд┐рдЫрд▓реЗ рд╡рд╛рд▓реЗ рд╕реЗ рдереЛрдбрд╝реА рдХрдард┐рди рд╣реИ, рд╣рдо LLM рдЗрдВрдЬрди рдХреЛ рдЕрдзрд┐рдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА Qwen/Qwen3-Next-80B-A3B-Thinking рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рд┐рдЪ рдХрд░реЗрдВрдЧреЗ!

sql_engine.description = updated_description

agent = CodeAgent(
    tools=[sql_engine],
    model=InferenceClientModel(model_id="Qwen/Qwen3-Next-80B-A3B-Thinking"),
)

agent.run("Which waiter got more total money from tips?")

рдпрд╣ рд╕реАрдзреЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ! рд╕реЗрдЯрдЕрдк рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд░реВрдк рд╕реЗ рд╕рд░рд▓ рдерд╛, рд╣реИ рдирд╛?

рдпрд╣ рдЙрджрд╛рд╣рд░рдг рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛! рд╣рдордиреЗ рдЗрди рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЛ рдЫреБрдЖ рд╣реИ:

  • рдирдП рдЯреВрд▓реНрд╕ рдХрд╛ рдирд┐рд░реНрдорд╛рдгред
  • рдЯреВрд▓ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ред
  • рдПрдХ рдордЬрдмреВрдд LLM рдореЗрдВ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рд╕реЗ рдПрдЬреЗрдВрдЯ рдХреА рддрд░реНрдХрд╢рдХреНрддрд┐ рдореЗрдВ рдорджрдж рдорд┐рд▓рддреА рд╣реИред

тЬЕ рдЕрдм рдЖрдк рд╡рд╣ text-to-SQL рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдХрд╛ рдЖрдкрдиреЗ рд╣рдореЗрд╢рд╛ рд╕рдкрдирд╛ рджреЗрдЦрд╛ рд╣реИ! тЬи