100行代码讲懂Agent skills开发框架的原理和流程

本文摘要背景与目的当前主流 LLM 应用开发框架越来越多,如 LangChain、Dify、LlamaIndex、Semantic Kernel、Coze 等,效果更是每过几天就会给人一个大惊喜!这些主流框架,复杂度也越来越高,刚入门的同学很多云里雾里,无从下手,本🤖 simple\_skills\_agent 极简项目 基于最原生的 Python,不使用任何开发框架,以天气 Agent 的极简项目,为大...

背景与目的

当前主流 LLM 应用开发框架越来越多,如 LangChain、Dify、LlamaIndex、Semantic Kernel、Coze 等,效果更是每过几天就会给人一个大惊喜!

这些主流框架,复杂度也越来越高,刚入门的同学很多云里雾里,无从下手,本🤖 simple\_skills\_agent 极简项目 基于最原生的 Python,不使用任何开发框架,以天气 Agent 的极简项目,为大家展现出 Agent skills 的开发框架的核心逻辑和设计理念,重点突出 Agent Skills 新范式,将特定领域知识,用结构化的文档层次组织,通过LLM决策过程中基于渐进式的动态加载,来最低消耗资源(Tokens),按需激活 上下文工程,来引导 LLM 给出在特定领域 基于经验(skills) "干好活”!!

  1. 什么是 Agent Skills

  2. Agent Skills 场景

我们先看 2 个 Agent Skills 的相关视频,来感性了解一下相关的场景:

【引用声明-来自公众号:轩辕的编程宇宙。在此感谢作者!】

【引用声明-来自小红书:阿甘探 AI。在此感谢作者!】

Agent 和MCP解决 AI "能不能干活“ 的问题,也就是 AI 能做什么决策,能自主调用哪些工具去干活。

而 Agent Skills 解决的是 AI "能不能把活干好“ 的问题,它最大的亮点是决策的 “渐进式披露”,从业务 Skills 规则和流程,保证结果的稳定输出。

  1. Agent Skills 发展历史回顾

    • 2022 年 OpenAI 发布 GPT-3.5 并支持函数调用,为 Agent Skills 奠定技术基础;
    • 2023 年 LangChain、LlamaIndex 等主流 Agent 框架发布,提出 “Tool/Chain/Agent” 分层模型,将 Skill 封装为 Chain/Tool 组合,是 Agent Skills 的工程化雏形;
    • 2024 年至今,“技能可扩展” 成为 Agent 框架核心设计原则,出现配置化 Skill 开发(如通过 Markdown/JSON 定义 Skill,无需改动核心代码),也是当前新手开发的主流方向。

Agent Skills 的发展与 AI Agent、大语言模型(LLM)的技术演进深度绑定,核心经历了3 个阶段,从 “硬编码函数” 逐步进化为 “LLM 驱动的可扩展技能”,也是新手需要理解的技术演进逻辑:

  1. Agent Skills 的价值

Agent 工程扩展 LLM 能力传统上主要有如下几个方案:

  • 提示词工程(Prompt Engineering):通过给 LLM 输入指定的文本来引导 LLM 给出结果;
  • 工具调用(Tool Calling):通过 LLM 决策相关的外阅 API,把模型与工具相连接,完成某项任务;
  • 微调(Fine-tuning):通过重新训练 LLM 权重来内化增强能力。

Agent Skills 代表了一种新的范式,上下文工程(Context Engineering),将特定领域知识,用结构化的文档层次组织,通过 LLM 决策过程中基于渐进式的动态加载,来最低消耗资源(Tokens),按需激活 上下文工程,来引导 LLM 给出在特定领域 基于经验(skills) "干好活”

  1. 🤖 simple\_skills\_agent 项目介绍

  2. 项目介绍

本次实战项目"🤖simple\_skills\_agent",是一个高度解耦、纯本地 LLM 驱动的天气查询 Agent 框架,核心特点是「规则与代码分离」(所有业务规则都在 weather_skill.md 中)、「LLM 主导决策」(参数解析 / 结果生成全由本地 llama-3-8b 完成)、「无硬编码逻辑」(修改规则仅需改 md 文件)。

