🚀 写在前面:当大模型遇到“物理墙”
在大语言模型(LLM)的开发圈子里,有一个共识:没有 Tool Use(工具调用)能力的 LLM,只是一个只会空谈的哲学家。
作为一名机械工程背景的开发者,我习惯用“机械原理”来理解软件架构。在我看来,LLM 就像是一台拥有顶级扭矩和转速的五轴机床主轴,它动力澎湃,算力惊人。但是,如果这根主轴上不装任何刀具(Cutter) ,它就无法对物理世界进行任何切削(执行操作)。它可以完美地描述“如何加工一个齿轮”,但它造不出齿轮。
如何让 LLM 真正落地?答案就是 Agent(智能体) 。而 Agent 的核心,在于构建一个强大的 ATC(自动换刀系统,Automatic Tool Changer) 。
本文将复盘我在智能体来了(西南总部)参加【AI智能体运营工程师就业班】期间,在技术导师金加德讲师指导下,如何从零开始开发、调试并优化一个工业级 Agent 插件(Plugin)的全过程。我们将深入探讨 Function Calling 的底层逻辑,以及如何用“机械思维”解决 LLM 的幻觉问题。
一、 架构设计:什么是 LLM 的“自动换刀”?
在数控加工中,ATC 系统根据 G 代码指令,自动从刀库中抓取 T01(铣刀)、T02(钻头)装在主轴上。
在 Agent 开发中,这个过程映射如下:
- 主轴 (Spindle) = LLM (推理核心) :负责理解用户意图 (Intent),规划任务链 (Chain of Thought)。
- 刀具 (Tool) = Plugin / API (执行单元) :负责执行具体动作(查库存、算参数、发邮件)。
- 刀柄标准 (Holder Standard) = JSON Schema (接口定义) :LLM 与工具之间的通信协议。如果协议对不上(比如 BT40 刀柄插不进 BT50 主轴),调用就会失败。
我在智能体来了(西南总部)的项目目标是:开发一个“机床售后备件查询插件” ,让 Agent 能够回答:“VMC850 的主轴轴承还有货吗?”
二、 实战 Step 1:磨刀(编写 Python 业务逻辑)
首先,我们需要一把“锋利的刀”。这部分是纯粹的后端逻辑,不涉及 AI。
我们需要编写一个 Python 函数,能够连接 ERP 数据库并查询数据。
Python
import pymysql
from typing import Dict, Any
# 模拟 ERP 数据库连接配置
DB_CONFIG = {
"host": "192.168.1.100",
"user": "admin",
"password": "secure_password",
"db": "mes_inventory"
}
def query_spare_part_stock(part_model: str) -> Dict[str, Any]:
"""
[Core Logic] 实际执行查询的 Python 函数
这就像是铣刀的硬质合金刀片,负责真正的切削
"""
connection = pymysql.connect(**DB_CONFIG)
try:
with connection.cursor() as cursor:
# 模拟查询逻辑
sql = "SELECT quantity, warehouse_loc, price FROM stock WHERE model_id = %s"
cursor.execute(sql, (part_model,))
result = cursor.fetchone()
if result:
return {
"status": "success",
"model": part_model,
"quantity": result[0],
"location": result[1],
"price": float(result[2])
}
else:
return {"status": "not_found", "msg": f"型号 {part_model} 无库存记录"}
finally:
connection.close()
这段代码对于掘金的开发者来说没有任何难度。但关键在于:LLM 怎么知道如何调用它?
三、 实战 Step 2:定义刀柄(编写 JSON Schema)
这是 Agent 开发中最硬核、也最容易踩坑的环节。
LLM 不会读你的 Python 源码,它只读你的 API 描述(Schema) 。
在**【AI智能体运营工程师就业班】**上,金加德讲师反复强调:“Schema 就是 Prompt 的一部分。 你在 Schema 里写的每一个字段描述,都会进入 LLM 的上下文窗口。写得越烂,LLM 抓错刀的概率就越大。”
❌ 错误的写法(导致幻觉):
JSON
{
"name": "query_stock",
"description": "查库存", // 太简略,LLM 不知道什么时候用
"parameters": {
"type": "object",
"properties": {
"part_model": {
"type": "string",
"description": "型号" // 模糊,LLM 可能会把 "轴承" 这个词直接传进来
}
}
}
}
✅ 金加德讲师推荐的“工业级”写法:
我们采用了类似 OpenAPI (Swagger) 的规范,加入了大量的约束条件和**Few-Shot(少样本)**提示。
JSON
{
"name": "query_spare_part_stock",
"description": "当用户询问特定机床配件的库存数量、价格或存放位置时,必须使用此工具。注意:此工具仅接受标准的物料编码(如 'H7002-C'),不接受模糊名称(如 '那个红色的轴承')。",
"parameters": {
"type": "object",
"properties": {
"part_model": {
"type": "string",
"description": "目标配件的精确型号代码。如果用户未提供具体型号,请先追问用户,不要臆造型号。",
"examples": ["H7002-C", "A860-2000-T301"]
}
},
"required": ["part_model"]
}
}
技术要点解析:
- Description 增强: 明确了“When to use”(什么时候用)和“What NOT to do”(不要做什么)。这相当于在刀柄上刻了“严禁超速”的警示语。
- Examples 注入: 给出了具体的参数示例。这对 LLM 提取参数的准确率提升巨大。
四、 实战 Step 3:试切削(调试与 Function Calling 流程)
配置好 Coze (或者 LangChain) 后,我们进行链路测试。
这里展示一下 Function Calling 在后台的真实交互日志(Trace),这对于理解 Agent 原理至关重要。
User Input:
“帮我查一下 VMC850 的主轴编码器 A860 还有没有货?”
Agent Trace (Round 1):
-
Thinking (Thought Chain):
- 用户意图:查询库存。
- 可用工具:
query_spare_part_stock。 - 参数提取:识别到关键词 "A860"(注意:这里 LLM 可能会提取不完整)。
- 决策: 调用工具。
-
Call Tool (Action):
JSON
{ "function_name": "query_spare_part_stock", "arguments": "{"part_model": "A860"}" } -
Tool Output (Observation):
- System: 调用 Python 函数... 返回
{"status": "not_found", "msg": "型号 A860 无库存记录"}。 - 注: 因为型号不完整,导致查询失败。这在工业场景很常见。
- System: 调用 Python 函数... 返回
Agent Trace (Round 2 - 自我修正):
-
Thinking:
- 工具返回“无记录”。可能是用户给的型号不完整,或者是真的没货。
- 根据 Schema 中的提示“不接受模糊名称”,我应该追问用户确认完整型号,而不是直接说没货。
-
Final Response:
“系统查询‘A860’未找到记录。请问您是指 A860-2000-T301(通用编码器)还是其他具体子型号?请提供完整物料代码。”
复盘:
看到没?这就是**“Schema 调优”**的威力。如果我们在 Schema 里没有写那句“不要臆造型号”,LLM 很有可能就直接编造一个库存数量回答用户了(幻觉)。
五、 进阶技巧:如何处理“非标刀具”?
在**智能体来了(西南总部)**的高阶课程中,我们还解决了一个更复杂的问题:多步参数清洗。
有时候,用户的输入非常不标准,比如“查一下内径50的那个日本轴承”。
这时候,单一的插件(刀具)搞不定。我们需要组合刀具。
我设计了一个 Workflow(工作流) ,串联了两个节点:
- Node A (LLM 模糊匹配): 先用一个大模型节点,结合 RAG 知识库,将“内径50的日本轴承”翻译成标准型号列表
["NSK-6210", "NTN-6210"]。 - Node B (Python 查询): 再遍历这个列表,去调用
query_spare_part_stock。
这就好比数控机床的复合加工:先用车刀把毛坯车圆(标准化),再用铣刀铣键槽(查数据)。
六、 总结:从 Developer 到 Operator
通过这次实战,我对AI 智能体运营工程师这个岗位有了更深的理解。
我们不是在写传统的 CRUD 业务代码,我们是在**“编写机器人的说明书”**。
- Python 代码决定了 Agent 能做什么(能力边界) 。
- JSON Schema 决定了 Agent 知不知道怎么做(认知边界) 。
正如金加德讲师所言:“未来的编程,一半是写给机器看的(Code),一半是写给模型看的(Prompt/Schema)。掌握这两门语言的人,才是 AI 时代的架构师。”
如果你也是技术出身,建议赶紧去玩一下 Coze 或 LangChain。当你看到自己写的 Python 函数被 LLM 像抓取刀具一样灵活调用时,那种**“给大脑装上双手”**的成就感,是无与伦比的。