Metadata-Version: 2.4
Name: skillify
Version: 0.1.0
Summary: LLM Skill 引擎 — 轻量级 Skill 管理、匹配与执行框架
Author-email: ArtLjn <liuw8789@gmail.com>
Maintainer-email: ArtLjn <liuw8789@gmail.com>
License: MIT License
        
        Copyright (c) 2026 ArtLjn
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: Homepage, https://github.com/ArtLjn/skillify
Project-URL: Repository, https://github.com/ArtLjn/skillify
Project-URL: Issues, https://github.com/ArtLjn/skillify/issues
Project-URL: Documentation, https://github.com/ArtLjn/skillify#readme
Project-URL: Changelog, https://github.com/ArtLjn/skillify/releases
Keywords: llm,skill,function-calling,agent,tool-use,openai,anthropic
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: ruff>=0.4.0; extra == "dev"
Requires-Dist: build>=1.0; extra == "dev"
Requires-Dist: twine>=4.0; extra == "dev"
Dynamic: license-file

<p align="center">
  <img src="https://raw.githubusercontent.com/ArtLjn/skillify/main/docs/banner.png" alt="skillify" width="100%">
</p>

<p align="center">
  <img src="https://img.shields.io/badge/python-3.10+-blue?style=flat-square" alt="Python 3.10+">
  <img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="MIT License">
  <img src="https://img.shields.io/badge/zero-LLM__dependency-orange?style=flat-square" alt="Zero LLM Dependency">
</p>

---

## 为什么需要 skillify？

在构建 LLM 应用时，你通常需要：

1. 将业务能力封装为 LLM 可调用的 **Function Calling Tool**
2. 对用户输入做**关键词快匹配**，高频指令不浪费 LLM Token
3. 统一管理**参数校验、执行、结果校验**的完整链路
4. 支持配置驱动的 **CRUD Skill**，不用写 Python 代码

skillify 把这些能力封装为一个独立 SDK，**不绑定任何 LLM 提供商**，拿来即用。

## 核心特性

| 特性 | 说明 |
|------|------|
| **4 种 Skill 模式** | Rule（关键词回复）、CRUD（数据管理）、Dispatch（结构化操作）、Subagent（LLM 多轮对话） |
| **Pattern 快通道** | 关键词匹配延迟 < 1ms，高频指令直接拦截不走 LLM |
| **LLM 意图兜底** | 快通道未命中时，自动调用 LLM 意图分类匹配 |
| **Function Calling** | 自动将 Skill 转为 OpenAI / Anthropic tool definition 格式 |
| **校验框架（Harness）** | 9 条内置规则 + 自定义扩展，pre/post 两阶段校验 |
| **可插拔存储** | 内存 / SQLite / MCP 边侧存储，一行代码切换 |
| **零 LLM 依赖** | 核心包仅依赖 PyYAML，LLM 客户端由调用方注入 |
| **配置驱动** | Markdown / YAML / JSON 三种格式，写配置即定义 Skill |

## 安装

```bash
pip install skillify
```

或从源码安装：

```bash
git clone https://github.com/ArtLjn/skillify.git
cd skillify
pip install -e .
```

## 快速开始

### 30 秒上手

```python
from skillify import SkillManager, SkillContext

# 1. 初始化 — 扫描 Skill 目录，自动注册
sm = SkillManager(skill_dirs=["./skills"])

# 2. 转为 LLM function calling 格式
tools = sm.to_tool_definitions()  # 直接注入 LLM tools 参数

# 3. 关键词快通道匹配（< 1ms）
match = sm.fast_match("帮我查天气")

# 4. 执行 Skill
ctx = SkillContext(user_id="user_001", timezone="Asia/Shanghai")
result = await sm.execute("weather", {"city": "苏州"}, ctx)
print(result.result.reply)
```

### 一站式路由 — handle()

```python
result = await sm.handle("你好", context)

if result.executed:
    # 已自动执行完成（Rule/CRUD/Dispatch）
    print(result.execute_result.result.reply)
elif result.source == HandleSource.SUBAGENT:
    # Subagent 类型，需要上层 handoff 到独立 LLM 循环
    skill = sm.get_skill(result.match.skill_name)
elif result.source == HandleSource.NONE:
    print("未匹配任何 Skill")
```

路由逻辑：

```
用户输入 → fast_match() → 命中 Rule/CRUD/Dispatch → FAST（自动执行）
                        → 命中 Subagent          → SUBAGENT（handoff）
                        → 未命中 + 有 LLM        → LLM_INTENT（意图兜底）
                        → 未命中 + 无 LLM        → NONE
```

## Skill 类型一览

