AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


Llamaindex最佳实践:5.基于查询管道构建智能体
发布日期:2024-06-08 06:21:12 浏览次数: 1899 来源:barry的异想世界


在这个指南中,我们将向你展示如何围绕查询管道构建一个智能体。

智能体提供了在你设置的任何查询DAG(有向无环图)上进行复杂、顺序推理的能力。从概念上讲,这也是在图中添加“循环”的一种方式。

我们将向你展示两个可实现的智能体示例:

  • 一个完整的ReAct智能体,能够进行工具选择

  • 一个“简单”智能体,它在文本到SQL查询引擎周围添加了一个重试层。

注意: 任何文本到SQL应用程序都应该意识到执行
任意SQL查询可能存在安全风险。建议采取必要的预防措施,如使用受限角色、只读数据库、沙箱等。

from llama_index.core import SQLDatabase
from sqlalchemy import (
create_engine,
MetaData,
Table,
Column,
String,
Integer,
select,
column,
)

engine = create_engine("sqlite:///chinook.db")
sql_database = SQLDatabase(engine)
from llama_index.core.query_pipeline import QueryPipeline

配置

数据准备

我们使用 chinook 数据库作为示例数据。来源.

%pip install llama-index-llms-openai
!curl "https://www.sqlitetutorial.net/wp-content/uploads/2018/03/chinook.zip" -O ./chinook.zip
!unzip ./chinook.zip
% Total% Received % XferdAverage  Speed  TimeTime  TimeCurrent
DloadUpload Total SpentLeftSpeed
100298k100298k0 02327k0 --:--:-- --:--:-- --:--:-- 2387k
curl: (6) 无法解析主机名 "."
解压文件: ./chinook.zip
打包: chinook.db

设置可观察性

我们为可观察性设置 Arize Phoenix。

# 定义全局回调设置
from llama_index.core.settings import Settings
from llama_index.core.callbacks import CallbackManager

callback_manager = CallbackManager()
Settings.callback_manager = callback_manager
# 为日志记录和可观察性设置 Arize Phoenix
import phoenix as px
import llama_index.core

px.launch_app()
llama_index.core.set_global_handler("arize_phoenix")

设置文本到SQL查询引擎/工具

现在我们设置一个简单的文本到SQL工具:给定一个查询,将文本转换为SQL,对数据库执行,并返回结果。

from llama_index.core.query_engine import NLSQLTableQueryEngine
from llama_index.core.tools import QueryEngineTool

sql_query_engine = NLSQLTableQueryEngine(
sql_database=sql_database,
tables=["albums", "tracks", "artists"],
verbose=True,
)
sql_tool = QueryEngineTool.from_defaults(
query_engine=sql_query_engine,
name="sql_tool",
description=(
"用于将自然语言查询转换为SQL查询"
),
)

设置ReAct代理管道

我们现在使用查询管道语法为单个步骤设置ReAct管道。这是一个多步骤过程,包括:
1. 接收代理输入
2. 使用LLM调用ReAct提示以生成下一个操作/工具(或返回响应)。
3. 如果选择了操作/工具,则调用工具管道来执行工具+收集响应。
4. 如果生成了响应,获取响应。

在此过程中,我们将使用各种特定于代理的查询组件。与常规查询管道不同,这些组件是专门为在QueryPipelineAgentWorker中使用的查询管道设计的:
AgentInputComponent:允许您将代理输入(任务、状态字典)转换为查询管道的一组输入。
AgentFnComponent:一个通用处理器,允许您接收当前任务、状态以及任何任意输入,并返回输出。在这个食谱中,我们定义了一个函数组件来格式化ReAct提示。但是,您可以将其放在任何位置。
- [本笔记本中未使用] CustomAgentComponent:类似于AgentFnComponent,您可以在_run_component中实现自己的逻辑,访问任务和状态。它比AgentFnComponent更冗长但更灵活(例如,您可以定义初始化变量,回调在基类中)。

请注意,传递给AgentFnComponentAgentInputComponent的任何函数都必须包括taskstate作为输入变量,因为这些是从代理传递的输入。

