Chapter 98
用于文本到 SQL 的智能体,带有自动错误修正功能
用于文本到 SQL 的智能体,带有自动错误修正功能
在本教程中,我们将学习如何实现一个利用 SQL 的智能体,使用 transformers.agents。
与标准文本到 SQL pipeline 相比,它有什么优势?
标准的文本到 SQL pipeline 是脆弱的,因为生成的 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)让我们检查系统是否能通过一个基本查询正常工作:
with engine.connect() as con:
rows = con.execute(text("""SELECT * from receipts"""))
for row in rows:
print(row)Output
(1, 'Alan Payne', 12.06, 1.2) (2, 'Alex Mason', 23.86, 0.24) (3, 'Woodrow Wilson', 53.43, 5.43) (4, 'Margaret James', 21.11, 1.0)
构建我们的智能体
现在,让我们将 SQL 表格使其可由智能体(工具)检索。
智能体的 description 属性将被嵌入到大语言模型(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)Output
Columns: - receipt_id: INTEGER - customer_name: VARCHAR(16) - price: FLOAT - tip: FLOAT
现在,让我们构建我们的工具。它需要以下内容:(详细信息请参阅文档 )
- 带有
Args:部分的文档字符串 - 类型提示
from transformers.agents 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现在让我们创建一个利用这个工具的智能体。
我们将使用 ReactCodeAgent,它是 transformers.agents 的主要智能体类:一个根据 ReAct 框架编写代码并能迭代先前输出的智能体。
llm_engine 是驱动智能体系统的 LLM。HfEngine 允许你通过 HF 的推理 API 调用 LLM,无论是通过无服务器或专用端点,但你也可以使用任何专有的 API:查看这个指南以了解如何进行适配。
from transformers.agents import ReactCodeAgent, HfApiEngine
agent = ReactCodeAgent(
tools=[sql_engine],
llm_engine=HfApiEngine("meta-llama/Meta-Llama-3-8B-Instruct"),
)agent.run("Can you give me the name of the client who got the most expensive receipt?")Output
[32;20;1m======== New task ========[0m
[37;1mCan you give me the name of the client who got the most expensive receipt?[0m
[33;1m=== Agent thoughts:[0m
[0mThought: I will use the tool sql_engine to query the table'receipts' and retrieve the client who got the most expensive receipt. I will sort the results in descending order based on the 'price' column and then return the client name.[0m
[33;1m>>> Agent is executing the code below:[0m
[0m[38;5;7mreceipts_result[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;7msql_engine[39m[38;5;7m([39m[38;5;7mquery[39m[38;5;109;01m=[39;00m[38;5;144m"[39m[38;5;144mSELECT customer_name, MAX(price) FROM receipts[39m[38;5;144m"[39m[38;5;7m)[39m
[38;5;109mprint[39m[38;5;7m([39m[38;5;7mreceipts_result[39m[38;5;7m)[39m[0m
[33;1m====[0m
[33;1mPrint outputs:[0m
[32;20m
('Woodrow Wilson', 53.43)
[0m
[33;1m=== Agent thoughts:[0m
[0mThought: From the output of the previous step, I can see that Woodrow Wilson got the most expensive receipt with a price of 53.43. Now, I want to verify the client name with the receipt data. I will use the tool sql_engine again to query the table'receipts' and retrieve the receipt information for Woodrow Wilson.[0m
[33;1m>>> Agent is executing the code below:[0m
[0m[38;5;7mreceipt_info[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;7msql_engine[39m[38;5;7m([39m[38;5;7mquery[39m[38;5;109;01m=[39;00m[38;5;144m"[39m[38;5;144mSELECT * FROM receipts WHERE customer_name=[39m[38;5;144m'[39m[38;5;144mWoodrow Wilson[39m[38;5;144m'[39m[38;5;144m"[39m[38;5;7m)[39m
[38;5;109mprint[39m[38;5;7m([39m[38;5;7mreceipt_info[39m[38;5;7m)[39m[0m
[33;1m====[0m
[33;1mPrint outputs:[0m
[32;20m
(3, 'Woodrow Wilson', 53.43, 5.43)
[0m
[33;1m=== Agent thoughts:[0m
[0mThought: From the output of the previous step, I can see that the receipt for Woodrow Wilson has the receipt_id 3, the customer_name 'Woodrow Wilson', the price 53.43, and the tip 5.43. Now, I want to give the final answer of the task using the tool final_answer.[0m
[33;1m>>> Agent is executing the code below:[0m
[0m[38;5;7mfinal_answer[39m[38;5;7m([39m[38;5;144m"[39m[38;5;144mThe client who got the most expensive receipt is Woodrow Wilson.[39m[38;5;144m"[39m[38;5;7m)[39m[0m
[33;1m====[0m
[33;1mPrint outputs:[0m
[32;20m[0m
[33;1mLast output from code snippet:[0m
[32;20mThe client who got the most expensive receipt is Woodrow Wilson.[0m
[32;20;1mFinal answer:[0m
[32;20mThe client who got the most expensive receipt is Woodrow Wilson.[0m
'The client who got the most expensive receipt is Woodrow Wilson.'
提高难度:表格连接
现在让我们增加一点难度!我们希望智能体能够处理跨多个表的连接查询。
因此,让我们创建一个第二个表,用于记录每个 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)我们需要更新 SQLExecutorTool,将这个表的描述添加进去,以便让 LLM 能够正确地利用这个表中的信息。
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)Output
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: Table 'receipts': Columns: - receipt_id: INTEGER - customer_name: VARCHAR(16) - price: FLOAT - tip: FLOAT Table 'waiters': Columns: - receipt_id: INTEGER - waiter_name: VARCHAR(16)
由于这个请求比之前的更具挑战性,我们将切换 LLM 引擎,使用更强大的 Qwen/Qwen2.5-72B-Instruct !
sql_engine.description = updated_description
agent = ReactCodeAgent(
tools=[sql_engine],
llm_engine=HfApiEngine("Qwen/Qwen2.5-72B-Instruct"),
)
agent.run("Which waiter got more total money from tips?")Output
[32;20;1m======== New task ========[0m
[37;1mWhich waiter got more total money from tips?[0m
[33;1m=== Agent thoughts:[0m
[0mThought: I need to first compute the total amount of tips for each waiter. I will use the `sql_engine` tool to perform a query that sums the tips for each waiter.[0m
[33;1m>>> Agent is executing the code below:[0m
[0m[38;5;7mquery[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;144m"""[39m
[38;5;144mSELECT W.waiter_name, SUM(R.tip) as total_tips[39m
[38;5;144mFROM receipts R[39m
[38;5;144mJOIN waiters W ON R.receipt_id = W.receipt_id[39m
[38;5;144mGROUP BY W.waiter_name[39m
[38;5;144m"""[39m
[38;5;7mresult[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;7msql_engine[39m[38;5;7m([39m[38;5;7mquery[39m[38;5;7m)[39m
[38;5;109mprint[39m[38;5;7m([39m[38;5;7mresult[39m[38;5;7m)[39m[0m
[33;1m====[0m
[33;1mPrint outputs:[0m
[32;20m
('Corey Johnson', 1.2)
('Margaret James', 1.0)
('Michael Watts', 5.67)
[0m
[33;1m=== Agent thoughts:[0m
[0mThought: Now I have the total tips for each waiter. I need to compare these values to find the waiter with the highest total tips. I will use Python code to do this.[0m
[33;1m>>> Agent is executing the code below:[0m
[0m[38;5;60;03m# Extracting the total tips from the result[39;00m
[38;5;7mwaiters_tips[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;7m{[39m[38;5;7mrow[39m[38;5;7m[[39m[38;5;139m0[39m[38;5;7m][39m[38;5;7m:[39m[38;5;7m [39m[38;5;7mrow[39m[38;5;7m[[39m[38;5;139m1[39m[38;5;7m][39m[38;5;7m [39m[38;5;109;01mfor[39;00m[38;5;7m [39m[38;5;7mrow[39m[38;5;7m [39m[38;5;109;01min[39;00m[38;5;7m [39m[38;5;109meval[39m[38;5;7m([39m[38;5;7mresult[39m[38;5;7m)[39m[38;5;7m}[39m
[38;5;109mprint[39m[38;5;7m([39m[38;5;7mwaiters_tips[39m[38;5;7m)[39m
[38;5;60;03m# Finding the waiter with the highest total tips[39;00m
[38;5;7mbest_waiter[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;109mmax[39m[38;5;7m([39m[38;5;7mwaiters_tips[39m[38;5;7m,[39m[38;5;7m [39m[38;5;7mkey[39m[38;5;109;01m=[39;00m[38;5;7mwaiters_tips[39m[38;5;109;01m.[39;00m[38;5;7mget[39m[38;5;7m)[39m
[38;5;7mfinal_answer[39m[38;5;7m([39m[38;5;7mbest_waiter[39m[38;5;7m)[39m[0m
[33;1m====[0m
[31;20mCode execution failed due to the following error:
EXECUTION FAILED:
Evaluation stopped at line 'waiters_tips = {row[0]: row[1] for row in eval(result)}' because of the following error:
It is not permitted to evaluate other functions than the provided tools or functions defined in previous code (tried to execute eval).[0m
Traceback (most recent call last):
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 895, in evaluate_python_code
result = evaluate_ast(node, state, static_tools, custom_tools, authorized_imports)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 741, in evaluate_ast
return evaluate_assign(expression, state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 322, in evaluate_assign
result = evaluate_ast(assign.value, state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 825, in evaluate_ast
return evaluate_dictcomp(expression, state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 694, in evaluate_dictcomp
iter_value = evaluate_ast(gen.iter, state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 746, in evaluate_ast
return evaluate_call(expression, state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 385, in evaluate_call
raise InterpreterError(
transformers.agents.python_interpreter.InterpreterError: It is not permitted to evaluate other functions than the provided tools or functions defined in previous code (tried to execute eval).
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/agents.py", line 1135, in step
result = self.python_evaluator(
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 904, in evaluate_python_code
raise InterpreterError(msg)
transformers.agents.python_interpreter.InterpreterError: EXECUTION FAILED:
Evaluation stopped at line 'waiters_tips = {row[0]: row[1] for row in eval(result)}' because of the following error:
It is not permitted to evaluate other functions than the provided tools or functions defined in previous code (tried to execute eval).
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/agents.py", line 811, in direct_run
step_logs = self.step()
^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/agents.py", line 1155, in step
raise AgentExecutionError(error_msg)
transformers.agents.agents.AgentExecutionError: Code execution failed due to the following error:
EXECUTION FAILED:
Evaluation stopped at line 'waiters_tips = {row[0]: row[1] for row in eval(result)}' because of the following error:
It is not permitted to evaluate other functions than the provided tools or functions defined in previous code (tried to execute eval).
[31;20mError in generating llm output: (ReadTimeoutError("HTTPSConnectionPool(host='api-inference.huggingface.co', port=443): Read timed out. (read timeout=120)"), '(Request ID: a887a819-3b3b-4bab-ba37-a05b83a8cbf1)').[0m
Traceback (most recent call last):
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/urllib3/connectionpool.py", line 537, in _make_request
response = conn.getresponse()
^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/urllib3/connection.py", line 466, in getresponse
httplib_response = super().getresponse()
^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/.pyenv/versions/3.12.0/lib/python3.12/http/client.py", line 1411, in getresponse
response.begin()
File "/Users/aymeric/.pyenv/versions/3.12.0/lib/python3.12/http/client.py", line 324, in begin
version, status, reason = self._read_status()
^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/.pyenv/versions/3.12.0/lib/python3.12/http/client.py", line 285, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/.pyenv/versions/3.12.0/lib/python3.12/socket.py", line 707, in readinto
return self._sock.recv_into(b)
^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/.pyenv/versions/3.12.0/lib/python3.12/ssl.py", line 1249, in recv_into
return self.read(nbytes, buffer)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/.pyenv/versions/3.12.0/lib/python3.12/ssl.py", line 1105, in read
return self._sslobj.read(len, buffer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TimeoutError: The read operation timed out
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/requests/adapters.py", line 667, in send
resp = conn.urlopen(
^^^^^^^^^^^^^
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/urllib3/connectionpool.py", line 847, in urlopen
retries = retries.increment(
^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/urllib3/util/retry.py", line 470, in increment
raise reraise(type(error), error, _stacktrace)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/urllib3/util/util.py", line 39, in reraise
raise value
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/urllib3/connectionpool.py", line 793, in urlopen
response = self._make_request(
^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/urllib3/connectionpool.py", line 539, in _make_request
self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/urllib3/connectionpool.py", line 370, in _raise_timeout
raise ReadTimeoutError(
urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='api-inference.huggingface.co', port=443): Read timed out. (read timeout=120)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/agents.py", line 1099, in step
llm_output = self.llm_engine(
^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/llm_engine.py", line 89, in __call__
response = self.client.chat_completion(messages, stop=stop_sequences, max_tokens=1500)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/huggingface_hub/inference/_client.py", line 706, in chat_completion
data = self.post(
^^^^^^^^^^
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/huggingface_hub/inference/_client.py", line 259, in post
response = get_session().post(
^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/requests/sessions.py", line 637, in post
return self.request("POST", url, data=data, json=json, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/requests/sessions.py", line 589, in request
resp = self.send(prep, **send_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/requests/sessions.py", line 703, in send
r = adapter.send(request, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/huggingface_hub/utils/_http.py", line 66, in send
return super().send(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/venvs/cookbook2/lib/python3.12/site-packages/requests/adapters.py", line 713, in send
raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: (ReadTimeoutError("HTTPSConnectionPool(host='api-inference.huggingface.co', port=443): Read timed out. (read timeout=120)"), '(Request ID: a887a819-3b3b-4bab-ba37-a05b83a8cbf1)')
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/agents.py", line 811, in direct_run
step_logs = self.step()
^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/agents.py", line 1103, in step
raise AgentGenerationError(f"Error in generating llm output: {e}.")
transformers.agents.agents.AgentGenerationError: Error in generating llm output: (ReadTimeoutError("HTTPSConnectionPool(host='api-inference.huggingface.co', port=443): Read timed out. (read timeout=120)"), '(Request ID: a887a819-3b3b-4bab-ba37-a05b83a8cbf1)').
[33;1m=== Agent thoughts:[0m
[0mThought: I cannot use `eval` to process the string result. I need to parse the result string in a safer and more direct way. I'll do this by splitting the string and converting it into a dictionary.[0m
[33;1m>>> Agent is executing the code below:[0m
[0m[38;5;60;03m# Parsing the result string into a list of tuples[39;00m
[38;5;7mresult_list[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;7m[[39m[38;5;7mline[39m[38;5;109;01m.[39;00m[38;5;7msplit[39m[38;5;7m([39m[38;5;144m"[39m[38;5;144m, [39m[38;5;144m"[39m[38;5;7m)[39m[38;5;7m [39m[38;5;109;01mfor[39;00m[38;5;7m [39m[38;5;7mline[39m[38;5;7m [39m[38;5;109;01min[39;00m[38;5;7m [39m[38;5;7mresult[39m[38;5;109;01m.[39;00m[38;5;7msplit[39m[38;5;7m([39m[38;5;144m"[39m[38;5;186m\n[39m[38;5;144m"[39m[38;5;7m)[39m[38;5;7m][39m
[38;5;60;03m# Converting the list of tuples into a dictionary[39;00m
[38;5;7mwaiters_tips[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;7m{[39m[38;5;7mrow[39m[38;5;7m[[39m[38;5;139m0[39m[38;5;7m][39m[38;5;109;01m.[39;00m[38;5;7mstrip[39m[38;5;7m([39m[38;5;144m'[39m[38;5;186m\'[39m[38;5;144m'[39m[38;5;7m)[39m[38;5;7m:[39m[38;5;7m [39m[38;5;109mfloat[39m[38;5;7m([39m[38;5;7mrow[39m[38;5;7m[[39m[38;5;139m1[39m[38;5;7m][39m[38;5;109;01m.[39;00m[38;5;7mstrip[39m[38;5;7m([39m[38;5;7m)[39m[38;5;7m)[39m[38;5;7m [39m[38;5;109;01mfor[39;00m[38;5;7m [39m[38;5;7mrow[39m[38;5;7m [39m[38;5;109;01min[39;00m[38;5;7m [39m[38;5;7mresult_list[39m[38;5;7m [39m[38;5;109;01mif[39;00m[38;5;7m [39m[38;5;7mrow[39m[38;5;7m}[39m
[38;5;109mprint[39m[38;5;7m([39m[38;5;7mwaiters_tips[39m[38;5;7m)[39m
[38;5;60;03m# Finding the waiter with the highest total tips[39;00m
[38;5;7mbest_waiter[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;109mmax[39m[38;5;7m([39m[38;5;7mwaiters_tips[39m[38;5;7m,[39m[38;5;7m [39m[38;5;7mkey[39m[38;5;109;01m=[39;00m[38;5;7mwaiters_tips[39m[38;5;109;01m.[39;00m[38;5;7mget[39m[38;5;7m)[39m
[38;5;7mfinal_answer[39m[38;5;7m([39m[38;5;7mbest_waiter[39m[38;5;7m)[39m[0m
[33;1m====[0m
[31;20mCode execution failed due to the following error:
EXECUTION FAILED:
Evaluation stopped at line 'waiters_tips = {row[0].strip('\''): float(row[1].strip()) for row in result_list if row}' because of the following error:
Index 1 out of bounds for list of length 1[0m
Traceback (most recent call last):
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 895, in evaluate_python_code
result = evaluate_ast(node, state, static_tools, custom_tools, authorized_imports)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 741, in evaluate_ast
return evaluate_assign(expression, state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 322, in evaluate_assign
result = evaluate_ast(assign.value, state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 825, in evaluate_ast
return evaluate_dictcomp(expression, state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 700, in evaluate_dictcomp
val = evaluate_ast(dictcomp.value, new_state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 746, in evaluate_ast
return evaluate_call(expression, state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 394, in evaluate_call
args.append(evaluate_ast(arg, state, static_tools, custom_tools))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 746, in evaluate_ast
return evaluate_call(expression, state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 368, in evaluate_call
obj = evaluate_ast(call.func.value, state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 804, in evaluate_ast
return evaluate_subscript(expression, state, static_tools, custom_tools)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 460, in evaluate_subscript
raise InterpreterError(f"Index {index} out of bounds for list of length {len(value)}")
transformers.agents.python_interpreter.InterpreterError: Index 1 out of bounds for list of length 1
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/agents.py", line 1135, in step
result = self.python_evaluator(
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/python_interpreter.py", line 904, in evaluate_python_code
raise InterpreterError(msg)
transformers.agents.python_interpreter.InterpreterError: EXECUTION FAILED:
Evaluation stopped at line 'waiters_tips = {row[0].strip('\''): float(row[1].strip()) for row in result_list if row}' because of the following error:
Index 1 out of bounds for list of length 1
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/agents.py", line 811, in direct_run
step_logs = self.step()
^^^^^^^^^^^
File "/Users/aymeric/Documents/Code/original_transformers/transformers/src/transformers/agents/agents.py", line 1155, in step
raise AgentExecutionError(error_msg)
transformers.agents.agents.AgentExecutionError: Code execution failed due to the following error:
EXECUTION FAILED:
Evaluation stopped at line 'waiters_tips = {row[0].strip('\''): float(row[1].strip()) for row in result_list if row}' because of the following error:
Index 1 out of bounds for list of length 1
[33;1m=== Agent thoughts:[0m
[0mThought: It appears that the result string is not being processed correctly. I need to ensure that the string is split into a list of tuples in a way that correctly captures each row. I'll inspect the result string to understand its exact format.[0m
[33;1m>>> Agent is executing the code below:[0m
[0m[38;5;60;03m# Inspect the result string[39;00m
[38;5;109mprint[39m[38;5;7m([39m[38;5;7mresult[39m[38;5;7m)[39m[0m
[33;1m====[0m
[33;1mPrint outputs:[0m
[32;20m
('Corey Johnson', 1.2)
('Margaret James', 1.0)
('Michael Watts', 5.67)
[0m
[33;1m=== Agent thoughts:[0m
[0mThought: The result string is a list of tuples, but it's not in a format that can be directly parsed using `split`. I need to handle the result string more carefully. I'll use a list comprehension to process the string and extract the waiter names and their total tips.[0m
[33;1m>>> Agent is executing the code below:[0m
[0m[38;5;60;03m# Split the result string into individual lines[39;00m
[38;5;7mlines[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;7mresult[39m[38;5;109;01m.[39;00m[38;5;7mstrip[39m[38;5;7m([39m[38;5;144m"[39m[38;5;144m[][39m[38;5;144m"[39m[38;5;7m)[39m[38;5;109;01m.[39;00m[38;5;7mreplace[39m[38;5;7m([39m[38;5;144m"[39m[38;5;144m)[39m[38;5;144m"[39m[38;5;7m,[39m[38;5;7m [39m[38;5;144m"[39m[38;5;144m"[39m[38;5;7m)[39m[38;5;109;01m.[39;00m[38;5;7mreplace[39m[38;5;7m([39m[38;5;144m"[39m[38;5;144m([39m[38;5;144m"[39m[38;5;7m,[39m[38;5;7m [39m[38;5;144m"[39m[38;5;144m"[39m[38;5;7m)[39m[38;5;109;01m.[39;00m[38;5;7msplit[39m[38;5;7m([39m[38;5;144m"[39m[38;5;186m\n[39m[38;5;144m"[39m[38;5;7m)[39m
[38;5;60;03m# Process each line to create a dictionary of waiters and their total tips[39;00m
[38;5;7mwaiters_tips[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;7m{[39m[38;5;7m}[39m
[38;5;109;01mfor[39;00m[38;5;7m [39m[38;5;7mline[39m[38;5;7m [39m[38;5;109;01min[39;00m[38;5;7m [39m[38;5;7mlines[39m[38;5;7m:[39m
[38;5;7m [39m[38;5;109;01mif[39;00m[38;5;7m [39m[38;5;7mline[39m[38;5;109;01m.[39;00m[38;5;7mstrip[39m[38;5;7m([39m[38;5;7m)[39m[38;5;7m:[39m
[38;5;7m [39m[38;5;7mwaiter[39m[38;5;7m,[39m[38;5;7m [39m[38;5;7mtip[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;7mline[39m[38;5;109;01m.[39;00m[38;5;7mstrip[39m[38;5;7m([39m[38;5;7m)[39m[38;5;109;01m.[39;00m[38;5;7msplit[39m[38;5;7m([39m[38;5;144m"[39m[38;5;144m, [39m[38;5;144m"[39m[38;5;7m)[39m
[38;5;7m [39m[38;5;7mwaiters_tips[39m[38;5;7m[[39m[38;5;7mwaiter[39m[38;5;109;01m.[39;00m[38;5;7mstrip[39m[38;5;7m([39m[38;5;7m)[39m[38;5;109;01m.[39;00m[38;5;7mstrip[39m[38;5;7m([39m[38;5;144m"[39m[38;5;144m'[39m[38;5;144m"[39m[38;5;7m)[39m[38;5;7m][39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;109mfloat[39m[38;5;7m([39m[38;5;7mtip[39m[38;5;109;01m.[39;00m[38;5;7mstrip[39m[38;5;7m([39m[38;5;7m)[39m[38;5;7m)[39m
[38;5;109mprint[39m[38;5;7m([39m[38;5;7mwaiters_tips[39m[38;5;7m)[39m
[38;5;60;03m# Finding the waiter with the highest total tips[39;00m
[38;5;7mbest_waiter[39m[38;5;7m [39m[38;5;109;01m=[39;00m[38;5;7m [39m[38;5;109mmax[39m[38;5;7m([39m[38;5;7mwaiters_tips[39m[38;5;7m,[39m[38;5;7m [39m[38;5;7mkey[39m[38;5;109;01m=[39;00m[38;5;7mwaiters_tips[39m[38;5;109;01m.[39;00m[38;5;7mget[39m[38;5;7m)[39m
[38;5;7mfinal_answer[39m[38;5;7m([39m[38;5;7mbest_waiter[39m[38;5;7m)[39m[0m
[33;1m====[0m
[33;1mPrint outputs:[0m
[32;20m{'Corey Johnson': 1.2, 'Margaret James': 1.0, 'Michael Watts': 5.67}
[0m
[33;1mLast output from code snippet:[0m
[32;20mMichael Watts[0m
[32;20;1mFinal answer:[0m
[32;20mMichael Watts[0m
'Michael Watts'
它直接就能工作!设置过程出乎意料地简单,不是吗?
✅ 现在你可以去构建你一直梦想的文本到 SQL 系统了!✨
