用LangChain和CrewAI构建AI驱动的SQL数据分析代理

2024年12月03日 由 alex 发表 32 0

在当今这个数据驱动的世界里,自动化数据提取、分析和报告的工作流程对于节省时间和提高效率至关重要。本文将指导你如何使用LangChain和CrewAI构建一个由人工智能驱动的SQL工作流程。通过集成强大的Llama 3模型、SQL数据库工具和基于代理的自动化,你将学习如何创建一个无缝的管道来处理数据库查询、分析结果并生成高管报告——所有这些都只需极少的手动干预。无论你是数据爱好者、开发人员还是机器学习工程师,本指南都将帮助你在数据工作流程中实现更高层次的生产力。


9


环境设置


安装依赖项

首先,请确保你已经安装了Python,并使用以下代码来设置所需的库:


!pip install langchain-core==0.2.15 langchain-community==0.2.6 'crewai[tools]'==0.32.0 langchain-groq==0.1.5


配置环境变量

某些工具,如langchain-groq,需要API密钥进行身份验证。以下是设置GROQ_API_KEY环境变量的示例代码片段。


代码片段:


import os
# Replace 'your_groq_api_key' with your actual Groq API Key
os.environ["GROQ_API_KEY"] = "your_groq_api_key"


解释:

os.environ:用于直接在Python脚本中设置环境变量。

GROQ_API_KEY:一个关键密钥,用于验证你访问Groq API以使用Llama 3模型的权限。


如何设置你的Groq API密钥

要设置你的Groq API密钥,请按照以下步骤操作:


创建或登录到你的Groq帐户:

  • 访问Groq控制台。
  • 如果你已有帐户,请登录。否则,请注册并完成验证过程。


生成新的API密钥:

  • 登录后,导航到“API密钥”部分。
  • 点击“创建API密钥”。
  • 为你的密钥提供一个可识别的名称,以便稍后识别。
  • 提交以生成密钥。


安全存储你的API密钥:

  • 生成后,你的API密钥将显示出来。请立即复制,因为它可能不会再显示。
  • 安全地存储密钥,以防止未经授权的访问。


导入必要的库:


import json
import os
import sqlite3
from dataclasses import asdict, dataclass
from datetime import datetime, timezone
from pathlib import Path
from textwrap import dedent
from typing import Any, Dict, List, Tuple, Union
import pandas as pd
from crewai import Agent, Crew, Process, Task
from crewai_tools import tool
from google.colab import userdata
from langchain.schema import AgentFinish
from langchain.schema.output import LLMResult
from langchain_community.tools.sql_database.tool import (
    InfoSQLDatabaseTool,
    ListSQLDatabaseTool,
    QuerySQLCheckerTool,
    QuerySQLDataBaseTool,
)
from langchain_community.utilities.sql_database import SQLDatabase
from langchain_core.callbacks.base import BaseCallbackHandler
from langchain_core.prompts import ChatPromptTemplate
from langchain_groq import ChatGroq


数据库设置


加载数据集

首先,将ds-salaries.csv数据集加载到一个Pandas DataFrame中。


import pandas as pd
# Load the dataset into a Pandas DataFrame
file_path = "ds-salaries.csv"  # Replace with the path to your dataset
df = pd.read_csv(file_path)
# Display the first few rows to verify the data
print(df.head())


10


创建SQLite数据库

接下来,创建一个SQLite数据库(名为salaries.db),并在其中填充一个名为salaries的表。


import sqlite3
# Establish a connection to the SQLite database
connection = sqlite3.connect("salaries.db")
# Write the DataFrame to the database
df.to_sql(name="salaries", con=connection, if_exists="replace")


验证数据库设置

重新打开数据库连接,并显示样本行以确认数据已成功添加。


# Query the database to fetch sample rows
query = "SELECT * FROM salaries LIMIT 5;"
sample_data = pd.read_sql_query(query, connection)
# Display the sample data
print(sample_data)


定义一个机制来记录你的程序与大型语言模型(LLM)之间的交互(可选)


@dataclass
class Event:
    event: str
    timestamp: str
    text: str

def _current_time() -> str:
    return datetime.now(timezone.utc).isoformat()

class LLMCallbackHandler(BaseCallbackHandler):
    def __init__(self, log_path: Path):
        self.log_path = log_path
    def on_llm_start(
        self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
    ) -> Any:
        """Run when LLM starts running."""
        assert len(prompts) == 1
        event = Event(event="llm_start", timestamp=_current_time(), text=prompts[0])
        with self.log_path.open("a", encoding="utf-8") as file:
            file.write(json.dumps(asdict(event)) + "\n")
    def on_llm_end(self, response: LLMResult, **kwargs: Any) -> Any:
        """Run when LLM ends running."""
        generation = response.generations[-1][-1].message.content
        event = Event(event="llm_end", timestamp=_current_time(), text=generation)
        with self.log_path.open("a", encoding="utf-8") as file:
            file.write(json.dumps(asdict(event)) + "\n")


目的:此处理程序提供了一种清晰且可审核的方式来监控与大型语言模型(LLM)的交互,记录每个请求的输入和输出。