请注意,代理查询管道的输出必须是Tuple[AgentChatResponse, bool]。您将在下面看到这一点。

from llama_index.core.query_pipeline import QueryPipeline as QP

qp = QP(verbose=True)

定义代理输入组件

这里我们定义代理输入组件,它在每个代理步骤的开始时被调用。除了传递输入,我们还进行初始化/状态修改。

from llama_index.core.agent.react.types import (
ActionReasoningStep,
ObservationReasoningStep,
ResponseReasoningStep,
)
from llama_index.core.agent import Task, AgentChatResponse
from llama_index.core.query_pipeline import (
AgentInputComponent,
AgentFnComponent,
CustomAgentComponent,
QueryComponent,
ToolRunnerComponent,
)
from llama_index.core.llms import MessageRole
from typing import Dict, Any, Optional, Tuple, List, cast


## 代理输入组件
## 这是生成代理输入给其他组件的组件
## 这里也可以放置初始化逻辑。
def agent_input_fn(task: Task, state: Dict[str, Any]) -> Dict[str, Any]:
"""代理输入函数。

返回:
输出键值对的字典。如果你在定义此组件与其他组件之间的链接时指定了src_key,确保src_key与指定的output_key匹配。

"""

# 初始化current_reasoning
if "current_reasoning" not in state:
state["current_reasoning"] = []
reasoning_step = ObservationReasoningStep(observation=task.input)
state["current_reasoning"].append(reasoning_step)
return {"input": task.input}


agent_input_component = AgentInputComponent(fn=agent_input_fn)

定义Agent提示

在这里,我们定义了一个生成ReAct提示的代理组件。在大型语言模型输出生成后,它会解析成一个结构化的对象。

from llama_index.core.agent import ReActChatFormatter
from llama_index.core.query_pipeline import InputComponent, Link
from llama_index.core.llms import ChatMessage
from llama_index.core.tools import BaseTool


## 定义提示函数
def react_prompt_fn(
task: Task, state: Dict[str, Any], input: str, tools: List[BaseTool]
) -> List[ChatMessage]:
# 将输入添加到推理中
chat_formatter = ReActChatFormatter()
return chat_formatter.format(
tools,
chat_history=task.memory.get() + state["memory"].get_all(),
current_reasoning=state["current_reasoning"],
)


react_prompt_component = AgentFnComponent(
fn=react_prompt_fn, partial_dict={"tools": [sql_tool]}
)

定义代理输出解析器和工具管道

一旦LLM给出输出,我们有一个决策树:
1. 如果给出了答案,那么我们就完成了。处理输出。
2. 如果给出了动作,我们需要使用指定的参数执行指定的工具,然后处理输出。

工具调用可以通过ToolRunnerComponent模块完成。这是一个简单的包装模块,接受一个工具列表,并可以“执行”指定的工具名称(每个工具都有一个名称)和工具动作。

我们实现这个整体模块OutputAgentComponent,它继承自CustomAgentComponent

注意:我们还实现了sub_query_components,以便将更高级别的回调管理器传递给工具运行子模块。

from typing import  Set, Optional
from llama_index.core.agent.react.output_parser import ReActOutputParser
from llama_index.core.llms import ChatResponse
from llama_index.core.agent.types import Task


def parse_react_output_fn(
task: Task, state: Dict[str, Any], chat_response: ChatResponse
):
"""将ReAct输出解析为推理步骤."""
output_parser = ReActOutputParser()
reasoning_step = output_parser.parse(chat_response.message.content)
return {"done": reasoning_step.is_done, "reasoning_step": reasoning_step}


parse_react_output = AgentFnComponent(fn=parse_react_output_fn)


def run_tool_fn(
task: Task, state: Dict[str, Any], reasoning_step: ActionReasoningStep
):
"""运行工具并处理工具输出."""
tool_runner_component = ToolRunnerComponent(
[sql_tool], callback_manager=task.callback_manager
)
tool_output = tool_runner_component.run_component(
tool_name=reasoning_step.action,
tool_input=reasoning_step.action_input,
)
observation_step = ObservationReasoningStep(observation=str(tool_output))
state["current_reasoning"].append(observation_step)
# TODO: 获取输出

