LLM如何以ReAct Agent方式统计分析去重后数据

之前探索了LLM与程序协作来去重清洗文本格式数据

https://blog.csdn.net/liliang199/article/details/159865538

这里进一步探索LLM如何以ReAct Agent的方式,统计分析融合去重后的数据。

LLM不实际运行统计分析,而是借助一专业统计工具完成,以确保分析过程的准确性。

所用示例参考和修改自网络资料。

1 Agent机制

1.1 LLM统计存在的问题

统计任务sum/count/avg/group by要求绝对精确。

LLM虽然也具备统计能力,直接让LLM处理统计任务,由可能存在多次运行不一致的问题。

而且,随着统计数据规模的扩大,由注意力漂移导致的误差累积会越来越多。

LLM的不稳定性和幻觉会影响到统计结果的准确性。

1.2 Agent ReAct机制

既然LLM不善于处理统计任务,更合理的方案是,准备各种统计工具,由LLM决定调用哪些工具。

具体为

1)LLM理解自然语言,生成工具调用如 SQL

2)由Agent调用后端同工具获得精确结果

3)再由LLM 组织自然语言回答。

Agent ReAct模式允许多轮工具调用,能处理复杂查询。

比如"对比今年和去年的销售额"需要两次调用工具。

2 Agent 运行

这里以代码方式示例LLM如何以ReAct Agent方式统计分析去重后数据。

2.1 环境设置

参考之前文档,LLM环境设置示例代码 如下。

复制代码
import os
 
model_name = gpt_model_name # LLM名称,比如deepseek-r1, qwen3.5-8b
os.environ['OPENAI_API_KEY'] = gpt_api_key # LLM供应商提供的api key
os.environ['OPENAI_BASE_URL'] = gpt_api_url # LLM供应商提供llm访问api的url
 
from openai import OpenAI
 
client = OpenAI()

这里采用上一节"LLM与程序协作来去重清洗文本格式数据"去重处理后的数据进行测试。

name company date description ext_person ext_place ext_amount ext_date original_ids index id block_key new_id

0 张三 ABC科技 2023-05-02 张三昨天在北京签了合同,金额50000元 | 张总与北京分公司达成5万交易 张三 北京 50000 元 2024-05-21 [1, 2] NaN NaN NaN 1

1 李四 XYZ有限公司 2023-06-01 李四在上海支付了1200元 李四 上海 1200 元 None NaN 2.0 3.0 XYZ有 2

数据表名称为records_dedup,参考链接如下

https://blog.csdn.net/liliang199/article/details/159865538

2.2 工具定义

这里定义数据库查询统计工具execute_sql,统计逻辑由sql定义实现。

1)工具代码

复制代码
# ================= 阶段3:查询统计 + ReAct Agent =================
# 定义工具:执行 SQL 查询(只读)
def execute_sql(query: str) -> str:
    """执行 SQL SELECT 语句,返回 JSON 字符串"""
    try:
        print(query)
        conn = sqlite3.connect("example.db")
        df_result = pd.read_sql_query(query, conn)
        conn.close()
        return df_result.to_json(orient="records")
    except Exception as e:
        return f"SQL错误: {e}"

query = "select * from records_dedup"
json_data = execute_sql(query)
for result in json.loads(json_data):
    print(result)

输出示例如下,可见该工具能实际运行sql。

select * from records_dedup

{'name': '张三', 'company': 'ABC科技', 'date': '2023-05-02', 'description': '张三昨天在北京签了合同,金额50000元 | 张总与北京分公司达成5万交易', 'ext_person': '张三', 'ext_place': '北京', 'ext_amount': '50000 元', 'ext_date': '2024-05-21', 'original_ids': '[1, 2]', 'index': None, 'id': None, 'block_key': None, 'new_id': 1}

{'name': '李四', 'company': 'XYZ有限公司', 'date': '2023-06-01', 'description': '李四在上海支付了1200元', 'ext_person': '李四', 'ext_place': '上海', 'ext_amount': '1200 元', 'ext_date': None, 'original_ids': None, 'index': 2.0, 'id': 3.0, 'block_key': 'XYZ有', 'new_id': 2}

2)工具描述

为方便LLM理解工具,这里定义工具描述,示例如下。

复制代码
# 定义工具描述(供 LLM 理解)
tools = [
    {
        "type": "function",
        "function": {
            "name": "execute_sql",
            "description": "在 SQLite 数据库上执行只读 SQL 查询。数据库表 'records_dedup' 包含字段:id, name, company, date, description, ext_person, ext_place, ext_amount, ext_date",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {"type": "string", "description": "有效的 SELECT SQL 语句"}
                },
                "required": ["query"]
            }
        }
    }
]

2.3 Agent运行

这里运行基于 ReAct Agent 的自然语言查询,即统计类任务精确执行 SQL。

由LLM决定是否调用工具,在需要时由Agent运行工具程序,拿到结果后生成最终答案。

代码如下所示。

