微信扫码
与创始人交个朋友
我要投稿
实际案例的运行画面
import os
from dotenv import load_dotenv
from langchain_community.agent_toolkits.sql.base import create_sql_agent
from langchain_community.utilities.sql_database import SQLDatabase
from langchain.agents.agent_types import AgentType
from langchain_openai import AzureChatOpenAI, ChatOpenAI
from langchain_community.callbacks.manager import get_openai_callback
from langchain_community.agent_toolkits import SQLDatabaseToolkit
# 加载环境变量
load_dotenv()
def get_llm():
"""根据环境变量选择使用的LLM"""
model_type = os.getenv("MODEL_TYPE", "azure")# 默认使用azure
if model_type.lower() == "azure":
return AzureChatOpenAI(
openai_api_key=os.getenv("AZURE_OPENAI_API_KEY"),
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
deployment_name=os.getenv("AZURE_OPENAI_DEPLOYMENT_NAME"),
openai_api_version=os.getenv("AZURE_OPENAI_API_VERSION"),
temperature=0
)
else:
return ChatOpenAI(
model=os.getenv("MODEL_NAME", "gpt-3.5-turbo"),# 默认使用gpt-3.5-turbo
openai_api_key=os.getenv("OPENAI_API_KEY"),
openai_api_base=os.getenv("OPENAI_API_BASE"),# API基础URL
temperature=0
)
# 使用get_llm()替换原来的llm初始化
llm = get_llm()
# 连接数据库
db = SQLDatabase.from_uri("sqlite:///Chinook.db")
# 创建 SQL 工具包
toolkit = SQLDatabaseToolkit(db=db, llm=llm)
# 创建 SQL Agent
agent = create_sql_agent(
llm=llm,
toolkit=toolkit,
agent_type=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
verbose=True
)
def main():
print("欢迎使用自然语言查询系统!")
print("输入 'quit' 或 'exit' 退出程序")
while True:
query = input("\n请输入您的查询: ")
if query.lower() in ['quit', 'exit']:
print("感谢使用!再见!")
break
try:
# 使用计数器追踪 token 使用情况
with get_openai_callback() as cb:
# 使用 invoke 替代 run
result = agent.invoke({"input": query})
print("\n查询结果:")
print(result["output"])
print(f"\nToken 使用情况:")
print(f"Prompt Tokens: {cb.prompt_tokens}")
print(f"Completion Tokens: {cb.completion_tokens}")
print(f"Total Tokens: {cb.total_tokens}")
print(f"Total Cost (USD): ${cb.total_cost}")
except Exception as e:
print(f"查询出错: {str(e)}")
if __name__ == "__main__":
main()
.
├── README.md# 项目说明文档
├── .env # 环境变量文件
├── main.py# 主程序入口
├── Chinook.db # 示例数据库
└── Chinook_Sqlite.sql # 数据库初始化脚本
表名 | 描述 |
---|---|
Customer | 存储客户信息 |
Employee | 存储员工信息 |
Invoice | 存储订单信息 |
Track | 存储音轨信息 |
Album | 存储专辑信息 |
Artist | 存储艺术家信息 |
欢迎使用自然语言查询系统!
输入 'quit' 或 'exit' 退出程序
请输入您的查询: 统计雇员人数
> Entering new SQL Agent Executor chain...
Action: sql_db_list_tables
Action Input: Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, TrackThe "Employee" table is likely to contain information about employees. I should check the schema of the "Employee" table to confirm this.
Action: sql_db_schema
Action Input: Employee
CREATE TABLE "Employee" (
"EmployeeId" INTEGER NOT NULL,
"LastName" NVARCHAR(20) NOT NULL,
"FirstName" NVARCHAR(20) NOT NULL,
"Title" NVARCHAR(30),
"ReportsTo" INTEGER,
"BirthDate" DATETIME,
"HireDate" DATETIME,
"Address" NVARCHAR(70),
"City" NVARCHAR(40),
"State" NVARCHAR(40),
"Country" NVARCHAR(40),
"PostalCode" NVARCHAR(10),
"Phone" NVARCHAR(24),
"Fax" NVARCHAR(24),
"Email" NVARCHAR(60),
PRIMARY KEY ("EmployeeId"),
FOREIGN KEY("ReportsTo") REFERENCES "Employee" ("EmployeeId")
)
/*
3 rows from Employee table:
EmployeeIdLastNameFirstName Title ReportsTo BirthDate HireDateAddress CityState CountryPostalCodePhone Fax Email
1 Adams AndrewGeneral Manager None1962-02-18 00:00:00 2002-08-14 00:00:00 11120 Jasper Ave NW EdmontonAB CanadaT5K 2N1 +1 (780) 428-9482 +1 (780) 428-3457 andrew@chinookcorp.com
2 Edwards Nancy Sales Manager 1 1958-12-08 00:00:00 2002-05-01 00:00:00 825 8 Ave SWCalgary ABCanada T2P 2T3 +1 (403) 262-3443 +1 (403) 262-3322 nancy@chinookcorp.com
3 Peacock JaneSales Support Agent 2 1973-08-29 00:00:00 2002-04-01 00:00:00 1111 6 Ave SW Calgary ABCanada T2P 5M5 +1 (403) 262-3443 +1 (403) 262-6712 jane@chinookcorp.com
*/The "Employee" table contains information about employees. To count the number of employees, I can use the `COUNT` function on the `EmployeeId` column.
Action: sql_db_query_checker
Action Input: SELECT COUNT(EmployeeId) AS EmployeeCount FROM Employee;```sql
SELECT COUNT(EmployeeId) AS EmployeeCount FROM Employee;
```The query is correct and ready to be executed.
Action: sql_db_query
Action Input: SELECT COUNT(EmployeeId) AS EmployeeCount FROM Employee;[(8,)]I now know the final answer.
Final Answer: The number of employees is 8.
> Finished chain.
查询结果:
The number of employees is 8.
Token 使用情况:
Prompt Tokens: 132
Completion Tokens: 15
Total Tokens: 147
Total Cost (USD): $0.0008849999999999999
请输入您的查询: 统计各国艺术家的销量
> Entering new SQL Agent Executor chain...
Action: sql_db_list_tables
Action Input: Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, TrackTo calculate the sales of artists by country, I need to identify the relevant tables and their relationships. The `Artist` table will provide artist information, and the `Invoice` table will provide sales data. The `Customer` table will link sales to countries.
I will first check the schema of the `Artist`, `Invoice`, and `Customer` tables to understand their structure and relationships.
Action: sql_db_schema
Action Input: Artist, Invoice, Customer
CREATE TABLE "Artist" (
"ArtistId" INTEGER NOT NULL,
"Name" NVARCHAR(120),
PRIMARY KEY ("ArtistId")
)
/*
3 rows from Artist table:
ArtistIdName
1 AC/DC
2 Accept
3 Aerosmith
*/
CREATE TABLE "Customer" (
"CustomerId" INTEGER NOT NULL,
"FirstName" NVARCHAR(40) NOT NULL,
"LastName" NVARCHAR(20) NOT NULL,
"Company" NVARCHAR(80),
"Address" NVARCHAR(70),
"City" NVARCHAR(40),
"State" NVARCHAR(40),
"Country" NVARCHAR(40),
"PostalCode" NVARCHAR(10),
"Phone" NVARCHAR(24),
"Fax" NVARCHAR(24),
"Email" NVARCHAR(60) NOT NULL,
"SupportRepId" INTEGER,
PRIMARY KEY ("CustomerId"),
FOREIGN KEY("SupportRepId") REFERENCES "Employee" ("EmployeeId")
)
/*
3 rows from Customer table:
CustomerIdFirstName LastNameCompany Address CityState Country PostalCodePhoneFax Email SupportRepId
1 LuísGonçalves Embraer - Empresa Brasileira de Aeronáutica S.A.Av. Brigadeiro Faria Lima, 2170São José dos Campos SPBrazil12227-000 +55 (12) 3923-5555+55 (12) 3923-5566 luisg@embraer.com.br3
2 LeonieKöhlerNoneTheodor-Heuss-Straße 34 Stuttgart NoneGermany 70174 +49 0711 2842222 Noneleonekohler@surfeu.de 5
3 FrançoisTremblayNone1498 rue Bélanger MontréalQCCanadaH2G 1A7+1 (514) 721-4711 Noneftremblay@gmail.com 3
*/
CREATE TABLE "Invoice" (
"InvoiceId" INTEGER NOT NULL,
"CustomerId" INTEGER NOT NULL,
"InvoiceDate" DATETIME NOT NULL,
"BillingAddress" NVARCHAR(70),
"BillingCity" NVARCHAR(40),
"BillingState" NVARCHAR(40),
"BillingCountry" NVARCHAR(40),
"BillingPostalCode" NVARCHAR(10),
"Total" NUMERIC(10, 2) NOT NULL,
PRIMARY KEY ("InvoiceId"),
FOREIGN KEY("CustomerId") REFERENCES "Customer" ("CustomerId")
)
/*
3 rows from Invoice table:
InvoiceId CustomerIdInvoiceDate BillingAddressBillingCity BillingStateBillingCountry BillingPostalCode Total
1 2 2021-01-01 00:00:00 Theodor-Heuss-Straße 34 Stuttgart NoneGermany 70174 1.98
2 4 2021-01-02 00:00:00 Ullevålsveien 14OsloNoneNorway01713.96
3 8 2021-01-03 00:00:00 Grétrystraat 63 BrusselsNoneBelgium 10005.94
*/To calculate the sales of artists by country, I need to join the `Artist`, `Customer`, and `Invoice` tables. However, I also need to consider the `Track` and `InvoiceLine` tables to link the artists to the invoices.
I will first check the schema of the `Track` and `InvoiceLine` tables to understand their structure and relationships.
Action: sql_db_schema
Action Input: Track, InvoiceLine
CREATE TABLE "InvoiceLine" (
"InvoiceLineId" INTEGER NOT NULL,
"InvoiceId" INTEGER NOT NULL,
"TrackId" INTEGER NOT NULL,
"UnitPrice" NUMERIC(10, 2) NOT NULL,
"Quantity" INTEGER NOT NULL,
PRIMARY KEY ("InvoiceLineId"),
FOREIGN KEY("TrackId") REFERENCES "Track" ("TrackId"),
FOREIGN KEY("InvoiceId") REFERENCES "Invoice" ("InvoiceId")
)
/*
3 rows from InvoiceLine table:
InvoiceLineId InvoiceId TrackId UnitPrice Quantity
1 1 2 0.991
2 1 4 0.991
3 2 6 0.991
*/
CREATE TABLE "Track" (
"TrackId" INTEGER NOT NULL,
"Name" NVARCHAR(200) NOT NULL,
"AlbumId" INTEGER,
"MediaTypeId" INTEGER NOT NULL,
"GenreId" INTEGER,
"Composer" NVARCHAR(220),
"Milliseconds" INTEGER NOT NULL,
"Bytes" INTEGER,
"UnitPrice" NUMERIC(10, 2) NOT NULL,
PRIMARY KEY ("TrackId"),
FOREIGN KEY("MediaTypeId") REFERENCES "MediaType" ("MediaTypeId"),
FOREIGN KEY("GenreId") REFERENCES "Genre" ("GenreId"),
FOREIGN KEY("AlbumId") REFERENCES "Album" ("AlbumId")
)
/*
3 rows from Track table:
TrackId NameAlbumId MediaTypeId GenreId ComposerMillisecondsBytes UnitPrice
1 For Those About To Rock (We Salute You) 1 1 1 Angus Young, Malcolm Young, Brian Johnson343719111703340.99
2 Balls to the Wall 2 2 1 U. Dirkschneider, W. Hoffmann, H. Frank, P. Baltes, S. Kaufmann, G. Hoffmann 3425625510424 0.99
3 Fast As a Shark 3 2 1 F. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman 230619 3990994 0.99
*/To calculate the sales of artists by country, I need to join the `Artist`, `Customer`, `Invoice`, `InvoiceLine`, and `Track` tables. The `Track` table will link to the `Artist` table through the `Album` table, so I also need to check the schema of the `Album` table.
Action: sql_db_schema
Action Input: Album
CREATE TABLE "Album" (
"AlbumId" INTEGER NOT NULL,
"Title" NVARCHAR(160) NOT NULL,
"ArtistId" INTEGER NOT NULL,
PRIMARY KEY ("AlbumId"),
FOREIGN KEY("ArtistId") REFERENCES "Artist" ("ArtistId")
)
/*
3 rows from Album table:
AlbumId Title ArtistId
1 For Those About To Rock We Salute You 1
2 Balls to the Wall 2
3 Restless and Wild 2
*/To calculate the sales of artists by country, I need to join the `Artist`, `Customer`, `Invoice`, `InvoiceLine`, `Track`, and `Album` tables. The `Track` table links to the `Album` table, which in turn links to the `Artist` table. The `InvoiceLine` table links to the `Invoice` table, which links to the `Customer` table to get the country information.
I will construct a query to join these tables and calculate the total sales for each artist by country.
Here is the query:
```sql
SELECT
c.Country,
ar.Name AS ArtistName,
SUM(il.UnitPrice * il.Quantity) AS TotalSales
FROM
InvoiceLine il
JOIN
Invoice i ON il.InvoiceId = i.InvoiceId
JOIN
Customer c ON i.CustomerId = c.CustomerId
JOIN
Track t ON il.TrackId = t.TrackId
JOIN
Album al ON t.AlbumId = al.AlbumId
JOIN
Artist ar ON al.ArtistId = ar.ArtistId
GROUP BY
c.Country, ar.Name
ORDER BY
TotalSales DESC
LIMIT 10;
...
Action: sql_db_query
Action Input: SELECT c.Country, ar.Name AS ArtistName, SUM(il.UnitPrice * il.Quantity) AS TotalSales FROM InvoiceLine il JOIN Invoice i ON il.InvoiceId = i.InvoiceId JOIN Customer c ON i.CustomerId = c.CustomerId JOIN Track t ON il.TrackId = t.TrackId JOIN Album al ON t.AlbumId = al.AlbumId JOIN Artist ar ON al.ArtistId = ar.ArtistId GROUP BY c.Country, ar.Name ORDER BY TotalSales DESC LIMIT 10;[('USA', 'The Office', 33.82999999999999), ('USA', 'Iron Maiden', 33.65999999999998), ('USA', 'Metallica', 26.729999999999986), ('USA', 'U2', 22.769999999999992), ('Australia', 'Iron Maiden', 17.82), ('Czech Republic', 'Lost', 15.92), ('Ireland', 'Lost', 15.92), ('USA', 'Lost', 15.92), ('Canada', 'Os Paralamas Do Sucesso', 15.840000000000002), ('Portugal', 'Iron Maiden', 15.840000000000002)]I now know the final answer.
Final Answer: The top 10 sales of artists by country are as follows:
1. USA - The Office: $33.83
2. USA - Iron Maiden: $33.66
3. USA - Metallica: $26.73
4. USA - U2: $22.77
5. Australia - Iron Maiden: $17.82
6. Czech Republic - Lost: $15.92
7. Ireland - Lost: $15.92
8. USA - Lost: $15.92
9. Canada - Os Paralamas Do Sucesso: $15.84
10. Portugal - Iron Maiden: $15.84
> Finished chain.
查询结果:
The top 10 sales of artists by country are as follows:
1. USA - The Office: $33.83
2. USA - Iron Maiden: $33.66
3. USA - Metallica: $26.73
4. USA - U2: $22.77
5. Australia - Iron Maiden: $17.82
6. Czech Republic - Lost: $15.92
7. Ireland - Lost: $15.92
8. USA - Lost: $15.92
9. Canada - Os Paralamas Do Sucesso: $15.84
10. Portugal - Iron Maiden: $15.84
Token 使用情况:
Prompt Tokens: 221
Completion Tokens: 113
Total Tokens: 334
Total Cost (USD): $0.0028
输出结果分析示例
53AI,企业落地应用大模型首选服务商
产品:大模型应用平台+智能体定制开发+落地咨询服务
承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-01-07
Agent 最全 Playbook:场景、记忆和交互创新
2025-01-06
探索AI Agent工作流设计模式:构建智能任务协作的未来
2025-01-04
吴恩达DeepLearning.AI课程系列 - 大模型检索增强生成(七):对话
2025-01-04
2024年AI Agents发展现状:机遇与挑战并存
2024-12-26
开发者的选择越来越多了,又一个AI智能体框架玩家:PydanticAI
2024-12-25
2025年,拥抱AI Agent!
2024-12-25
基于LangChain构建安全Agent应用实践(含代码)
2024-12-22
ANTHROPIC:高端的食材往往需要最朴素的烹饪方法: prompt, workflow, agent
2024-04-08
2024-08-18
2024-10-10
2024-06-03
2024-04-08
2024-04-17
2024-09-04
2024-07-13
2024-06-24
2024-04-11
2024-12-02
2024-11-25
2024-10-30
2024-10-11
2024-08-18
2024-08-16
2024-08-04
2024-07-29