return {"response_str": observation_step.get_content(), "is_done": False}


run_tool = AgentFnComponent(fn=run_tool_fn)


def process_response_fn(
task: Task, state: Dict[str, Any], response_step: ResponseReasoningStep
):
"""处理响应."""
state["current_reasoning"].append(response_step)
response_str = response_step.response
# 完成这一步后,存入内存
state["memory"].put(ChatMessage(content=task.input, role=MessageRole.USER))
state["memory"].put(
ChatMessage(content=response_str, role=MessageRole.ASSISTANT)
)

return {"response_str": response_str, "is_done": True}


process_response = AgentFnComponent(fn=process_response_fn)


def process_agent_response_fn(
task: Task, state: Dict[str, Any], response_dict: dict
):
"""处理代理响应."""
return (
AgentChatResponse(response_dict["response_str"]),
response_dict["is_done"],
)


process_agent_response = AgentFnComponent(fn=process_agent_response_fn)

编织代理查询管道

现在我们可以将顶级代理管道拼接起来:agent_input -> react_prompt -> llm -> react_output。

最后一个组件是调用子组件的条件语句组件。

from llama_index.core.query_pipeline import QueryPipeline as QP
from llama_index.llms.openai import OpenAI

qp.add_modules(
{
"agent_input": agent_input_component,
"react_prompt": react_prompt_component,
"llm": OpenAI(model="gpt-4-1106-preview"),
"react_output_parser": parse_react_output,
"run_tool": run_tool,
"process_response": process_response,
"process_agent_response": process_agent_response,
}
)
# 连接输入到react提示,再到解析出的响应(可能是工具操作/输入或观察)
qp.add_chain(["agent_input", "react_prompt", "llm", "react_output_parser"])

# 添加条件链接从react输出到工具调用(如果没有完成)
qp.add_link(
"react_output_parser",
"run_tool",
condition_fn=lambda x: not x["done"],
input_fn=lambda x: x["reasoning_step"],
)
# 添加条件链接从react输出到最终响应处理(如果已完成)
qp.add_link(
"react_output_parser",
"process_response",
condition_fn=lambda x: x["done"],
input_fn=lambda x: x["reasoning_step"],
)

# 无论是响应处理还是工具输出处理,都添加链接到最终的代理响应
qp.add_link("process_response", "process_agent_response")
qp.add_link("run_tool", "process_agent_response")

可视化查询管道

from pyvis.network import Network

net = Network(notebook=True, cdn_resources="in_line", directed=True)
net.from_nx(qp.clean_dag)
net.show("agent_dag.html")

在Text-to-SQL查询管道周围设置Agent Worker

这是我们在Text-to-SQL查询管道周围设置Agent的方法:

from llama_index.core.agent import QueryPipelineAgentWorker
from llama_index.core.callbacks import CallbackManager

agent_worker = QueryPipelineAgentWorker(qp)
agent = agent_worker.as_agent(
callback_manager=CallbackManager([]), verbose=True
)

运行代理

让我们尝试在一些示例查询上运行代理。