复制代码
def react_agent(user_question: str, max_steps=3):
    """ReAct 循环:LLM 决定是否调用工具,拿到结果后给出最终答案"""
    messages = [
        {"role": "system", "content": "你是一个数据库查询助手。你需要根据用户问题,调用 execute_sql 工具来获取精确数据。不允许自己编造数字。若需要多步查询,请逐步调用工具。最终用自然语言回答用户。"},
        {"role": "user", "content": user_question}
    ]
    for _ in range(max_steps):
        response = client.chat.completions.create(
            model=model_name,
            messages=messages,
            tools=tools,
            tool_choice="auto",
            temperature=0
        )
        msg = response.choices[0].message
        messages.append(msg)  # 将助手消息加入历史

        # 如果没有工具调用,说明已经得出最终答案
        if not msg.tool_calls:
            return msg.content

        # 执行工具调用
        for tool_call in msg.tool_calls:
            func_name = tool_call.function.name
            args = json.loads(tool_call.function.arguments)
            if func_name == "execute_sql":
                result = execute_sql(args["query"])
                print(result)
                messages.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "content": result
                })
    return "达到最大步骤限制,未完成查询。"

# 测试查询
print("\n=== ReAct Agent 查询示例 ===")
question = "统计每个公司的总金额(ext_amount),按金额从高到低排序"
answer = react_agent(question)
print(f"用户问题:{question}")
print(f"最终答案:{answer}")

# 另一个需要多步的查询(演示)
question2 = "先查出张三的 ext_amount,再查出李四的,比较谁大"
answer2 = react_agent(question2)
print(f"\n用户问题:{question2}")
print(f"最终答案:{answer2}")

# 关闭连接
conn.close()

输入如下所示。

=== ReAct Agent 查询示例 ===

SELECT company, SUM(ext_amount) as total_amount FROM records_dedup GROUP BY company ORDER BY total_amount DESC

{"company":"ABC\\u79d1\\u6280","total_amount":50000.0},{"company":"XYZ\\u6709\\u9650\\u516c\\u53f8","total_amount":1200.0}

用户问题:统计每个公司的总金额(ext_amount),按金额从高到低排序

最终答案:

根据查询结果,每个公司的总金额统计如下(按金额从高到低排序):

| 公司 | 总金额 |

|------|--------|

| ABC 科技 | 50,000.00 |

| XYZ 有限公司 | 1,200.00 |

其中,ABC 科技的总金额最高,为 50,000.00 元;XYZ 有限公司的总金额为 1,200.00 元。

SELECT ext_amount FROM records_dedup WHERE name = '张三'

{"ext_amount":"50000 \\u5143"}

SELECT ext_amount FROM records_dedup WHERE name = '李四'

{"ext_amount":"1200 \\u5143"}

用户问题:先查出张三的 ext_amount,再查出李四的,比较谁大

最终答案:

根据查询结果:

  • **张三**的 ext_amount 为 **50000 元**

  • **李四**的 ext_amount 为 **1200 元**

比较结果:**张三的 ext_amount 更大**,比李四多 48800 元。

相比直接运行程序,Agent可以更有效地调用工具,而且避免了LLM不稳定和存在幻觉的问题。

3 优化注意点

Agent相比直接运行程序更高效,由于Agent依赖LLM决策,依然可能存在不稳定性问题。

这里罗列一些可能存在的问题,以及可能的优化方案。

1)LLM生成SQL可能存在语法或逻辑错误,如join缺失,需增加SQL语法校验等安全限制。

2)多轮调用可能产生冗长的中间输出,所以需要设计清晰的工具描述和终止条件。

3)提供数据库schema的详细描述(表名、字段、类型、示例值)作为 system prompt。

4)对于对常见查询类型可预置模板减少推理开销。

reference


LLM与程序协作来去重清洗文本格式数据

https://blog.csdn.net/liliang199/article/details/159865538

LLM如何与程序协作来结构化文本财报数据

https://blog.csdn.net/liliang199/article/details/159834630

如何使用向量库faiss和LLM判断问题是否被记录

https://blog.csdn.net/liliang199/article/details/159476341

LLM如何基于tools对同一数据不同问题进行查询

https://blog.csdn.net/liliang199/article/details/159767913

相关推荐
这张生成的图像能检测吗2 小时前
(论文速读)FD-LLM:将振动信号编码为文本表示来将振动信号与大型语言模型进行对齐
人工智能·深度学习·语言模型·智能制造·故障诊断
圣殿骑士-Khtangc2 小时前
Amazon CodeWhisperer 超详细使用教程:AWS 云原生 AI 编程助手上手指南
人工智能·ai编程·aws·编程助手·codewhisperer
问道飞鱼2 小时前
【数据库相关】MySQL全分类SQL详解(超多数据类型+全约束+实战落地)
数据库·sql·mysql·范例
花千树-0102 小时前
IndexTTS2 入门指南:从模型概念到 macOS 安装实战
人工智能·ai·chatgpt·aigc
不剪发的Tony老师2 小时前
mayfly-go:一款基于WEB的服务器、数据库、中间件统一运维平台
运维·服务器·数据库
淡忘旧梦2 小时前
ChatGPT回答白屏
人工智能·chatgpt·代理模式
望百川归海2 小时前
FS-SAM2微调和推理加速
人工智能
lifallen2 小时前
Flink Agent:ActionTask 与可续跑状态机 (Coroutine/Continuation)
java·大数据·人工智能·语言模型·flink
数据分析能量站2 小时前
Harnessing Claude 打造高效、低成本、可进化的 AI 应用
人工智能