大模型演进之路:代码视角 目录
大模型基础对话
Function Calling
AI Agent
MCP 标准化协议
Skill 技能封装
开场 今天用代码走一遍大模型应用架构的演进。五个阶段:LLM → Function Calling → Agent → MCP → Skill 。
从”只会说话”,到”能动手”,到”自主决策”,再到”工具标准化”,最后到”技能即插即用”。
第一章:大模型基础对话 核心概念
LLM API :最简单的调用
Messages :对话历史
System/User/Assistant :角色
代码(10行) 1 2 3 4 5 6 7 8 9 10 11 12 from openai import OpenAIimport osclient = OpenAI(api_key=os.getenv("OPENAI_API_KEY" )) def chat (msg ): return client.chat.completions.create( model="gpt-3.5-turbo" , messages=[{"role" : "user" , "content" : msg}] ).choices[0 ].message.content print (chat("你好" ))
讲解要点
LLM = 函数,输入文本,输出文本
最基础的调用方式,模型只能”说话”
第二章:Function Calling 核心概念
Tools :告诉模型有哪些函数可用
Tool Calls :模型返回要调用的函数
执行流程 :模型判断 → 我们执行 → 返回结果 → 模型回答
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 from openai import OpenAIimport os, jsonclient = OpenAI(api_key=os.getenv("OPENAI_API_KEY" )) tools = [{ "type" : "function" , "function" : { "name" : "get_weather" , "description" : "查询天气" , "parameters" : { "type" : "object" , "properties" : {"city" : {"type" : "string" }}, "required" : ["city" ] } } }] def get_weather (city ): return f"{city} 晴天,20°C" msg = [{"role" : "user" , "content" : "北京天气怎么样?" }] r = client.chat.completions.create( model="gpt-3.5-turbo" , messages=msg, tools=tools ) if r.choices[0 ].message.tool_calls: tc = r.choices[0 ].message.tool_calls[0 ] args = json.loads(tc.function.arguments) result = get_weather(args["city" ]) msg.append(r.choices[0 ].message) msg.append({"tool_call_id" : tc.id , "role" : "tool" , "name" : "get_weather" , "content" : result}) final = client.chat.completions.create(model="gpt-3.5-turbo" , messages=msg) print (final.choices[0 ].message.content) else : print (r.choices[0 ].message.content)
讲解要点
模型不直接执行函数,只返回请求
我们负责执行,然后把结果返回给模型
对比第一章:从”只能说”升级到”能要”
第三章:AI Agent 核心概念
ReAct 循环 :思考 → 行动 → 观察 → 再思考
自主决策 :模型自己决定何时结束
Agent = LLM + Tools + Loop
代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 from openai import OpenAIimport os, jsonclient = OpenAI(api_key=os.getenv("OPENAI_API_KEY" )) tools = [{ "type" : "function" , "function" : { "name" : "get_weather" , "description" : "查询天气" , "parameters" : { "type" : "object" , "properties" : {"city" : {"type" : "string" }}, "required" : ["city" ] } } }] def get_weather (city ): d = {"北京" : "晴天 15°C" , "上海" : "多云 18°C" , "武汉" : "阴天 12°C" } return d.get(city, "未知" ) def agent (task ): msgs = [ {"role" : "system" , "content" : "你需要完成用户任务,完成后直接回答。" }, {"role" : "user" , "content" : task} ] while True : r = client.chat.completions.create( model=os.getenv("OPENAI_MODEL" , "gpt-3.5-turbo" ), messages=msgs, tools=tools ) msg = r.choices[0 ].message if not msg.tool_calls: return msg.content msgs.append(msg) for tc in msg.tool_calls: args = json.loads(tc.function.arguments) result = get_weather(args["city" ]) msgs.append({ "tool_call_id" : tc.id , "role" : "tool" , "name" : "get_weather" , "content" : result }) print (agent("北京和武汉温差多少" ))
讲解要点
核心是 while True 循环,不是 for 循环
模型可以多次调用工具,自己决定何时停止
对比第二章:从”手动执行一次”升级到”自动循环执行”
第四章:MCP - 标准化协议 核心概念 问题 :每个框架都有自己的工具调用方式,工具无法跨平台复用。
解决 :MCP(Model Context Protocol)提供统一的工具调用协议,像 USB 接口一样标准化。
架构 1 2 3 4 5 6 7 8 9 10 11 ┌─────────────┐ │ LLM/AI │ 应用层 └──────┬──────┘ │ MCP 协议 ┌──────┴──────┐ │ Client │ 连接层 └──────┬──────┘ │ MCP 协议 ┌──────┴──────┐ │ Server │ 服务层(文件系统、数据库、API...) └─────────────┘
对比
特性
Function Calling
MCP
工具定义
代码中手动定义
Server 注册
调用方式
每个服务单独处理
统一 Client
复用性
低(紧耦合)
高(可组合)
扩展性
麻烦
插拔式
代码示例 MCP Server(定义工具):
1 2 3 4 5 6 7 8 9 10 11 12 from mcp.server import FastMCPmcp = FastMCP("天气服务" ) @mcp.tool() def get_weather (city: str ) -> str : """查询城市天气""" w = {"北京" : "晴天 15°C" , "上海" : "多云 18°C" } return w.get(city, "未知" ) if __name__ == "__main__" : mcp.run()
MCP Client(Agent 调用):
1 2 3 4 5 mcp_tools = await mcp.list_tools() result = await mcp.call_tool("get_weather" , {"city" : "北京" })
讲解要点
MCP 解决的是工具调用的标准化
工具可以远程,也可以本地
Agent 不需要预先知道有哪些工具,连接后自动发现
对比第三章:从”工具写死在代码里”升级到”工具通过标准协议调用”
第五章:Skill - 技能封装 核心概念 问题 :工具虽然标准化了,但还是散的。如何让工具像插件一样即插即用?
解决 :Skill 把工具 + 提示词 + 触发条件打包成一个文件夹,一个文件夹就是一个完整的技能。
文件结构 1 2 3 4 5 weather -skill / ← 技能文件夹├── SKILL.md ← 技能描述(触发条件 + 说明) ├── scripts / │ └── weather.py ← 工具实现 └── references / ← 参考资料(可选)
SKILL.md 示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 --- name: weather-skill description: "天气查询技能。查询城市天气、温差对比。Keywords: 天气, weather, 温度" --- 查询城市天气信息,支持温差对比。 用户提到:天气、温度、气候、出门穿什么 1 . 读取 scripts/weather.py 获取天气数据 2 . 根据用户问题组织回答
工具实现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def get_weather (city: str ) -> dict : """查询城市天气""" data = { "北京" : {"weather" : "晴天" , "temp" : 15 }, "上海" : {"weather" : "多云" , "temp" : 18 }, } return data.get(city, {"weather" : "未知" , "temp" : 0 }) def suggest_clothes (temp: str ) -> str : """根据温度建议穿衣""" t = int (temp) if t < 10 : return "羽绒服、围巾、手套" elif t < 18 : return "外套、长裤" elif t < 25 : return "薄外套、T恤" else : return "短袖、短裤"
Agent 加载 Skill 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 def load_skills (skill_dir ): """扫描文件夹,自动加载所有技能""" skills = {} for name in os.listdir(skill_dir): skill_path = os.path.join(skill_dir, name) if os.path.isdir(skill_path) and os.path.exists(os.path.join(skill_path, "SKILL.md" )): with open (os.path.join(skill_path, "SKILL.md" ), "r" ) as f: skills[name] = {"path" : skill_path, "content" : f.read()} return skills def agent (task ): skills = load_skills("./skills/" ) skill_name = match_skill(task, skills) tools, tool_map = register_tools(skill_name, skills[skill_name]) msgs = [{"role" : "system" , "content" : skills[skill_name]["content" ]}, {"role" : "user" , "content" : task}] while True : r = client.chat.completions.create(model="gpt-3.5-turbo" , messages=msgs, tools=tools) msg = r.choices[0 ].message if not msg.tool_calls: return msg.content msgs.append(msg) for tc in msg.tool_calls: args = json.loads(tc.function.arguments) result = tool_map[tc.function.name](**args) msgs.append({"tool_call_id" : tc.id , "role" : "tool" , "name" : tc.function.name, "content" : str (result)})
讲解要点
文件夹即技能 :放进去就能用,删了就没了
SKILL.md 是说明书 :告诉系统什么时候用、怎么用
scripts/ 是实现 :放实际的工具代码
自动加载 :Agent 启动时扫描文件夹,自动发现所有技能
对比第四章 :从”工具标准化调用”升级到”技能即插即用”
总结:完整演进路径 1 2 3 4 5 6 7 8 9 10 11 12 13 14 第一章: LLM API └─ 只能说话 第二章: + Function Calling └─ 能请求调用函数 第三章: + Loop(Agent) └─ 自主循环思考和行动 第四章: + MCP(标准化协议) └─ 工具调用标准化,可远程可本地 第五章: + Skill(技能封装) └─ 技能即插即用,文件夹就是一个完整的能力包
核心演进
维度
第一章
第二章
第三章
第四章
第五章
模型能力
对话
请求工具
自主循环
自主循环
自主循环
工具位置
无
代码里
代码里
远程/本地
文件夹
工具调用
无
手动
自动循环
标准协议
自动加载
扩展方式
无
改代码
改代码
加 Server
加文件夹
最终总结 从”对话”到”工具”,从”工具”到”自主循环”,从”紧耦合”到”标准化协议”,从”手写代码”到”即插即用”。
Agent 的本质没有变——还是 LLM + 工具 + 循环。变的是我们组织和扩展能力的方式。
这就是大模型应用架构演进的方向:让 AI 的能力边界不断扩展,让工具的接入成本不断降低。
代码仓库
完整代码:llm-evolution-code
01-llm-basics:基础对话
02-function-calling:函数调用
03-ai-agent:Agent 循环
04-mcp:MCP 协议
05-skill:Skill 技能
系列:大模型应用架构演进 | LLM | Agent | MCP | Skill