本项目的基本流程为:加载技能定义 → 命令行接收用户输入 → 大模型意图识别(确认是否为天气查询) → 技能执行(提取城市 → 调用天气工具 → 获取数据) → 大模型润色结果 → 命令行输出回复。

详细流程图如下:

这个项目能充分展现当前工业界流行的 Skills 模式,核心流程和技术点一一对应,且无框架依赖,让大家对底层逻辑有一个最基本的认知,遵循Agent 技能开发的标准执行链路

  1. 技能加载:Agent 启动时加载 skills 目录的技能定义文件,解耦配置与代码;
  2. 用户输入接收:命令行作为交互入口,模拟 Agent 的用户交互层;
  3. 意图识别:由大模型(llama-3-8b)判断用户输入是否触发对应技能,是 Skills 的核心前置判断(避免无意义的工具调用);
  4. 技能执行:触发技能后,执行该技能的专属逻辑(提取参数 → 调用工具 → 获取原始数据);
  5. 结果整合 / 润色:大模型对工具返回的结构化原始数据进行自然语言润色,符合人类对话习惯;
  6. 结果输出:将最终结果返回给用户,完成一次技能调用。
  7. 🤖 simple\_skills\_agent 项目整体架构

  8. 架构设计

  • 类型:轻量级纯 Python Agent 框架(无第三方 Agent 框架依赖,原生实现);
  • 部署方式:本地离线部署(依赖 LM Studio 运行 llama-3-8b,无外网 LLM API 调用);
  • 核心思想:Skills 驱动(所有业务规则通过 weather_skill.md 定义,代码仅负责执行);
  • 交互方式:命令行交互(CLI),适合本地调试和基础功能验证。
  1. 关键模块

🤖 simple\_skills\_agent 项目,有如下几个核心模块,职责说明如下表:

  1. 基本代码流程

项目代 码 simple\_skills\_agent.py 的基本处理流程如下:

