このチュートリアルでは、SQLを活用したエージェントの実装方法について説明します。 smolagents.
なぜシンプルにして、標準的なテキストからSQLへのパイプラインを使わないのか?
標準的なtext-to-sqlパイプラインは、生成されるSQLクエリが不正確である可能性があるため、もろい。さらに悪いことに、クエリが不正確であってもエラーにはならず、アラームを発生させることなく不正確な、あるいは役に立たない出力をすることもある。
その代わり、エージェントシステムは出力を批判的に検査し、クエリを変更する必要があるかどうかを判断することができる。
このエージェントを作ろう💪
まず、SQL環境をセットアップする:
コピー
from sqlalchemy import (
create_engine、
メタデータ、
テーブル
カラム
文字列
整数、
Float、
を挿入する、
検査する、
text、
)
engine = create_engine("sqlite:///:memory:")
metadata_obj = MetaData()
# city SQLテーブルの作成
テーブル名 = "領収書"
receipts = テーブル(
テーブル名、
metadata_obj、
カラム("receipt_id", 整数, primary_key=True)、
カラム("customer_name", String(16), primary_key=True)、
Column("価格", Float)、
カラム("チップ", Float)、
)
metadata_obj.create_all(engine)
rows = [
{"receipt_id":1, "customer_name":"Alan Payne", "price":12.06、"チップ":1.20},
{"receipt_id":2, "customer_name": "アレックス・メイソン":"アレックス・メイソン", "価格":23.86、チップ0.24},
{"receipt_id":3, "customer_name": "ウッドロウ・ウィルソン":"ウッドロウ・ウィルソン", "価格":53.43、チップ5.43},
{"receipt_id":4, "customer_name": "マーガレット・ジェームズ":"マーガレット・ジェームズ", "価格":21.11、チップ1.00},
]
for rows:
stmt = insert(receipts).values(**row)
with engine.begin() as connection:
カーソル = connection.execute(stmt)エージェントの構築 #
では、SQLテーブルをツールで検索できるようにしてみよう。
ツールのdescription属性は、エージェントシステムによってLLMのプロンプトに埋め込まれます。ここでSQLテーブルについて説明します。
コピー
inspector = inspect(engine)
columns_info = [(col["name"], col["type"]) for col in inspector.get_columns("receipts")].
table_description = "列:◆n" + "◆n".join([f" - {name}: {col_type}" for name, col_type in columns_info])
print(table_description)コピー
カラム - receipt_id:INTEGER - 顧客名: VARCHAR(16) - 価格FLOAT - チップ: FLOAT
それではツールを作ってみよう。それには以下のものが必要だ:(読む ツールドック 詳細はこちら)
- docstringに
引数:引数を列挙する部分。 - 入力と出力の両方にヒントを入力する。
コピー
from smolagents import tool
ツール
def sql_engine(query: str) -> str:
"""
テーブルに対してSQLクエリを実行できるようにします。結果の文字列表現を返します。
テーブルの名前は 'receipts' である。その説明は以下の通りである:
カラム
- receipt_id:INTEGER
- 顧客名: VARCHAR(16)
- 価格:FLOAT
- チップ: FLOAT
引数
クエリ:実行するクエリ。これは正しいSQLでなければなりません。
"""
出力 = ""
with engine.connect() as con:
rows = con.execute(text(query))
for rows:
output += "行" + str(行)
出力を返すでは、このツールを活用するエージェントを作ってみよう。
を使用している。 コードエージェントこれはsmolagentsのメイン・エージェント・クラスで、ReActフレームワークに従って、コードでアクションを記述し、以前の出力を反復することができるエージェントである。
モデルはエージェントシステムを動かすLLMです。HfApiModelはHFの推論APIを使ってLLMを呼び出すことができます。
コピー
from smolagents import CodeAgent, HfApiModel
agent = CodeAgent(
tools=[sql_engine]、
model=HfApiModel("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: テーブル結合 #
では、もっと難易度を上げてみよう!エージェントに複数のテーブルの結合を処理させたいのです。
そこで、レシートIDごとにウェイターの名前を記録した2つ目のテーブルを作ってみよう!
コピー
テーブル名 = "ウェイター"
receipts = テーブル(
テーブル名
metadata_obj、
カラム("receipt_id", 整数, primary_key=True)、
カラム("waiter_name", String(16), primary_key=True)、
)
metadata_obj.create_all(engine)
rows = [
{"receipt_id":1, "waiter_name":"Corey Johnson"}、
{"receipt_id": 1, "waiter_name": "Corey Johnson"}:2, "waiter_name":「マイケル・ワッツ}
{"receipt_id": 2, "waiter_name": "Michael Watts"}:3, "waiter_name": "Michael Watts":「マイケル・ワッツ"}、
4, "waiter_name":「マーガレット・ジェームス}
]
for rows:
stmt = insert(receipts).values(**row)
with engine.begin() as connection:
カーソル = connection.execute(stmt)テーブルを変更したので SQLExecutorツール LLMがこのテーブルの情報を適切に活用できるようにするために、このテーブルの説明をこのテーブルに追加する。
コピー
updated_description = """テーブルに対してSQLクエリを実行できます。このツールの出力は実行出力の文字列表現であることに注意してください。
以下のテーブルを使用できます:""
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}':˶n"
table_description += "カラム:{n}" + "{n}".join([f" - {name}: {col_type}" for name, col_type in columns_info])
updated_description += "Ⅾ" + table_description
print(updated_description)このリクエストは前のものよりも少し難しいので、LLMエンジンをより強力な Qwen/Qwen2.5-コーダー-32B-インストラクター!
コピー
sql_engine.description = updated_description
agent = CodeAgent(
tools=[sql_engine]、
model=HfApiModel("Qwen/Qwen2.5-Coder-32B-Instruct")、
)
agent.run("Which waiter got more total money from tips?")直接機能する!セットアップは驚くほど簡単だったでしょう?
この例は終わった!我々はこれらの概念に触れた:
- 新しいツールを作る。
- ツールの説明を更新する
- より強力なLLMに切り替えることは、エージェントの推論を助ける。
✅ これで、ずっと夢見ていたtext-to-SQLシステムを構築することができます!✨