好处:

  • 提高工作流程的透明度。
  • 通过保留详细的交互日志来简化调试过程。
  • 通过存储时间戳和内容来确保结果的可重复性。


示例用法:

在初始化LLM时,你传递此回调以跟踪所有交互。


使用LangChain设置LLM

此步骤展示了如何使用LangChain和前面定义的回调处理程序将LLM(Llama 3)集成到工作流中。


配置LLM

ChatGroq模型被配置为处理提示并返回响应,同时使用LLMCallbackHandler来记录交互。


llm = ChatGroq(
    temperature=0,
    model_name="llama3-70b-8192",
    callbacks=[LLMCallbackHandler(Path("prompts.jsonl"))],
)


温度(Temperature):决定LLM(大型语言模型)响应的随机性。

  • 值为0时,确保响应是确定性的,适用于像SQL生成或摘要这样的精确任务。


模型名称(Model Name):指定正在使用的Llama 3模型的版本和配置。


回调(Callbacks):将LLMCallbackHandler附加到日志中,以将所有输入和输出记录到一个名为prompts.jsonl的文件中。


你可以使用示例查询来测试LLM集成。


human = "{text}"
prompt = ChatPromptTemplate.from_messages([("human", human)])
chain = prompt | llm
response = chain.invoke(
    {
        "text": "What is captial of France"
    }
)
print(response.content)


定义工具:

初始化数据库


db = SQLDatabase.from_uri("sqlite:///salaries.db")