| 模式 | 适用场景 | LLM 调用 | 延迟 | 定义方式 |
|------|---------|----------|------|---------|
| **Rule** | 简单指令（快捷回复、问候） | 0 | < 1ms | Markdown 配置 |
| **CRUD** | 数据管理（待办、笔记） | 0 | < 10ms | Markdown 配置 |
| **Dispatch** | 结构化操作（提醒、日历、查询） | 0（Skill 侧） | < 100ms | Markdown + scripts/ |
| **Subagent** | 复杂推理（旅行规划、数据分析） | 2~5 次 | ~2s | Markdown + scripts/ |
| **Python** | 自定义逻辑 | 自定义 | 自定义 | 继承 Skill 基类 |

### Rule 模式 — 关键词回复

```markdown
---
name: greeting
type: skill
description: 问候回复
triggers:
  - 你好
  - 早上好
rules:
  - pattern: 你好
    response: "你好！有什么可以帮你的吗？"
  - pattern: 早上好
    response: "早上好！新的一天加油"
default: "收到消息"
---
```

### CRUD 模式 — 数据管理

```markdown
---
name: todo
type: skill
label: 待办事项
description: 待办事项管理。触发词: 待办、任务
fields:
  - title
  - priority
  - due_date
display_format: "{title}（{priority}，截止 {due_date}）"
---
```

```python
result = await sm.execute("todo", {"action": "create", "title": "买牛奶", "priority": "高"})
result = await sm.execute("todo", {"action": "query"})
```

### Dispatch 模式 — 结构化操作

配置驱动 + `scripts/` 下的工具脚本，主 Agent LLM 负责提取参数，Skill 只做执行器：

```markdown
---
name: local_reminder
type: skill
dispatch: reminder_store
description: 本地提醒管理。触发词: 提醒、闹钟
tools:
  - reminder_store
---
```

### Python Skill — 自定义逻辑

```python
from skillify import Skill, SkillContext, SkillResult, ResultStatus

class WeatherSkill(Skill):
    def name(self) -> str:       return "weather"
    def description(self) -> str: return "查询天气。触发词: 天气"
    def triggers(self) -> list[str]: return ["天气", "气温"]
    def parameters_schema(self) -> dict: return {
        "type": "object",
        "properties": {"city": {"type": "string", "description": "城市名"}},
        "required": ["city"],
    }
    async def execute(self, params: dict, context: SkillContext) -> SkillResult:
        return SkillResult(status=ResultStatus.SUCCESS, reply=f"{params['city']}今天晴，25°C")

# 注册
sm.register_skill(WeatherSkill())
```

## 存储系统

一行代码切换存储后端：

```python
from skillify.io.storage import create_storage, StorageType, set_default_factory

# 内存（默认）
sm = SkillManager(skill_dirs=["./skills"])

# SQLite
set_default_factory(lambda name: create_storage(StorageType.SQLITE, prefix=name))
sm = SkillManager(skill_dirs=["./skills"])

# 自定义存储后端 — 实现 StorageBackend 接口即可
class MyStorage(StorageBackend):
    async def create(self, item: dict) -> dict: ...
    async def query(self, filters: dict | None = None) -> list[dict]: ...
    async def get(self, item_id: str) -> dict | None: ...
    async def delete(self, item_id: str) -> dict | None: ...
    async def update(self, item_id: str, updates: dict) -> dict | None: ...
```

## 校验框架

内置 9 条校验规则（pre/post 两阶段），可扩展：

```python
from skillify.core.harness import ValidationRule, ValidationResult

class SensitiveWordRule(ValidationRule):
    @property
    def name(self) -> str: return "sensitive_word"

    def validate(self, skill, params, result, context) -> ValidationResult:
        vr = ValidationResult(passed=True)
        if result and "违禁词" in result.reply:
            vr.add_issue(self.name, Severity.ERROR, "回复包含敏感词", "reply")
        return vr

sm.harness.add_rule(SensitiveWordRule())
```

## 更多文档

- [SDK 使用指南](docs/sdk_usage.md) — 完整 API 参考、配置格式、Skill 类型详解

## 项目结构

```
skillify/
├── src/skillify/
│   ├── core/          # 核心引擎：匹配、执行、校验、注册
│   ├── io/            # 存储、加载器
│   ├── models/        # 数据模型（schemas）
│   ├── skills/        # Skill 基类、配置驱动 Skill、Subagent
│   └── tools/         # 内置工具
├── skills/            # Skill 配置 + 脚本（示例）
├── tests/             # 测试用例
├── docs/              # 文档
└── scripts/           # 构建脚本
```

## License

[MIT](LICENSE)
