从零实现一个多工具智能体:RAG + SQL + 计算器(Python + LangGraph)

4 阅读3分钟

这是我学习 AI Agent 开发第一周的实战记录:实现一个能自动判断问题类型、调用不同工具(RAG、SQL、计算器)的智能体。全文代码开源,思路清晰,适合想动手做 Agent 的同学参考。

一、为什么要做这个?

AI Agent 是当下大模型落地的热门方向。但 Agent 不只是“能聊天的模型”,而是能自己动脑子、用工具、完成复杂任务的程序。

这周我给自己定了一个小目标:实现一个最小化的多工具智能体。它能:

  • 判断用户是想查知识、查数据,还是做计算
  • 根据判断结果,自动调用对应的工具
  • 用自然语言给出答案

最终效果是这样的:

用户问题智能体行为回答
什么是 AI Agent?知识类 → RAG 检索AI Agent 是智能体程序
笔记本卖了多少?数据类 → 生成 SQL笔记本共销售 95 台
25 * 4 等于多少?计算类 → 数学计算25 * 4 = 100

二、技术栈

工具用途
Python 3.13开发语言
DeepSeek API大模型(便宜,中文友好)
Chroma向量数据库(RAG 检索)
SQLite业务数据存储
LangGraphAgent 框架(状态图 + 条件路由)

三、整体架构

智能体的核心流程如下: 用户输入

【判断意图】→ 知识类 → RAG 检索 → 回答

数据类 → 生成 SQL → 执行 → 解释结果

计算类 → 提取表达式 → 计算 → 返回

关键点:用一个 LLM 判断意图,然后根据意图走不同的处理分支

四、核心代码解析

1. 定义状态(传递的数据包)

class AgentState(TypedDict):
    question: str    # 用户问题
    intent: str      # 意图:knowledge / data / calculator
    answer: str      # 最终答案

2. 意图判断节点

def classify_node(state: AgentState):
   prompt = f"""判断问题类型,只回答"knowledge"、"data"或"calculator"。
   知识类:问概念、定义、解释
   数据类:问统计、数量、金额
   计算类:数学计算
   问题:{state["question"]}
   类型:"""
   result = call_deepseek(prompt).strip().lower()
   intent = "knowledge" if "knowledge" in result else "data" if "data" in result else "calculator"
   return {"intent": intent}

3. 条件路由(根据意图选节点)

def route_by_intent(state: AgentState):
   if state["intent"] == "knowledge":
       return "knowledge"
   elif state["intent"] == "data":
       return "sql"
   else:
       return "calculator"

builder.add_conditional_edges("classify", route_by_intent, {
   "knowledge": "knowledge",
   "sql": "sql",
   "calculator": "calculator"
})

4. 各工具节点

RAG 节点(从 Chroma 检索):

def knowledge_node(state):
    context = search_rag(state["question"])
    prompt = f"基于资料回答问题。资料:{context}\n问题:{state['question']}"
    return {"answer": call_deepseek(prompt)}

SQL 节点(让模型写 SQL 并执行):

def sql_node(state):
    sql = call_deepseek(f"数据库结构:{schema}\n问题:{state['question']}\nSQL:")
    result = execute_sql(sql)
    answer = call_deepseek(f"查询结果:{result}\n用自然语言回答")
    return {"answer": answer}

计算器节点(安全执行数学表达式):

def calculator_node(state):
    expr = call_deepseek(f"提取表达式:{state['question']}")
    result = eval(expr, {"__builtins__": {}}, {"sqrt": math.sqrt, "pi": math.pi})
    return {"answer": f"{expr} = {result}"}

五、运行效果

直接看终端输出:

934a7d3c9b69df53026063f09347707e.png 智能体成功区分知识类、数据类、计算类问题

六、踩坑记录

  1. API Key 空格:复制时容易带上空格 → 用 .strip() 清理
  2. Chroma 模型下载:默认源在国外 → 用国内镜像 HF_ENDPOINT
  3. SQL 带 Markdown:模型返回 ```sql ... ``` → 用字符串清理
  4. eval 安全:限制 __builtins__ 和只允许少数函数,防止恶意代码

七、总结与下一步

第一周完成了:

  • RAG 检索(Chroma)
  • SQL 生成与执行
  • 计算器工具
  • LangGraph 图结构 + 条件路由

下一步:

  • 增加联网搜索工具
  • 支持多步推理(例如:先查笔记本销量,再和鼠标对比)
  • 用 FastAPI 封装成服务

八、代码仓库

所有代码已开源在 GitHub:
github.com/qiu121122/a…

欢迎 star、fork、交流!

本文首发于掘金,如有转载需求请私信联系。