main 函数项目启动 -> 加载 skills 规则 -> 初始化天气类 -> 循环响应用户问题(接受用户输入 -> 解析用户指令 -> 调用工具 -> LLM 格式化返回用户的答案。

  1. 基本代码框架

项目代 码 simple\_skills\_agent.py 的基本框架如下:

import os
import re
import json
import requests
from typing import Dict, Any

# ===================== 全局配置(适配本机LM Studio,保留你的原有配置)=====================
# LM Studio开启OpenAI兼容API后的基础地址(默认端口1234,无需修改)
LM_STUDIO_BASE_URL = "http://localhost:1234/v1"
# 本机部署的模型名称(需和LM Studio中显示的模型名一致)
LM_STUDIO_MODEL = "llama-3-8b"
# 大模型请求参数(适配llama-3-8b,温度0.0保证解析稳定)
LLM_CONFIG = {
    "temperature": 0.0,  # 纯规则解析,温度设为0,结果更稳定
    "max_tokens": 512,
    "top_p": 0.9,
    "stream": False
}
# Skills目录路径(固定为项目下的skills目录)
SKILLS_DIR = os.path.join(os.path.dirname(__file__), "skills")
# 优化后的天气Skill文件路径(对应你优化后的skills.md,重命名为weather_skill.md)
WEATHER_SKILL_FILE = os.path.join(SKILLS_DIR, "weather_skill.md")

# ===================== 第一步:Skill加载模块(适配优化后的skills.md结构)=====================
def load_weather_skill() -> Dict[str, Any]:
    """
    从优化后的weather_skill.md加载结构化的天气Skill规则
    返回结构化字典,而非纯文本,便于后续模块调用(解耦更彻底)
    :return: 结构化Skill字典,包含所有规则信息
    """  
    # 解析优化后的skills.md,提取所有结构化信息
    skill_dict = {
        "raw_content": skill_content,  # 保留原始内容,供LLM解析使用
        "description": "",
        "tool": {
            "name": "",
            "type": "",
            "url": "",
            "param_mapping": "",
            "timestamp_rule": "",
            "headers_rule": ""
        },
        "core_fields": [],
        "llm_instruction": ""
    }

    return skill_dict

# ===================== 本地大模型调用模块(保留你的原有逻辑)=====================
def call_lm_studio(prompt: str) -> str:
    """
    调用本机LM Studio的llama-3-8b模型,返回模型生成的文本
    基于LM Studio的OpenAI兼容API,无框架依赖
    :param prompt: 大模型的提示词/指令
    :return: 模型生成的纯文本结果
    """
    # 构造OpenAI兼容的请求体
    payload = {
        ...
    }
    # 解析大模型返回结果
    result = response.json()
    return result

# ===================== 第三步:指令解析模块(适配优化后的解析规则)=====================
def parse_user_query(user_input: str, skill_dict: Dict[str, Any]) -> Dict[str, Any]:
    """
    调用本地LLM,根据优化后的Skill规则解析用户指令
    严格遵循skills.md中的解析要求,无硬编码规则
    :param user_input: 用户原始命令行输入
    :param skill_dict: 结构化的天气Skill字典
    :return: 结构化参数字典,如{"city": "上海", "query_time": "now"}
    """
    # 构造解析提示词(严格按优化后的Skill规则)
    prompt = f"""
你是一个严格遵守规则的AI Agent指令解析器,必须按以下规则解析用户的天气查询指令:
"""
    # 第四步:调用本地LLM获取解析结果
    parse_result = call_lm_studio(prompt)
    ...

# ===================== 第四步:工具调用模块(完全基于Skill规则,无硬编码)=====================
class WeatherTool:
    """
    天气工具类,完全按优化后的weather_skill.md规则实现
    所有工具逻辑(API地址、参数、请求头)均从Skill读取,无硬编码
    """
    def __init__(self, skill_dict: Dict[str, Any]):
        # 从Skill字典中提取API地址(核心:无硬编码)
        self.weather_api = skill_dict["tool"]["url"]
        # 从Skill中提取核心查询项(用于结果过滤)
        self.core_fields = skill_dict["core_fields"]
       ...

    # 第五步:行动-技能执行:提取城市→调用天气工具→获取数据
    def get_weather_data(self, city_name: str) -> Dict[str, Any]:
        """
        获取指定城市的原始天气数据,严格按Skill的核心查询项过滤
        :param city_name: 解析后的城市名
        :return: 结构化天气数据字典(匹配核心查询项)
        """
        response = self.session.get(api_url, timeout=10, verify=False)
        # 5. 按Skill的核心查询项构造结果(无硬编码字段)
            weather_result = {
                "城市": city_name,
                f"{self.core_fields[0]}(℃)": real_time.get("temperature", "暂无数据"),
                f"{self.core_fields[1]}": daily.get("dayText", "暂无数据"),
                f"{self.core_fields[2]}": real_time.get("windDirection", "暂无数据"),
                f"{self.core_fields[3]}": real_time.get("windSpeed", "暂无数据"),
                f"{self.core_fields[4]}(%)": real_time.get("humidity", "暂无数据")
            }
         return weather_result


# ===================== 第七步:结果生成模块(LLM主导,无硬编码生成规则)=====================
def generate_answer(weather_data: Dict[str, Any], skill_dict: Dict[str, Any]) -> str:
    """
    调用本地LLM,将结构化天气数据转为自然语言回答
    生成规则完全由LLM主导,无硬编码的文本拼接
    :param weather_data: 工具返回的结构化天气数据
    :param skill_dict: 结构化的天气Skill字典
    :return: 口语化自然语言回答
    """
    # 构造生成提示词(LLM主导结果格式化)
    prompt = f"""
你是一个友好的天气查询助手,需要将以下结构化天气数据转为口语化的自然语言回答:
"""
    # 第八步:调用本地LLM生成结果
    return call_lm_studio(prompt)

# ===================== 第六步:核心Agent主逻辑+命令行交互(保留你的原有交互体验)=====================
def main():
    """Agent主入口,实现:Skill加载→命令行交互→指令解析→工具调用→结果生成→响应"""
    print("=" * 60)
    print("🤖【原生Python Skills Agent - 天气查询助手(纯LLM驱动)】")
    print("提示:1. 输入城市天气查询问题(如:今天上海的天气如何?);2. 输入exit/退出可终止程序;3. 仅支持国内城市")
    print("=" * 60 + "\n")

    try:
        # 初始化:加载结构化天气Skill(仅加载一次)
        print("🔧 正在加载天气Skill规则...")
        skill_dict = load_weather_skill()
        print(f"✅ 成功加载天气Skill:{WEATHER_SKILL_FILE}\n")

        # 初始化天气工具(完全基于Skill规则)
        weather_tool = WeatherTool(skill_dict)

        # 命令行持续交互循环
        while True:
            # 第二步:获取用户输入
            user_input = input("🙋 你:").strip()
            # 核心Agent执行流程
            try:
                # 1. 解析用户指令,提取结构化参数
                print("🤖 Agent:正在解析你的查询指令...")
                parse_data = parse_user_query(user_input, skill_dict)
              
                city = parse_data["city"]
                print(f"✅ Agent:解析成功,目标查询城市:{city}")

                # 2. 调用天气工具,获取结构化天气数据
                print("🌤️ Agent:正在调用天气工具查询数据...")
                weather_data = weather_tool.get_weather_data(city)

                # 3. 第九步:调用LLM,生成自然语言回答
                print("📝 Agent:正在整理查询结果...")
                answer = generate_answer(weather_data, skill_dict)

                # 4. 第十步:调用天气工具,获取结构化天气数据输出最终结果
                print(f"\n🤖 Agent:{answer}\n")


# 程序入口
if __name__ == "__main__":
    main()
  1. 🤖 simple\_skills\_agent 代码详解

以下分别按照🤖 simple\_skills\_agent 项目的主体结构 ,分别详细代码介绍:

  1. 项目依赖&基础配置(全局变量)

# LM Studio配置(本地大模型核心)
LM_STUDIO_BASE_URL = "http://localhost:1234/v1"  # OpenAI兼容API地址
LM_STUDIO_MODEL = "llama-3-8b"                   # 本地加载的模型名
LLM_CONFIG = {
    "temperature": 0.0,  # 0温度=无随机性,保证解析结果稳定
    "max_tokens": 512,   # 限制生成长度,避免冗余
    "top_p": 0.9,
    "stream": False
}
# Skill路径配置(解耦核心)
SKILLS_DIR = os.path.join(os.path.dirname(__file__), "skills")
WEATHER_SKILL_FILE = os.path.join(SKILLS_DIR, "weather_skill.md")
  • 核心作用:集中管理环境参数,修改时无需改动业务代码;
  • 设计亮点temperature=0.0 是纯规则解析场景的最优配置(避免 LLM 生成随机结果);
  • 关键细节os.path.dirname(file) 保证路径适配不同运行环境(相对路径 → 绝对路径)。
  1. Skill 加载层(load_weather_skill()

def load_weather_skill() -> Dict[str, Any]:
    # 1. 文件存在性校验
    if not os.path.exists(WEATHER_SKILL_FILE):
        raise FileNotFoundError(...)
    # 2. 读取md文件
    with open(...) as f:
        skill_content = f.read()
    # 3. 结构化解析(正则提取各模块)
    skill_dict = {
        "raw_content": skill_content,  # 保留原始内容供LLM使用
        "description": "",            # 技能描述
        "tool": {...},                # 工具配置(API地址/参数)
        "core_fields": [],            # 核心查询项
        "llm_instruction": ""         # LLM解析规则
    }
    # 4. 正则提取各字段(适配md格式)
    desc_match = re.search(r'## 技能描述\n(.*?)\n## 绑定工具', skill_content, re.DOTALL)
    # ... 其他正则提取逻辑
    return skill_dict
  • 核心作用:将非结构化的 md 文件转为结构化字典,让代码可直接读取规则;
  • 设计亮点

    • 保留 raw_content 字段,避免重复读取文件;
    • 正则使用 re.DOTALL. 匹配换行),适配 md 的多行文本;
    • 提取核心字段时去除序号 / 括号(如 1. 实时气温(℃)实时气温);
  • 关键细节:所有解析逻辑基于 md 的固定格式,修改 md 结构时需同步调整正则。
  1. LLM 调用层(call_lm_studio()

def call_lm_studio(prompt: str) -> str:
    # 1. 构造OpenAI兼容请求体
    payload = {
        "model": LM_STUDIO_MODEL,
        "messages": [{"role": "user", "content": prompt}],
        **LLM_CONFIG
    }
    # 2. 发送POST请求
    response = requests.post(
        url=f"{LM_STUDIO_BASE_URL}/chat/completions",
        headers={"Content-Type": "application/json"},
        json=payload,
        timeout=60  # 本地模型推理慢,超时设60秒
    )
    response.raise_for_status()  # 主动抛出HTTP异常
    # 3. 解析结果
    result = response.json()
    return result["choices"][0]["message"]["content"].strip()
  • 核心作用:封装 LLM 调用逻辑,为上层提供统一的「提示词 → 生成文本」接口;
  • 设计亮点

    • 完全兼容 OpenAI 的 API 格式,适配 LM Studio 的默认配置;
    • timeout=60 适配本地模型推理速度(避免过早超时);
    • response.raise_for_status() 主动抛出异常,便于上层捕获;
  • 关键细节:无 API 密钥配置(LM Studio 本地调用无需密钥),符合离线部署需求。
  1. 指令解析层(parse_user_query()

def parse_user_query(user_input: str, skill_dict: Dict[str, Any]) -> Dict[str, Any]:
    # 1. 构造严格的提示词(核心:规则驱动)
    prompt = f"""
你是一个严格遵守规则的AI Agent指令解析器...
【核心解析规则】
{skill_dict['llm_instruction']}
【用户原始指令】:{user_input}
【强制要求】:仅返回JSON格式...
"""
    # 2. 调用LLM
    parse_result = call_lm_studio(prompt)
    # 3. 清洗结果(去除llama-3-8b可能输出的```标记)
    parse_result = re.sub(r"```(json)?|```", "", parse_result).strip()
    # 4. JSON解析容错
    try:
        return json.loads(parse_result)
    except json.JSONDecodeError:
        return {"error": "..."}
  • 核心作用:实现「自然语言 → 结构化参数」的转换,纯 LLM 驱动无硬编码解析逻辑;
  • 设计亮点

    • 提示词强制要求「仅返回 JSON」,避免 LLM 生成冗余文本;
    • 结果清洗逻辑适配 llama-3-8b 的输出习惯(模型可能带代码块标记);
    • JSON 解析容错,保证程序不崩溃;
  • 关键细节:所有解析规则都来自 skill_dict,修改规则仅需改 md 文件。
  1. 工具调用层(WeatherTool 类)

class WeatherTool:
    def __init__(self, skill_dict: Dict[str, Any]):
        self.weather_api = skill_dict["tool"]["url"]  # 从Skill读取API地址
        self.core_fields = skill_dict["core_fields"]  # 从Skill读取核心字段
        self.session = requests.Session()             # 会话复用提升效率
        # 模拟浏览器请求头,避免API风控
        self.session.headers.update({...})
  
    def get_weather_data(self, city_name: str) -> Dict[str, Any]:
        # 1. 构造API地址(时间戳+城市名替换)
        timestamp = str(int(time.time()))
        api_url = self.weather_api.replace("{city_name}", city_name).replace("{timestamp}", timestamp)
        # 2. 发起请求
        response = self.session.get(api_url, timeout=10, verify=False)
        response.raise_for_status()
        # 3. 解析数据并按核心字段过滤
        raw_data = response.json()
        weather_result = {
            "城市": city_name,
            f"{self.core_fields[0]}(℃)": real_time.get("temperature", "暂无数据"),
            # ... 其他字段
        }
        return weather_result
  • 核心作用:按 Skill 规则调用外部 API,获取结构化天气数据;
  • 设计亮点

    • 完全无硬编码:API 地址、核心字段均从 Skill 读取;
    • requests.Session() 复用 TCP 连接,提升多次请求效率;
    • verify=False 适配气象局 API 的 SSL 证书问题;
    • 缺失值统一返回「暂无数据」,提升用户体验;
  • 关键细节:API 参数替换({city_name}/{timestamp})严格按 Skill 规则实现。
  1. 结果生成层(generate_answer()

def generate_answer(weather_data: Dict[str, Any], skill_dict: Dict[str, Any]) -> str:
    prompt = f"""
你是一个友好的天气查询助手...
【核心要求】
1. 仅包含{skill_dict['core_fields']}这5项信息;
2. 缺失数据显示「暂无数据」;
3. 回答口语化、简洁易懂;
【结构化天气数据】:
{json.dumps(weather_data, ensure_ascii=False, indent=2)}
"""
    return call_lm_studio(prompt)
  • 核心作用:实现「结构化数据 → 自然语言」的转换,纯 LLM 驱动无硬编码文本拼接;
  • 设计亮点

    • 提示词明确约束输出规则(仅包含核心字段、口语化);
    • json.dumps(ensure_ascii=False) 保证中文正常显示;
    • 完全由 LLM 处理格式,无需手动拼接字符串;
  • 关键细节:提示词的「友好助手」角色设定,让生成结果更符合用户预期。
  1. 交互层(main() 函数)

def main():
    # 1. 初始化(加载Skill+创建工具实例)
    skill_dict = load_weather_skill()
    weather_tool = WeatherTool(skill_dict)
    # 2. 交互循环
    while True:
        user_input = input("🙋 你:").strip()
        # 退出/空输入处理
        if user_input in ["exit", "退出", "q", "Q"]: break
        if not user_input: continue
        # 3. 核心流程
        parse_data = parse_user_query(user_input, skill_dict)
        if "error" in parse_data:
            print(f"❌ Agent:{parse_data['error']}\n")
            continue
        weather_data = weather_tool.get_weather_data(parse_data["city"])
        answer = generate_answer(weather_data, skill_dict)
        print(f"\n🤖 Agent:{answer}\n")
  • 核心作用:串联所有模块,提供用户交互入口;
  • 设计亮点

    • 异常捕获机制(try/except)保证程序不崩溃;
    • 清晰的状态提示(🔧/✅/🌤️/📝)提升用户体验;
    • 仅加载一次 Skill / 工具实例,提升运行效率;
  • 关键细节:交互循环的「退出条件」和「空输入处理」,避免无效执行。
  1. 🤖 simple\_skills\_agent 运行效果

项目运行步骤

步骤 1:启动 LM Studio 本地大模型 API

打开 LM Studio→「Server」→ 选择 llama-3-8b→ 点击「Start Server」,确保控制台显示 Server running on http://127.0.0.1:1234

步骤 2:

  1. 将代码保存为 simple_weather_agent.py
  2. 命令行进入文件所在目录,执行:
  3. 运行
python simple_skills_agent.py

或直接在 VS2026 IDE 环境中点执行

步骤 3:运行成功后,弹出对话界面:

  1. 🤖simple\_skills\_agent 项目的源码

项目源代码:https://github.com/hechunji/simple\_skills\_agent

关键项目附件:

暂时无法在飞书文档外展示此内容

暂时无法在飞书文档外展示此内容

  1. 总结

Agent Skills 开发的关键技术小结,所有技术点均为当前 Agent Skills 开发的核心技术,且用 Python 原生实现,无框架封装,方便你理解底层:

  1. 技能定义解耦:技能的工具选择、查询项、执行规则全部写在 weather_skill.md,修改技能无需改核心代码(比如想换成百度天气,仅需修改 md 文件和少量工具调用代码);
  2. 大模型驱动的意图识别:放弃传统的正则硬匹配,由大模型基于技能定义做意图判断,泛化性更强(比如用户问 “上海今天热吗?”“成都现在刮什么风?” 都能识别为天气查询);
  3. 工具调用封装:将天气接口调用封装为独立的 call_weather_tool 函数,符合 Skills 的工具化思想(一个技能对应一个 / 多个工具,工具与 Agent 核心逻辑解耦);
  4. 本地大模型原生对接:兼容 OpenAI API 格式,用 Python 内置的 http.client 实现请求,无任何第三方库依赖,理解大模型 API 的底层通信逻辑;
  5. 参数提取与结构化处理:从用户输入中提取核心参数(城市名),工具返回结构化数据,再由大模型转为自然语言,体现Agent 的 “感知 - 执行 - 表达” 能力
  6. 技能的单一职责weather_skill 仅负责天气查询,后续扩展其他技能(如快递查询、时间查询),仅需在 skills 目录添加新的 md 文件,再在代码中添加对应技能执行逻辑,符合Skills 的模块化开发思想

【END】

下期预告:100 行代码讲懂多 skills Agent 开发框架的原理和流程

觉得内容不错?我要

打赏杯咖啡或蜜雪冰城吧
微信扫一扫
微信赞赏码
支付宝扫一扫
支付宝赞赏码
评论 暂无评论
请登录后参与评论