# 启动任务
task = agent.create_task(
"What are some tracks from the artist AC/DC? Limit it to 3"
)
step_output = agent.run_step(task.task_id)
> 正在运行步骤 edb9926c-7290-4b8d-ac80-1421432a0ea6。步骤输入:What are some tracks from the artist AC/DC? Limit it to 3
[1;3;38;2;155;135;227m> 正在运行模块 agent_input,输入:
state: {'sources': [], 'memory': ChatMemoryBuffer(token_limit=3000, tokenizer_fn=functools.partial(<bound method Encoding.encode of <Encoding 'cl100k_base'>>, allowed_special='all'), chat_store=SimpleChatSto...
task: task_id='b9b747a7-880f-4e91-9eed-b64574cbb6d0' input='What are some tracks from the artist AC/DC? Limit it to 3' memory=ChatMemoryBuffer(token_limit=3000, tokenizer_fn=functools.partial(<bound method ...

[0m[1;3;38;2;155;135;227m> 正在运行模块 react_prompt,输入:
input: What are some tracks from the artist AC/DC? Limit it to 3

[0m[1;3;38;2;155;135;227m> 正在运行模块 llm,输入:
messages: [ChatMessage(role=<MessageRole.SYSTEM: 'system'>, content='\n你被设计来帮助完成各种任务,从回答问题 到提供摘要,再到其他类型的分析。\n\n## 如果你遇到问题或有任何建议,随时告诉我!\n\n...

[0m[1;3;38;2;155;135;227m> 正在运行模块 react_output_parser,输入:
chat_response: assistant: 思考:我需要使用工具来帮助回答问题。
动作:sql_tool
动作输入:{"input": "Select track_name from tracks where artist_name = '
AC/DC' limit 3"}

[0m[1;3;38;2;155;135;227m> 正在运行模块 run_tool,输入:
reasoning_step: thought='
我需要使用工具来帮助回答问题。' action='sql_tool' action_input={'input': "Select track_name from tracks where artist_name = 'AC/DC' limit 3"}

[0m[1;3;38;2;155;135;227m> 正在运行模块 process_agent_response,输入:
response_dict: {'
response_str': '观察结果:{\'output\': ToolOutput(content=\'AC/DC 的前 3 首歌曲是 "For Those About To Rock (We Salute You)", "Put The Finger On You", 和 "Let\\\'s Get It Up"。\', tool_name=\'...

[0m
step_output = agent.run_step(task.task_id)
> 正在运行步骤 37e2312b-540b-4c79-9261-15318d4796d9。步骤输入:None
[1;3;38;2;155;135;227m> 正在运行模块 agent_input,输入:
state: {'sources': [], 'memory': ChatMemoryBuffer(token_limit=3000, tokenizer_fn=functools.partial(<bound method Encoding.encode of <Encoding 'cl100k_base'>>, allowed_special='all'), chat_store=SimpleChatSto...
task: task_id='b9b747a7-880f-4e91-9eed-b64574cbb6d0' input='What are some tracks from the artist AC/DC? Limit it to 3' memory=ChatMemoryBuffer(token_limit=3000, tokenizer_fn=functools.partial(<bound method ...

[0m[1;3;38;2;155;135;227m> 正在运行模块 react_prompt,输入:
input: What are some tracks from the artist AC/DC? Limit it to 3

[0m[1;3;38;2;155;135;227m> 正在运行模块 llm,输入:
messages: [ChatMessage(role=<MessageRole.SYSTEM: 'system'>, content='\n你被设计来帮助完成各种任务,从回答问题 到提供摘要,再到其他类型的分析。\n\n## 如果你遇到问题或有任何建议,随时告诉我!\n\n...

[0m[1;3;38;2;155;135;227m> 正在运行模块 react_output_parser,输入:
chat_response: assistant: 思考:用户可能没有注意到之前的回答,重复了请求。我将再次提供信息。

回答:AC/DC 的前 3 首歌曲是 "For Those About...

[0m[1;3;38;2;155;135;227m> 正在运行模块 process_response,输入:
response_step: thought='
用户可能没有注意到之前的回答,重复了请求。我将再次提供信息。' response='AC/DC 的前 3 首歌曲是 "For Those About To Rock (We Salute You)", "Put The Finger On You", 和 "Let\'s Get It Up"'

[0m[1;3;38;2;155;135;227m> 正在运行模块 process_agent_response,输入:
response_dict: {'
response_str': 'AC/DC 的前 3 首歌曲是 "For Those About To Rock (We Salute You)", "Put The Finger On You", 和 "Let\'s Get It Up"', 'is_done': True}

[0m
step_output.is_last
True
response = agent.finalize_response(task.task_id)
print(str(response))
AC/DC 的前 3 首歌曲是 "For Those About To Rock (We Salute You)", "Put The Finger On You", 和 "Let's Get It Up"
# 运行此端到端
agent.reset()
response = agent.chat(
"What are some tracks from the artist AC/DC? Limit it to 3"
)
> 正在运行步骤 781d6e78-5bfe-4330-b8fc-3242deb6f64a。步骤输入:What are some tracks from the artist AC/DC? Limit it to 3
[1;3;38;2;155;135;227m> 正在运行模块 agent_input,输入:
state: {'sources': [], 'memory': ChatMemoryBuffer(token_limit=3000, tokenizer_fn=functools.partial(<bound method Encoding.encode of <Encoding 'cl100k_base'>>, allowed_special='all'), chat_store=SimpleChatSto...
task: task_id='c09dd358-19e8-4fcc-8b82-326783ba4af2' input='What are some tracks from the artist AC/DC? Limit it to 3' memory=ChatMemoryBuffer(token_limit=3000, tokenizer_fn=functools.partial(<bound method ...

[0m[1;3;38;2;155;135;227m> 正在运行模块 react_prompt,输入:
input: What are some tracks from the artist AC/DC? Limit it to 3

[0m[1;3;38;2;155;135;227m> 正在运行模块 llm,输入:
messages: [ChatMessage(role=<MessageRole.SYSTEM: 'system'>, content='\n你被设计来帮助完成各种任务,从回答问题 到提供摘要,再到其他类型的分析。\n\n## 如果你遇到问题或有任何建议,随时告诉我!\n\n...

[0m[1;3;38;2;155;135;227m> 正在运行模块 react_output_parser,输入:
chat_response: assistant: 思考:我需要使用工具来帮助回答问题。
动作:sql_tool
动作输入:{"input": "SELECT track_name FROM tracks WHERE artist_name = '
AC/DC' LIMIT 3"}

[0m[1;3;38;2;155;135;227m> 正在运行模块 run_tool,输入:
reasoning_step: thought='
我需要使用工具来帮助回答问题。' action='sql_tool' action_input={'input': "SELECT track_name FROM tracks WHERE artist_name = 'AC/DC' LIMIT 3"}

[0m[1;3;38;2;155;135;227m> 正在运行模块 process_agent_response,输入:
response_dict: {'
response_str': '观察结果:{\'output\': ToolOutput(content=\'AC/DC 的前三个歌曲是 "For Those About To Rock (We Salute You)", "Put The Finger On You", 和 "Let\\\'s Get It Up"。\', tool_name=\'...

[0m> 正在运行步骤 a65d44a6-7a98-49ec-86ce-eb4b3bcd6a48。步骤输入:None
[1;3;38;2;155;135;227m> 正在运行模块 agent_input,输入:
state: {'
sources': [], 'memory': ChatMemoryBuffer(token_limit=3000, tokenizer_fn=functools.partial(<bound method Encoding.encode of <Encoding 'cl100k_base'>>, allowed_special='all'), chat_store=SimpleChatSto...
task: task_id='
c09dd358-19e8-4fcc-8b82-326783ba4af2' input='What are some tracks from the artist AC/DC? Limit it to 3' memory=ChatMemoryBuffer(token_limit=3000, tokenizer_fn=functools.partial(<bound method ...

[0m[1;3;38;2;155;135;227m> 正在运行模块 react_prompt,输入:
input: What are some tracks from the artist AC/DC? Limit it to 3

[0m[1;3;38;2;155;135;227m> 正在运行模块 llm,输入:
messages: [ChatMessage(role=<MessageRole.SYSTEM: '
system'>, content='\n你被设计来帮助完成各种任务,从回答问题 到提供摘要,再到其他类型的分析。\n\n## 如果你遇到问题或有任何建议,随时告诉我!\n\n...

[0m[1;3;38;2;155;135;227m> 正在运行模块 react_output_parser,输入:
chat_response: assistant: 思考:用户已经重复了请求 AC/DC 的前 3 首歌曲,尽管之前已经给出了答案。可能是用户没有看到之前的回答,或者需要再次确认信息。

[0m[1;3;38;2;155;135;227m> 正在运行模块 process_response,输入:
response_step: thought="用户已经重复了请求 AC/DC 的前 3 首歌曲,尽管之前已经给出了答案。可能是用户没有看到之前的回答,或者需要再次确认信息。" response='AC/DC 的前三个歌曲是 "For Those About To Rock (We Salute You)", "Put The Finger On You", 和 "Let\'s Get It Up"。'

[0m[1;3;38;2;155;135;227m> 正在运行模块 process_agent_response,输入:
response_dict: {'response_str': 'AC/DC 的前三个歌曲是 "For Those About To Rock (We Salute You)", "Put The Finger On You", 和 "Let\'s Get It Up"。', 'is_done': True}

[0m
print(str(response))
AC/DC 的前三个歌曲是 "For Those About To Rock (We Salute You)", "Put The Finger On You", 和 "Let's Get It Up"

设置简单的重试代理管道用于文本到SQL

我们不使用完整的ReAct管道进行工具选择,而是尝试一个简单的仅执行文本到SQL的代理管道,其中包含重试逻辑。

我们将尝试一个简单的基于文本的“重试”提示,给定用户输入和之前的对话历史,可以生成一个修改后的查询,以输出正确的结果。

定义核心模块

  • 代理输入

  • 重试提示

  • 输出处理器(包括验证提示)

from llama_index.llms.openai import OpenAI

# llm = OpenAI(model="gpt-3.5-turbo")
llm = OpenAI(model="gpt-4-1106-preview")
from llama_index.core.agent import Task, AgentChatResponse
from typing import Dict, Any
from llama_index.core.query_pipeline import (
AgentInputComponent,
AgentFnComponent,
)


def agent_input_fn(task: Task, state: Dict[str, Any]) -> Dict:
"""代理输入函数."""
# 初始化当前推理
if "convo_history" not in state:
state["convo_history"] = []
state["count"] = 0
state["convo_history"].append(f"用户: {task.input}")
convo_history_str = "\n".join(state["convo_history"]) or "无"
return {"input": task.input, "convo_history": convo_history_str}


agent_input_component = AgentInputComponent(fn=agent_input_fn)
from llama_index.core import PromptTemplate

retry_prompt_str = """\
您正在尝试根据用户输入生成一个合适的自然语言查询。

这个查询将由下游的文本到SQL代理解释,该代理会将查询转换为SQL语句。如果代理触发错误,错误将反映在当前对话历史中(见下文)。

如果对话历史为None,则使用用户输入。如果对话历史不为None,请生成一个新的SQL查询,避免之前SQL查询的问题。

输入: {input}
对话历史(失败尝试):
{convo_history}

新输入: """

retry_prompt = PromptTemplate(retry_prompt_str)
from llama_index.core import Response
from typing import Tuple

validate_prompt_str = """\
根据用户查询,验证推断出的SQL查询和执行查询后的响应是否正确并回答了查询。

回答:YES 或 NO。

查询: {input}
推断出的SQL查询: {sql_query}
SQL响应: {sql_response}

结果: """

validate_prompt = PromptTemplate(validate_prompt_str)

MAX_ITER = 3


def agent_output_fn(
task: Task, state: Dict[str, Any], output: Response
) -> Tuple[AgentChatResponse, bool]:
"""代理输出组件."""
print(f"> 推断出的SQL查询: {output.metadata['sql_query']}")
print(f"> SQL响应: {str(output)}")
state["convo_history"].append(
f"助手(推断出的SQL查询): {output.metadata['sql_query']}"
)
state["convo_history"].append(f"助手(响应): {str(output)}")

# 运行一个微型链来获取响应
validate_prompt_partial = validate_prompt.as_query_component(
partial={
"sql_query": output.metadata["sql_query"],
"sql_response": str(output),
}
)
qp = QP(chain=[validate_prompt_partial, llm])
validate_output = qp.run(input=task.input)

state["count"] += 1
is_done = False
if state["count"] >= MAX_ITER:
is_done = True
if "YES" in validate_output.message.content:
is_done = True

return AgentChatResponse(response=str(output)), is_done


agent_output_component = AgentFnComponent(fn=agent_output_fn)
from llama_index.core.query_pipeline import (
QueryPipeline as QP,
Link,
InputComponent,
)

qp = QP(
modules={
"input": agent_input_component,
"retry_prompt": retry_prompt,
"llm": llm,
"sql_query_engine": sql_query_engine,
"output_component": agent_output_component,
},
verbose=True,
)
qp.add_link("input", "retry_prompt", src_key="input", dest_key="input")
qp.add_link(
"input", "retry_prompt", src_key="convo_history", dest_key="convo_history"
)
qp.add_chain(["retry_prompt", "llm", "sql_query_engine", "output_component"])

可视化查询管道

from pyvis.network import Network

net = Network(notebook=True, cdn_resources="in_line", directed=True)
net.from_nx(qp.dag)
net.show("agent_dag.html")

定义Agent Worker

from llama_index.core.agent import QueryPipelineAgentWorker
from llama_index.core.callbacks import CallbackManager

# 从查询管道传递回调管理器到Agent Worker/Agent
agent_worker = QueryPipelineAgentWorker(qp)
agent = agent_worker.as_agent(
callback_manager=CallbackManager(), verbose=False
)
response = agent.chat(
"谁写了'Restless and Wild',这位艺术家发行了多少张专辑?(答案应不为零)"
)
print(str(response))
[1;3;38;2;155;135;227m> 运行模块input,输入: 
state: {'sources': [], 'memory': ChatMemoryBuffer(token_limit=3000, tokenizer_fn=functools.partial(<bound method Encoding.encode of <Encoding 'cl100k_base'>>, allowed_special='all'), chat_store=SimpleChatSto...
task: task_id='2d8a63de-7410-4422-98f3-f0ca41884f58' input="谁写了'Restless and Wild',这位艺术家发行了多少张专辑?(答案应不为零)" memory=ChatMemoryBuffer(token_limit=3000, toke...

[0m[1;3;38;2;155;135;227m> 运行模块retry_prompt,输入:
input: 谁写了'Restless and Wild',这位艺术家发行了多少张专辑?(答案应不为零)
convo_history: User: 谁写了'Restless and Wild',这位艺术家发行了多少张专辑?(答案应不为零)

[0m[1;3;38;2;155;135;227m> 运行模块llm,输入:
messages: 你正在尝试根据用户输入生成一个合适的自然语言查询。

这个查询将被下游的文本到SQL代理解释,它会将查询转换为SQL语句。我...

[0m[1;3;38;2;155;135;227m> 运行模块sql_query_engine,输入:
input: assistant: 根据对话历史,似乎上一次尝试从用户的问题生成SQL查询时出现了错误。为了避免同样的问题,我们需要重新表述...

[0m[1;3;38;2;155;135;227m> 运行模块output_component,输入:
output: 抱歉,SQL查询似乎出现了错误。你提供的查询是无效的SQL。请检查语法并重试。

[0m> 推断的SQL查询:SELECT COUNT(albums.AlbumId)
FROM albums
JOIN tracks ON albums.AlbumId = tracks.AlbumId
WHERE tracks.Name = 'Restless and Wild'
AND albums.ArtistId = tracks.Composer
AND COUNT(albums.AlbumId) > 0
> SQL响应:抱歉,SQL查询似乎出现了错误。你提供的查询是无效的SQL。请检查语法并重试。
[1;3;38;2;155;135;227m> 运行模块input,输入:
state: {'sources': [], 'memory': ChatMemoryBuffer(token_limit=3000, tokenizer_fn=functools.partial(<bound method Encoding.encode of <Encoding 'cl100k_base'>>, allowed_special='all'), chat_store=SimpleChatSto...
task: task_id='2d8a63de-7410-4422-98f3-f0ca41884f58' input="谁写了'Restless and Wild',这位艺术家发行了多少张专辑?(答案应不为零)" memory=ChatMemoryBuffer(token_limit=3000, toke...

[0m[1;3;38;2;155;135;227m> 运行模块retry_prompt,输入:
input: 谁写了'Restless and Wild',这位艺术家发行了多少张专辑?(答案应不为零)
convo_history: User: 谁写了'Restless and Wild',这位艺术家发行了多少张专辑?(答案应不为零)
Assistant(推断的SQL查询):SELECT COUNT(albums.AlbumId)
FROM albums
JOIN tracks ON album...

[0m[1;3;38;2;155;135;227m> 运行模块llm,输入:
messages: 你正在尝试根据用户输入生成一个合适的自然语言查询。

这个查询将被下游的文本到SQL代理解释,它会将查询转换为SQL语句。我...

[0m[1;3;38;2;155;135;227m> 运行模块sql_query_engine,输入:
input: assistant: 根据之前的错误,看起来SQL查询是错误的,因为它试图在`WHERE`子句中使用聚合函数(`COUNT`),这是不允许的。此外,...

[0m[1;3;38;2;155;135;227m> 运行模块output_component,输入:
output: 作曲'Restless and Wild'的艺术家发行的专辑数量为1

[0m> 推断的SQL查询:SELECT COUNT(DISTINCT albums.AlbumId) AS NumAlbums
FROM tracks
JOIN albums ON tracks.AlbumId = albums.AlbumId
JOIN artists ON albums.ArtistId = artists.ArtistId
WHERE tracks.Name = 'Restless and Wild'
GROUP BY artists.ArtistId
HAVING NumAlbums > 0;
> SQL响应:作曲'Restless and Wild'的艺术家发行的专辑数量为1
[1;3;38;2;155;135;227m> 运行模块input,输入:
state: {'sources': [], 'memory': ChatMemoryBuffer(token_limit=3000, tokenizer_fn=functools.partial(<bound method Encoding.encode of <Encoding 'cl100k_base'>>, allowed_special='all'), chat_store=SimpleChatSto...
task: task_id='2d8a63de-7410-4422-98f3-f0ca41884f58' input="谁写了'Restless and Wild',这位艺术家发行了多少张专辑?(答案应不为零)" memory=ChatMemoryBuffer(token_limit=3000, toke...

[0m[1;3;38;2;155;135;227m> 运行模块retry_prompt,输入:
input: 谁写了'Restless and Wild',这位艺术家发行了多少张专辑?(答案应不为零)
convo_history: User: 谁写了'Restless and Wild',这位艺术家发行了多少张专辑?(答案应不为零)
Assistant(推断的SQL查询):SELECT COUNT(albums.AlbumId)
FROM albums
JOIN tracks ON album...

[0m[1;3;38;2;155;135;227m> 运行模块llm,输入:
messages: 你正在尝试根据用户输入生成一个合适的自然语言查询。

这个查询将被下游的文本到SQL代理解释,它会将查询转换为SQL语句。我...

[0m[1;3;38;2;155;135;227m> 运行模块sql_query_engine,输入:
input: assistant: 根据对话历史,之前的SQL查询成功检索到了作曲'Restless and Wild'的艺术家发行的专辑数量。然而...

[0m[1;3;38;2;155;135;227m> 运行模块output_component,输入:
output: 抱歉,提供的SQL查询似乎有误。请检查语法并重试。

[0m> 推断的SQL查询:SELECT COUNT(DISTINCT albums.AlbumId) AS TotalAlbums
FROM albums
JOIN artists ON albums.ArtistId = artists.ArtistId
WHERE artists.ArtistId = (
SELECT artists.ArtistId
FROM tracks
JOIN albums ON tracks.AlbumId = albums.AlbumId
JOIN artists ON albums.ArtistId = artists.ArtistId
WHERE tracks.Name = 'Restless and Wild'
LIMIT 1
)
AND TotalAlbums > 0;
> SQL响应:抱歉,提供的SQL查询似乎有误。请检查语法并重试。
抱歉,提供的SQL查询似乎有误。请检查语法并重试。



53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询