它的功能:

  • 创建到名为salaries.db的SQLite数据库的连接。
  • from_uri:允许你使用URI指定数据库的位置(sqlite:///表示一个SQLite数据库文件)。


定义工具用于列出数据库中的表


@tool("list_tables")
def list_tables() -> str:
    """List the available tables in the database"""
    return ListSQLDatabaseTool(db=db).invoke("")


它的功能:

  • 定义一个名为“list_tables”的LangChain工具,用于列出数据库中的所有表。


实用性:

  • 通过识别可用的表,帮助代理理解数据库的结构。
  • 对于模式检索、查询或数据探索等任务至关重要。


组件:

  • @tool装饰器:将函数标记为可在工作流或代理中使用的工具。
  • ListSQLDatabaseTool:一个预构建的LangChain实用程序,用于查询并返回连接数据库中的所有表名。
  • .invoke(""):执行该工具,无需额外输入,因为列出表不需要参数。


运行工具


list_tables.run()


它的功能:

  • 执行list_tables工具,以检索并打印salaries.db数据库中所有表的名称。


定义工具以检索模式详细信息


@tool("tables_schema")
def tables_schema(tables: str) -> str:
    """
    Input is a comma-separated list of tables, output is the schema and sample rows
    for those tables. Be sure that the tables actually exist by calling `list_tables` first!
    Example Input: table1, table2, table3
    """
    tool = InfoSQLDatabaseTool(db=db)
    return tool.invoke(tables)


目的:

  • 此工具提供数据库中指定表的元数据(模式)和样本数据。


实用性:

  • 为理解表结构提供必要的元数据。
  • 帮助代理高效地构建查询和分析数据。


组件:

  • 输入:一个逗号分隔的表名字符串(例如,“salaries”)。
  • 输出:指定表的模式详细信息和样本行。


InfoSQLDatabaseTool:

  • LangChain实用程序,用于检索模式信息和数据的预览。
  • 需要数据库连接(db)。


tool.invoke(tables):

  • 使用给定的表名执行工具。
  • 以字符串形式返回模式和样本行。


定义execute_sql工具


@tool("execute_sql")
def execute_sql(sql_query: str) -> str:
    """Execute a SQL query against the database. Returns the result."""
    return QuerySQLDataBaseTool(db=db).invoke(sql_query)


目的:直接在数据库上执行SQL查询并检索结果。


组件:

  • 输入:sql_query - 要执行的SQL命令。
  • 输出:查询结果,通常是数据行。
  • QuerySQLDataBaseTool:一个LangChain实用程序,用于在连接的数据库上执行SQL命令。


用法:在验证查询后运行,以检索特定数据或执行更新。


定义check_sql工具


@tool("check_sql")
def check_sql(sql_query: str) -> str:
    """
    Use this tool to double check if your query is correct before executing it.
    Always use this tool before executing a query with `execute_sql`.
    """
    return QuerySQLCheckerTool(db=db, llm=llm).invoke({"query": sql_query})


目的:在执行前验证SQL查询以确保其正确性。


组件:

  • 输入:sql_query - 要验证的SQL命令。
  • 输出:关于查询正确性的反馈(例如,语法问题、无效的表名)。
  • QuerySQLCheckerTool:使用大型语言模型(LLM,llm)来分析并验证查询中可能存在的问题。


用法:通过在运行查询前确认其准确性来预防错误。


定义代理:


sql_dev(高级数据库开发人员)

角色:高效构建并执行SQL查询。

目标:根据请求生成准确且优化的SQL查询。


能力:

  • 使用list_tables、tables_schema、check_sql和execute_sql等工具与数据库进行交互。


LLM集成:辅助查询生成和优化。


sql_dev = Agent(
    role="Senior Database Developer",
    goal="Construct and execute SQL queries based on a request",
    backstory=dedent(
        """
        You are an experienced database engineer who is master at creating efficient and complex SQL queries.
        You have a deep understanding of how different databases work and how to optimize queries.
        Use the `list_tables` to find available tables.
        Use the `tables_schema` to understand the metadata for the tables.
        Use the `execute_sql` to check your queries for correctness.
        Use the `check_sql` to execute queries against the database.
    """
    ),
    llm=llm,
    tools=[list_tables, tables_schema, execute_sql, check_sql],
    allow_delegation=False,
)


data_analyst(高级数据分析师)

角色:分析数据库开发人员提供的数据。

目标:基于数据创建清晰且详细的分析报告。


能力:

  • 利用Python和大型语言模型(LLM)来生成见解。
  • 确保分析既精确又易于理解。


data_analyst = Agent(
    role="Senior Data Analyst",
    goal="You receive data from the database developer and analyze it",
    backstory=dedent(
        """
        You have deep experience with analyzing datasets using Python.
        Your work is always based on the provided data and is clear,
        easy-to-understand and to the point. You have attention
        to detail and always produce very detailed work (as long as you need).
    """
    ),
    llm=llm,
    allow_delegation=False,
)


report_writer(高级报告编辑)

角色:将分析内容概括为简洁的执行报告。

目标:在100字以内有效地传达关键见解。


能力:

  • 利用大型语言模型(LLM)生成清晰且有影响力的摘要。
  • 擅长制作要点式的、执行层风格的报告。


report_writer = Agent(
    role="Senior Report Editor",
    goal="Write an executive summary type of report based on the work of the analyst",
    backstory=dedent(
        """
        Your writing still is well known for clear and effective communication.
        You always summarize long texts into bullet points that contain the most
        important details.
        """
    ),
    llm=llm,
    allow_delegation=False,
)


任务定义


extract_data 任务


extract_data = Task(
    description="Extract data that is required for the query {query}.",
    expected_output="Database result for the query",
    agent=sql_dev,
)


目的:根据输入的查询从数据库中提取数据。

代理:将任务委托给sql_dev(SQL开发人员)。

输入:用于提取相关数据的查询。

输出:在数据库上执行的SQL查询的结果。


analyze_data 任务


analyze_data = Task(
    description="Analyze the data from the database and write an analysis for {query}.",
    expected_output="Detailed analysis text",
    agent=data_analyst,
    context=[extract_data],
)


目的:分析上一步中提取的数据。

代理:将任务委托给data_analyst(数据分析师)。

上下文:依赖于extract_data的输出,确保处理的是相关数据。

输出:对提取数据的详细文本分析。


write_report 任务


write_report = Task(
    description=dedent(
        """
        Write an executive summary of the report from the analysis. The report
        must be less than 100 words.
    """
    ),
    expected_output="Markdown report",
    agent=report_writer,
    context=[analyze_data],
)


目的:将分析内容概括为简洁、执行层风格的报告。

代理:将任务委托给report_writer(报告编写者)。

上下文:依赖于analyze_data的输出,确保摘要反映分析结果。

输出:一份100字以内的markdown格式报告。


工作流程

  1. extract_data:使用SQL查询从数据库中获取相关数据。
  2. analyze_data:处理并解释提取的数据。
  3. write_report:将分析内容浓缩为简洁、易于理解的报告。


定义crew

团队将定义的代理和任务整合成一个连贯的工作流程,实现端到端过程的自动化。以下是详细分解:


crew = Crew(
    agents=[sql_dev, data_analyst, report_writer],
    tasks=[extract_data, analyze_data, write_report],
    process=Process.sequential,
    verbose=2,
    memory=False,
    output_log_file="crew.log",
)


组件

agents:

输入:代理列表(sql_dev、data_analyst 和 report_writer)。

目的:定义将处理特定任务的角色。

代理角色:

  • sql_dev:处理数据库查询。
  • data_analyst:分析提取的数据。
  • report_writer:总结分析内容。


tasks:

输入:任务列表(extract_data、analyze_data 和 write_report)。

目的:指定工作流程,其中每个任务都依赖于前一个任务的输出。


process:

值:Process.sequential。

目的:确保任务按顺序执行,每个任务都会等待前一个任务完成。


verbose:

值:2。

目的:控制日志记录级别:

更高的详细程度会提供详细的任务执行日志,便于监控。


memory:

值:False。

目的:禁用任务间的内存保留,以确保无状态执行。


output_log_file:

值:"crew.log"。

目的:指定一个文件来存储整个过程的详细日志,便于调试和审计。


运行:


inputs = {
    "query": "Effects on salary (in USD) based on company location, size and employee experience"
}
result = crew.kickoff(inputs=inputs)


[2024-11-30 13:39:52][DEBUG]: == Working Agent: Senior Database Developer
 [2024-11-30 13:39:52][INFO]: == Starting Task: Extract data that is required for the query Effects on salary (in USD) based on company location, size and employee experience.
salaries
 

CREATE TABLE salaries (
 "index" INTEGER, 
 work_year INTEGER, 
 experience_level TEXT, 
 employment_type TEXT, 
 job_title TEXT, 
 salary INTEGER, 
 salary_currency TEXT, 
 salary_in_usd INTEGER, 
 employee_residence TEXT, 
 remote_ratio INTEGER, 
 company_location TEXT, 
 company_size TEXT
)
/*
3 rows from salaries table:
index work_year experience_level employment_type job_title salary salary_currency salary_in_usd employee_residence remote_ratio company_location company_size
0 2023 SE FT Principal Data Scientist 80000 EUR 85847 ES 100 ES L
1 2023 MI CT ML Engineer 30000 USD 30000 US 100 US S
2 2023 MI CT ML Engineer 25500 USD 25500 US 100 US S
*/
 
The provided SQL query appears to be correct and does not contain any of the common mistakes listed. Here is the final SQL query:
```
SELECT company_location, company_size, experience_level, AVG(salary_in_usd) AS avg_salary 
FROM salaries 
GROUP BY company_location, company_size, experience_level
```
 
[('AE', 'L', 'MI', 115000.0), ('AE', 'S', 'SE', 92500.0), ('AL', 'S', 'SE', 10000.0), ('AM', 'S', 'MI', 50000.0), ('AR', 'L', 'EN', 31000.0), ('AR', 'S', 'EN', 13000.0), ('AS', 'L', 'EN', 50000.0), ('AS', 'M', 'EN', 20000.0), ('AS', 'S', 'EN', 18053.0), ('AT', 'L', 'MI', 75141.66666666667), ('AT', 'M', 'EN', 50000.0), ('AT', 'M', 'MI', 61467.0), ('AT', 'S', 'SE', 91237.0), ('AU', 'L', 'EN', 56014.0), ('AU', 'L', 'MI', 71783.75), ('AU', 'L', 'SE', 152383.0), ('AU', 'M', 'EN', 54390.333333333336), ('AU', 'M', 'MI', 53368.0), ('AU', 'M', 'SE', 50000.0), ('AU', 'S', 'EN', 150000.0), ('BA', 'S', 'EN', 120000.0), ('BE', 'L', 'EN', 84053.0), ('BE', 'M', 'MI', 88654.0), ('BE', 'M', 'SE', 82744.0), ('BE', 'S', 'EN', 52008.0), ('BO', 'M', 'MI', 7500.0), ('BR', 'L', 'EN', 11197.0), ('BR', 'M', 'MI', 57698.77777777778), ('BR', 'M', 'SE', 21453.5), ('BR', 'S', 'MI', 12901.0), ('BS', 'M', 'MI', 45555.0), ('CA', 'L', 'EN', 83447.8), ('CA', 'L', 'EX', 159006.5), ('CA', 'L', 'MI', 98364.6), ('CA', 'L', 'SE', 120463.83333333333), ('CA', 'M', 'EN', 59500.0), ('CA', 'M', 'EX', 15000.0), ('CA', 'M', 'MI', 84802.33333333333), ('CA', 'M', 'SE', 152392.45283018867), ('CA', 'S', 'EX', 115222.0), ('CA', 'S', 'MI', 75000.0), ('CA', 'S', 'SE', 181369.0), ('CF', 'M', 'SE', 48609.0), ('CH', 'L', 'EN', 63487.5), ('CH', 'L', 'MI', 112549.5), ('CH', 'S', 'EN', 56536.0), ('CL', 'L', 'MI', 40038.0), ('CN', 'L', 'EN', 100000.0), ('CO', 'L', 'SE', 125000.0), ('CO', 'M', 'EN', 21844.0), ('CO', 'M', 'SE', 56500.0), ('CR', 'S', 'EN', 50000.0), ('CZ', 'L', 'MI', 69999.0), ('CZ', 'M', 'EN', 30469.0), ('CZ', 'M', 'MI', 5132.0), ('DE', 'L', 'EN', 80568.71428571429), ('DE', 'L', 'EX', 141846.0), ('DE', 'L', 'MI', 80497.6), ('DE', 'L', 'SE', 90249.25), ('DE', 'M', 'EN', 50436.5), ('DE', 'M', 'EX', 130026.0), ('DE', 'M', 'MI', 68544.0), ('DE', 'M', 'SE', 170163.55555555556), ('DE', 'S', 'EN', 51066.42857142857), ('DE', 'S', 'MI', 68600.33333333333), ('DE', 'S', 'SE', 96578.0), ('DK', 'L', 'EN', 19073.0), ('DK', 'L', 'SE', 88654.0), ('DK', 'S', 'EN', 37252.5), ('DZ', 'M', 'EN', 100000.0), ('EE', 'L', 'SE', 63312.0), ('EE', 'S', 'MI', 31520.0), ('EG', 'M', 'MI', 22800.0), ('ES', 'L', 'EN', 27317.0), ('ES', 'L', 'EX', 79833.0), ('ES', 'L', 'MI', 38228.0), ('ES', 'L', 'SE', 70423.5), ('ES', 'M', 'EN', 23713.75), ('ES', 'M', 'MI', 61223.41176470588), ('ES', 'M', 'SE', 59665.166666666664), ('ES', 'S', 'EX', 69741.0), ('ES', 'S', 'MI', 47282.0), ('FI', 'M', 'MI', 75020.0), ('FI', 'M', 'SE', 68318.0), ('FI', 'S', 'SE', 63040.0), ('FR', 'L', 'EN', 38284.0), ('FR', 'L', 'MI', 52299.333333333336), ('FR', 'L', 'SE', 87267.4), ('FR', 'M', 'EN', 51172.0), ('FR', 'M', 'MI', 69988.375), ('FR', 'M', 'SE', 89845.6), ('FR', 'S', 'EN', 51321.0), ('FR', 'S', 'MI', 52590.666666666664), ('FR', 'S', 'SE', 53654.0), ('GB', 'L', 'EN', 56049.0), ('GB', 'L', 'MI', 89857.77777777778), ('GB', 'L', 'SE', 95091.0), ('GB', 'M', 'EN', 63861.333333333336), ('GB', 'M', 'EX', 143877.5), ('GB', 'M', 'MI', 83154.95238095238), ('GB', 'M', 'SE', 102207.45161290323), ('GB', 'S', 'EN', 55410.0), ('GB', 'S', 'MI', 68182.0), ('GB', 'S', 'SE', 123510.0), ('GH', 'S', 'EN', 7000.0), ('GH', 'S', 'MI', 30000.0), ('GR', 'L', 'EN', 12877.0), ('GR', 'L', 'SE', 47899.0), ('GR', 'M', 'MI', 58574.454545454544), ('GR', 'S', 'MI', 20000.0), ('HK', 'L', 'MI', 65062.0), ('HN', 'S', 'MI', 20000.0), ('HR', 'M', 'MI', 91142.5), ('HR', 'S', 'SE', 45618.0), ('HU', 'L', 'MI', 35735.0), ('HU', 'M', 'EN', 17684.0), ('ID', 'L', 'EN', 15000.0), ('ID', 'L', 'MI', 53416.0), ('IE', 'L', 'SE', 172309.0), ('IE', 'M', 'MI', 88529.5), ('IE', 'M', 'SE', 128981.0), ('IE', 'S', 'SE', 68293.0), ('IL', 'L', 'SE', 423834.0), ('IL', 'M', 'MI', 119059.0), ('IN', 'L', 'EN', 39371.333333333336), ('IN', 'L', 'EX', 76309.0), ('IN', 'L', 'MI', 23267.235294117647), ('IN', 'L', 'SE', 58774.875), ('IN', 'M', 'EN', 18332.625), ('IN', 'M', 'MI', 18229.75), ('IN', 'S', 'EN', 12986.666666666666), ('IN', 'S', 'MI', 15654.0), ('IN', 'S', 'SE', 15806.0), ('IQ', 'S', 'EN', 100000.0), ('IR', 'M', 'EN', 100000.0), ('IT', 'L', 'MI', 51064.0), ('IT', 'L', 'SE', 68293.0), ('IT', 'M', 'EN', 24165.0), ('IT', 'S', 'EN', 21669.0), ('JP', 'S', 'EN', 41689.0), ('JP', 'S', 'MI', 71691.66666666667), ('JP', 'S', 'SE', 214000.0), ('KE', 'S', 'EN', 9272.0), ('KE', 'S', 'MI', 80000.0), ('LT', 'M', 'MI', 94812.0), ('LU', 'L', 'EN', 59102.0), ('LU', 'M', 'EN', 10000.0), ('LU', 'S', 'MI', 62726.0), ('LV', 'M', 'SE', 57946.5), ('MA', 'S', 'EN', 10000.0), ('MD', 'S', 'MI', 18000.0), ('MK', 'S', 'EN', 6304.0), ('MT', 'L', 'MI', 28369.0), ('MX', 'L', 'MI', 30000.0), ('MX', 'L', 'SE', 60000.0), ('MX', 'M', 'MI', 66000.0), ('MX', 'M', 'SE', 170000.0), ('MX', 'S', 'MI', 36000.0), ('MX', 'S', 'SE', 33511.0), ('MY', 'L', 'EN', 40000.0), ('NG', 'L', 'EN', 65000.0), ('NG', 'L', 'MI', 50000.0), ('NG', 'S', 'EN', 10000.0), ('NG', 'S', 'SE', 200000.0), ('NL', 'L', 'EN', 50944.0), ('NL', 'L', 'EX', 84053.0), ('NL', 'L', 'MI', 71314.0), ('NL', 'L', 'SE', 97629.33333333333), ('NL', 'M', 'MI', 102439.5), ('NL', 'S', 'MI', 54634.0), ('NZ', 'S', 'SE', 125000.0), ('PH', 'S', 'SE', 50000.0), ('PK', 'L', 'MI', 8000.0), ('PK', 'M', 'EN', 30000.0), ('PK', 'M', 'MI', 12000.0), ('PL', 'L', 'EX', 153667.0), ('PL', 'L', 'MI', 36227.333333333336), ('PL', 'S', 'MI', 44365.0), ('PR', 'M', 'SE', 167500.0), ('PT', 'L', 'EN', 21013.0), ('PT', 'L', 'MI', 55685.0), ('PT', 'L', 'SE', 68405.66666666667), ('PT', 'M', 'EN', 22809.0), ('PT', 'M', 'MI', 50180.0), ('PT', 'M', 'SE', 53782.333333333336), ('PT', 'S', 'SE', 29944.0), ('RO', 'L', 'MI', 53654.0), ('RO', 'M', 'MI', 60000.0), ('RU', 'L', 'EX', 168000.0), ('RU', 'M', 'EX', 85000.0), ('SE', 'M', 'EN', 80000.0), ('SE', 'S', 'EN', 130000.0), ('SG', 'L', 'EN', 66970.0), ('SG', 'L', 'MI', 82157.0), ('SG', 'L', 'SE', 8000.0), ('SG', 'M', 'MI', 41383.0), ('SI', 'L', 'MI', 24823.0), ('SI', 'L', 'SE', 102839.0), ('SI', 'M', 'MI', 61702.5), ('SK', 'S', 'SE', 12608.0), ('TH', 'L', 'EN', 15000.0), ('TH', 'L', 'MI', 24740.0), ('TH', 'M', 'SE', 29453.0), ('TR', 'L', 'SE', 20171.0), ('TR', 'M', 'MI', 18779.75), ('UA', 'L', 'EN', 13400.0), ('UA', 'M', 'SE', 84000.0), ('UA', 'S', 'SE', 50000.0), ('US', 'L', 'EN', 105386.73170731707), ('US', 'L', 'EX', 240000.0), ('US', 'L', 'MI', 126846.06666666667), ('US', 'L', 'SE', 175539.59493670886), ('US', 'M', 'EN', 104835.26016260163), ('US', 'M', 'EX', 204151.7888888889), ('US', 'M', 'MI', 129675.77541371158), ('US', 'M', 'SE', 157701.42453282225), ('US', 'S', 'EN', 80196.0), ('US', 'S', 'EX', 249000.0), ('US', 'S', 'MI', 76013.21428571429), ('US', 'S', 'SE', 122588.23529411765), ('VN', 'L', 'EN', 12000.0)]
 [2024-11-30 13:40:31][DEBUG]: == [Senior Database Developer] Task output: [('AE', 'L', 'MI', 115000.0), ('AE', 'S', 'SE', 92500.0), ('AL', 'S', 'SE', 10000.0), ('AM', 'S', 'MI', 50000.0), ('AR', 'L', 'EN', 31000.0), ('AR', 'S', 'EN', 13000.0), ('AS', 'L', 'EN', 50000.0), ('AS', 'M', 'EN', 20000.0), ('AS', 'S', 'EN', 18053.0), ('AT', 'L', 'MI', 75141.66666666667), ('AT', 'M', 'EN', 50000.0), ('AT', 'M', 'MI', 61467.0), ('AT', 'S', 'SE', 91237.0), ('AU', 'L', 'EN', 56014.0), ('AU', 'L', 'MI', 71783.75), ('AU', 'L', 'SE', 152383.0), ('AU', 'M', 'EN', 54390.333333333336), ('AU', 'M', 'MI', 53368.0), ('AU', 'M', 'SE', 50000.0), ('AU', 'S', 'EN', 150000.0), ('BA', 'S', 'EN', 120000.0), ('BE', 'L', 'EN', 84053.0), ('BE', 'M', 'MI', 88654.0), ('BE', 'M', 'SE', 82744.0), ('BE', 'S', 'EN', 52008.0), ('BO', 'M', 'MI', 7500.0), ('BR', 'L', 'EN', 11197.0), ('BR', 'M', 'MI', 57698.77777777778), ('BR', 'M', 'SE', 21453.5), ('BR', 'S', 'MI', 12901.0), ('BS', 'M', 'MI', 45555.0), ('CA', 'L', 'EN', 83447.8), ('CA', 'L', 'EX', 159006.5), ('CA', 'L', 'MI', 98364.6), ('CA', 'L', 'SE', 120463.83333333333), ('CA', 'M', 'EN', 59500.0), ('CA', 'M', 'EX', 15000.0), ('CA', 'M', 'MI', 84802.33333333333), ('CA', 'M', 'SE', 152392.45283018867), ('CA', 'S', 'EX', 115222.0), ('CA', 'S', 'MI', 75000.0), ('CA', 'S', 'SE', 181369.0), ('CF', 'M', 'SE', 48609.0), ('CH', 'L', 'EN', 63487.5), ('CH', 'L', 'MI', 112549.5), ('CH', 'S', 'EN', 56536.0), ('CL', 'L', 'MI', 40038.0), ('CN', 'L', 'EN', 100000.0), ('CO', 'L', 'SE', 125000.0), ('CO', 'M', 'EN', 21844.0), ('CO', 'M', 'SE', 56500.0), ('CR', 'S', 'EN', 50000.0), ('CZ', 'L', 'MI', 69999.0), ('CZ', 'M', 'EN', 30469.0), ('CZ', 'M', 'MI', 5132.0), ('DE', 'L', 'EN', 80568.71428571429), ('DE', 'L', 'EX', 141846.0), ('DE', 'L', 'MI', 80497.6), ('DE', 'L', 'SE', 90249.25), ('DE', 'M', 'EN', 50436.5), ('DE', 'M', 'EX', 130026.0), ('DE', 'M', 'MI', 68544.0), ('DE', 'M', 'SE', 170163.55555555556), ('DE', 'S', 'EN', 51066.42857142857), ('DE', 'S', 'MI', 68600.33333333333), ('DE', 'S', 'SE', 96578.0), ('DK', 'L', 'EN', 19073.0), ('DK', 'L', 'SE', 88654.0), ('DK', 'S', 'EN', 37252.5), ('DZ', 'M', 'EN', 100000.0), ('EE', 'L', 'SE', 63312.0), ('EE', 'S', 'MI', 31520.0), ('EG', 'M', 'MI', 22800.0), ('ES', 'L', 'EN', 27317.0), ('ES', 'L', 'EX', 79833.0), ('ES', 'L', 'MI', 38228.0), ('ES', 'L', 'SE', 70423.5), ('ES', 'M', 'EN', 23713.75), ('ES', 'M', 'MI', 61223.41176470588), ('ES', 'M', 'SE', 59665.166666666664), ('ES', 'S', 'EX', 69741.0), ('ES', 'S', 'MI', 47282.0), ('FI', 'M', 'MI', 75020.0), ('FI', 'M', 'SE', 68318.0), ('FI', 'S', 'SE', 63040.0), ('FR', 'L', 'EN', 38284.0), ('FR', 'L', 'MI', 52299.333333333336), ('FR', 'L', 'SE', 87267.4), ('FR', 'M', 'EN', 51172.0), ('FR', 'M', 'MI', 69988.375), ('FR', 'M', 'SE', 89845.6), ('FR', 'S', 'EN', 51321.0), ('FR', 'S', 'MI', 52590.666666666664), ('FR', 'S', 'SE', 53654.0), ('GB', 'L', 'EN', 56049.0), ('GB', 'L', 'MI', 89857.77777777778), ('GB', 'L', 'SE', 95091.0), ('GB', 'M', 'EN', 63861.333333333336), ('GB', 'M', 'EX', 143877.5), ('GB', 'M', 'MI', 83154.95238095238), ('GB', 'M', 'SE', 102207.45161290323), ('GB', 'S', 'EN', 55410.0), ('GB', 'S', 'MI', 68182.0), ('GB', 'S', 'SE', 123510.0), ('GH', 'S', 'EN', 7000.0), ('GH', 'S', 'MI', 30000.0), ('GR', 'L', 'EN', 12877.0), ('GR', 'L', 'SE', 47899.0), ('GR', 'M', 'MI', 58574.454545454544), ('GR', 'S', 'MI', 20000.0), ('HK', 'L', 'MI', 65062.0), ('HN', 'S', 'MI', 20000.0), ('HR', 'M', 'MI', 91142.5), ('HR', 'S', 'SE', 45618.0), ('HU', 'L', 'MI', 35735.0), ('HU', 'M', 'EN', 17684.0), ('ID', 'L', 'EN', 15000.0), ('ID', 'L', 'MI', 53416.0), ('IE', 'L', 'SE', 172309.0), ('IE', 'M', 'MI', 88529.5), ('IE', 'M', 'SE', 128981.0), ('IE', 'S', 'SE', 68293.0), ('IL', 'L', 'SE', 423834.0), ('IL', 'M', 'MI', 119059.0), ('IN', 'L', 'EN', 39371.333333333336), ('IN', 'L', 'EX', 76309.0), ('IN', 'L', 'MI', 23267.235294117647), ('IN', 'L', 'SE', 58774.875), ('IN', 'M', 'EN', 18332.625), ('IN', 'M', 'MI', 18229.75), ('IN', 'S', 'EN', 12986.666666666666), ('IN', 'S', 'MI', 15654.0), ('IN', 'S', 'SE', 15806.0), ('IQ', 'S', 'EN', 100000.0), ('IR', 'M', 'EN', 100000.0), ('IT', 'L', 'MI', 51064.0), ('IT', 'L', 'SE', 68293.0), ('IT', 'M', 'EN', 24165.0), ('IT', 'S', 'EN', 21669.0), ('JP', 'S', 'EN', 41689.0), ('JP', 'S', 'MI', 71691.66666666667), ('JP', 'S', 'SE', 214000.0), ('KE', 'S', 'EN', 9272.0), ('KE', 'S', 'MI', 80000.0), ('LT', 'M', 'MI', 94812.0), ('LU', 'L', 'EN', 59102.0), ('LU', 'M', 'EN', 10000.0), ('LU', 'S', 'MI', 62726.0), ('LV', 'M', 'SE', 57946.5), ('MA', 'S', 'EN', 10000.0), ('MD', 'S', 'MI', 18000.0), ('MK', 'S', 'EN', 6304.0), ('MT', 'L', 'MI', 28369.0), ('MX', 'L', 'MI', 30000.0), ('MX', 'L', 'SE', 60000.0), ('MX', 'M', 'MI', 66000.0), ('MX', 'M', 'SE', 170000.0), ('MX', 'S', 'MI', 36000.0), ('MX', 'S', 'SE', 33511.0), ('MY', 'L', 'EN', 40000.0), ('NG', 'L', 'EN', 65000.0), ('NG', 'L', 'MI', 50000.0), ('NG', 'S', 'EN', 10000.0), ('NG', 'S', 'SE', 200000.0), ('NL', 'L', 'EN', 50944.0), ('NL', 'L', 'EX', 84053.0), ('NL', 'L', 'MI', 71314.0), ('NL', 'L', 'SE', 97629.33333333333), ('NL', 'M', 'MI', 102439.5), ('NL', 'S', 'MI', 54634.0), ('NZ', 'S', 'SE', 125000.0), ('PH', 'S', 'SE', 50000.0), ('PK', 'L', 'MI', 8000.0), ('PK', 'M', 'EN', 30000.0), ('PK', 'M', 'MI', 12000.0), ('PL', 'L', 'EX', 153667.0), ('PL', 'L', 'MI', 36227.333333333336), ('PL', 'S', 'MI', 44365.0), ('PR', 'M', 'SE', 167500.0), ('PT', 'L', 'EN', 21013.0), ('PT', 'L', 'MI', 55685.0), ('PT', 'L', 'SE', 68405.66666666667), ('PT', 'M', 'EN', 22809.0), ('PT', 'M', 'MI', 50180.0), ('PT', 'M', 'SE', 53782.333333333336), ('PT', 'S', 'SE', 29944.0), ('RO', 'L', 'MI', 53654.0), ('RO', 'M', 'MI', 60000.0), ('RU', 'L', 'EX', 168000.0), ('RU', 'M', 'EX', 85000.0), ('SE', 'M', 'EN', 80000.0), ('SE', 'S', 'EN', 130000.0), ('SG', 'L', 'EN', 66970.0), ('SG', 'L', 'MI', 82157.0), ('SG', 'L', 'SE', 8000.0), ('SG', 'M', 'MI', 41383.0), ('SI', 'L', 'MI', 24823.0), ('SI', 'L', 'SE', 102839.0), ('SI', 'M', 'MI', 61702.5), ('SK', 'S', 'SE', 12608.0), ('TH', 'L', 'EN', 15000.0), ('TH', 'L', 'MI', 24740.0), ('TH', 'M', 'SE', 29453.0), ('TR', 'L', 'SE', 20171.0), ('TR', 'M', 'MI', 18779.75), ('UA', 'L', 'EN', 13400.0), ('UA', 'M', 'SE', 84000.0), ('UA', 'S', 'SE', 50000.0), ('US', 'L', 'EN', 105386.73170731707), ('US', 'L', 'EX', 240000.0), ('US', 'L', 'MI', 126846.06666666667), ('US', 'L', 'SE', 175539.59493670886), ('US', 'M', 'EN', 104835.26016260163), ('US', 'M', 'EX', 204151.7888888889), ('US', 'M', 'MI', 129675.77541371158), ('US', 'M', 'SE', 157701.42453282225), ('US', 'S', 'EN', 80196.0), ('US', 'S', 'EX', 249000.0), ('US', 'S', 'MI', 76013.21428571429), ('US', 'S', 'SE', 122588.23529411765), ('VN', 'L', 'EN', 12000.0)]

 [2024-11-30 13:40:31][DEBUG]: == Working Agent: Senior Data Analyst
 [2024-11-30 13:40:31][INFO]: == Starting Task: Analyze the data from the database and write an analysis for Effects on salary (in USD) based on company location, size and employee experience.
 [2024-11-30 13:40:33][DEBUG]: == [Senior Data Analyst] Task output: Based on the analysis, we can conclude that:
1. Location has a significant impact on salary, with certain locations offering higher average salaries than others.
2. Company size also has a significant impact on salary, with larger companies tend to offer higher average salaries.
3. Employee experience is also an important factor, with more experienced employees tend to earn higher average salaries.
4. The interaction between location, company size, and experience is complex, and certain combinations tend to offer higher average salaries than others.
These insights can be used to inform salary decisions and talent acquisition strategies for companies operating in different locations and industries.

 [2024-11-30 13:40:33][DEBUG]: == Working Agent: Senior Report Editor
 [2024-11-30 13:40:33][INFO]: == Starting Task: 
Write an executive summary of the report from the analysis. The report
must be less than 100 words.
 [2024-11-30 13:40:42][DEBUG]: == [Senior Report Editor] Task output: **Executive Summary**
===============
### Key Findings
* Location significantly impacts salary, with certain locations offering higher average salaries than others.
* Company size also has a significant impact on salary, with larger companies tend to offer higher average salaries.
* Employee experience is an important factor, with more experienced employees tend to earn higher average salaries.
* The interaction between location, company size, and experience is complex, and certain combinations tend to offer higher average salaries than others.
### Implications
These insights can inform salary decisions and talent acquisition strategies for companies operating in different locations and industries.
文章来源:https://medium.com/@sahin.samia/how-to-build-an-ai-powered-sql-data-analysis-agent-with-langchain-and-crewai-5c6d992f8851
欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
热门职位
Maluuba
20000~40000/月
Cisco
25000~30000/月 深圳市
PilotAILabs
30000~60000/年 深圳市
写评论取消
回复取消