diff --git a/packages/docs/content/skills.en.md b/packages/docs/content/skills.en.md index 68e5e57..ea65a0c 100644 --- a/packages/docs/content/skills.en.md +++ b/packages/docs/content/skills.en.md @@ -65,6 +65,9 @@ The built-in Skills, by group (the group manifest is `SKILL_GROUPS` in `packages | AI App Development | `penguin-sdk` | Build AI and RAG apps on the SDK: the createSession/run streaming loop plus a complete retrieval recipe with chunk-revealing citations | | | `penguin-cli` | Manage model API keys, default models and per-agent Vault secrets with the penguin CLI | | | `agenthub-models` | Call model APIs through `@prismshadow/agenthub`: streaming text, image generation, speech synthesis and embeddings | +| | `vllm` | Deploy and serve LLMs with vLLM behind an OpenAI-compatible endpoint, with tool calling enabled for agent workloads | +| | `ollama` | Deploy and serve local models with Ollama: pull and run them, then expose the OpenAI-compatible endpoint to apps and agents | +| | `llamafactory` | Fine-tune LLMs with LlamaFactory: register datasets, train via YAML configs, merge LoRA adapters and serve the result | | Agent Tuning | `agent-creation` | Turn a user requirement into a concrete agent: write the target agent's AGENTS.md and install the skills it needs | | | `benchmark-design` | Design and calibrate a multi-Case capability Benchmark with repeated independent evaluations and a traceable baseline | | | `agent-evaluation` | Run and score exactly one Benchmark Case run, with CLI execution, Trace provenance checks and private Rubric isolation | diff --git a/packages/docs/content/skills.zh.md b/packages/docs/content/skills.zh.md index 0c82aec..af430d6 100644 --- a/packages/docs/content/skills.zh.md +++ b/packages/docs/content/skills.zh.md @@ -65,6 +65,9 @@ Skill 库以 npm 包 `@prismshadow/penguin-skills` 发布,tarball 直接携带 | AI 应用开发 | `penguin-sdk` | 基于 SDK 构建 AI 与 RAG 应用:createSession/run 流式循环,外加带可溯源引用的完整检索配方 | | | `penguin-cli` | 用 penguin CLI 管理模型 API Key、默认模型与各 Agent 的 Vault 密钥 | | | `agenthub-models` | 经 `@prismshadow/agenthub` 调用模型 API:流式文本、图像生成、语音合成与 Embedding | +| | `vllm` | 用 vLLM 部署与服务 LLM,提供 OpenAI 兼容端点,并为 Agent 负载启用工具调用 | +| | `ollama` | 用 Ollama 部署与运行本地模型,把 OpenAI 兼容端点接入应用与 Agent | +| | `llamafactory` | 用 LlamaFactory 微调 LLM:注册数据集、以 YAML 配置训练、合并 LoRA 适配器并部署产物 | | Agent 调优 | `agent-creation` | 把用户需求变成具体的 Agent:撰写目标 Agent 的 AGENTS.md 并安装所需 Skill | | | `benchmark-design` | 设计并校准多 Case 的能力评测 Benchmark,含重复独立评测与可追溯基线 | | | `agent-evaluation` | 隔离执行并评分单个 Benchmark Case:CLI 执行、Trace 溯源检查、Rubric 私有隔离 | diff --git a/packages/server/test/skills.test.ts b/packages/server/test/skills.test.ts index 5cecf23..7e1327e 100644 --- a/packages/server/test/skills.test.ts +++ b/packages/server/test/skills.test.ts @@ -79,6 +79,9 @@ describe("skills api", () => { "penguin-sdk", "penguin-cli", "agenthub-models", + "vllm", + "ollama", + "llamafactory", ]); expect(body.groups[3]!.skills.map((s) => s.name)).toEqual([ "agent-creation", diff --git a/packages/skills/README.md b/packages/skills/README.md index aae9277..c8a877f 100644 --- a/packages/skills/README.md +++ b/packages/skills/README.md @@ -10,7 +10,7 @@ Included skills, in the order of the `SKILL_GROUPS` manifest in `src/index.ts` ( | --- | --- | | Office Productivity | `data-analysis`, `firecrawl` | | Software Development | `web-design`, `software-engineering` | -| AI App Development | `penguin-sdk`, `penguin-cli`, `agenthub-models` | +| AI App Development | `penguin-sdk`, `penguin-cli`, `agenthub-models`, `vllm`, `ollama`, `llamafactory` | | Agent Tuning | `agent-creation`, `benchmark-design`, `agent-evaluation`, `agent-optimization` | Agent Tuning powers the self-improvement loop: create the Target Agent, design a Benchmark, evaluate it, optimize it to version N+1 with a snapshot before every round. diff --git a/packages/skills/skills/llamafactory/SKILL.md b/packages/skills/skills/llamafactory/SKILL.md new file mode 100644 index 0000000..5469aaa --- /dev/null +++ b/packages/skills/skills/llamafactory/SKILL.md @@ -0,0 +1,105 @@ +--- +name: llamafactory +description: Fine-tune LLMs with LlamaFactory — register datasets, train via YAML configs, merge LoRA adapters and serve the result. +short_description: Fine-tune models with LlamaFactory. +short_description_zh: 用 LlamaFactory 微调模型。 +version: 1 +updated: 2026-07-22T00:00:00Z +--- + +# LlamaFactory Fine-Tuning + +LlamaFactory fine-tunes open-weight LLMs (LoRA/QLoRA and full-parameter; SFT, DPO and more) through the `llamafactory-cli` command driven by YAML configs. + +## Before you start + +If the user's message only invokes this skill (e.g. "use llamafactory skill") without a concrete request, ask the user what they want to fine-tune. Do not run any command until the goal is clear. + +Confirm before training: + +- GPU memory (`nvidia-smi`) — it bounds the model size and method; LoRA needs far less than full fine-tuning. +- The base model: a Hugging Face id or a local path. +- The dataset: where it lives and which format it is in. +- The goal: SFT with LoRA is the usual starting point. + +## Install + +```bash +git clone --depth 1 https://github.com/hiyouga/LlamaFactory.git +cd LlamaFactory +pip install -e . +pip install -r requirements/metrics.txt # optional: evaluation metrics +``` + +## Data + +Register every dataset in `data/dataset_info.json`; the alpaca and sharegpt formats are supported. A minimal local entry: + +```json +"my_dataset": { "file_name": "my_dataset.json" } +``` + +alpaca rows carry `instruction` / `input` / `output`; sharegpt rows carry a `conversations` list. Put the data file under `data/` next to the registry. + +## Train + +Training is driven by a YAML config. Start from the shipped example `examples/train_lora/qwen3_lora_sft.yaml`, or save a minimal config as `my_sft.yaml`, e.g. for [Qwen/Qwen3-1.7B](https://huggingface.co/Qwen/Qwen3-1.7B): + +```yaml +model_name_or_path: Qwen/Qwen3-1.7B +trust_remote_code: true +stage: sft +do_train: true +finetuning_type: lora +lora_rank: 8 +lora_target: all +dataset: my_dataset +template: qwen3 +output_dir: saves/qwen3-1.7b/lora/sft +learning_rate: 1.0e-4 +num_train_epochs: 3.0 +bf16: true +``` + +```bash +llamafactory-cli train my_sft.yaml +``` + +`llamafactory-cli webui` launches the no-code web UI for the same workflow. + +## Merge and export + +Merge the LoRA adapter into the base weights for standalone serving. Start from `examples/merge_lora/qwen3_lora_sft.yaml`, pointing `model_name_or_path`, `adapter_name_or_path` and `template` at your run (never merge into a quantized base): + +```yaml +model_name_or_path: Qwen/Qwen3-1.7B +adapter_name_or_path: saves/qwen3-1.7b/lora/sft +template: qwen3 +trust_remote_code: true +export_dir: saves/qwen3-1.7b-sft-merged +``` + +```bash +llamafactory-cli export my_merge.yaml +``` + +## Try the result + +Both commands take an inference config — derive it from `examples/inference/qwen3_lora_sft.yaml`, again pointing the model, adapter and template at your run: + +```yaml +model_name_or_path: Qwen/Qwen3-1.7B +adapter_name_or_path: saves/qwen3-1.7b/lora/sft +template: qwen3 +infer_backend: huggingface +trust_remote_code: true +``` + +```bash +llamafactory-cli chat my_infer.yaml # interactive chat with the tuned model +llamafactory-cli api my_infer.yaml # OpenAI-compatible API server +``` + +## Close the loop + +Serve the merged export as a standalone endpoint — vLLM serves the export directory directly, while Ollama needs an import first (a `Modelfile` with `FROM /path/to/export`, then `ollama create`; supported model architectures only) — then register the endpoint with PenguinHarness so agents can build, evaluate and tune AI apps on the fine-tuned model end to end. diff --git a/packages/skills/skills/llamafactory/icon.svg b/packages/skills/skills/llamafactory/icon.svg new file mode 100644 index 0000000..a9a5581 --- /dev/null +++ b/packages/skills/skills/llamafactory/icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/skills/skills/ollama/SKILL.md b/packages/skills/skills/ollama/SKILL.md new file mode 100644 index 0000000..e4dac8e --- /dev/null +++ b/packages/skills/skills/ollama/SKILL.md @@ -0,0 +1,91 @@ +--- +name: ollama +description: Deploy and serve local models with Ollama — pull and run them, then expose the OpenAI-compatible endpoint to apps and agents. +short_description: Run local models with Ollama. +short_description_zh: 用 Ollama 运行本地模型。 +version: 1 +updated: 2026-07-22T00:00:00Z +--- + +# Ollama Serving + +Ollama runs open-weight models locally with automatic GPU detection and an OpenAI-compatible API on `http://localhost:11434`. + +## Before you start + +If the user's message only invokes this skill (e.g. "use ollama skill") without a concrete request, ask the user what they want. Do not run any command until the goal is clear. + +Ask the user which model to run; if they have no preference, recommend the small default [Qwen/Qwen3.5-0.8B](https://huggingface.co/Qwen/Qwen3.5-0.8B) (`ollama pull qwen3.5:0.8b`). The model must fit the machine's RAM/VRAM. + +Ollama runs everywhere — macOS, Linux and Windows, on CPUs as well as NVIDIA/AMD GPUs — so engine choice follows the user's preference: Ollama is the simple default, while vLLM targets high-throughput GPU serving. Check the current state first: + +```bash +ollama --version # is Ollama installed? +ollama ps # is the service already serving models? +``` + +If port 11434 is already serving, reuse that instance — never kill an existing Ollama process. + +## Suggested workflow + +1. Ask the user which model to run; with no preference, recommend [Qwen/Qwen3.5-0.8B](https://huggingface.co/Qwen/Qwen3.5-0.8B) (`qwen3.5:0.8b`). +2. Pick the engine the user prefers: Ollama is the default; vLLM covers high-throughput GPU serving. +3. Install Ollama if missing, then `ollama pull qwen3.5:0.8b`. +4. Verify with `curl http://localhost:11434/v1/models`. +5. Register the endpoint: `penguin config model add ... --client-type openai --base-url http://localhost:11434/v1` — a pulled Ollama model is not visible to Penguin until added. +6. Confirm the new entry with `penguin config model list`. + +## Install + +```bash +curl -fsSL https://ollama.com/install.sh | sh # Linux; macOS/Windows use the desktop app +``` + +The service then listens on `http://localhost:11434`. + +## Pull and run + +```bash +ollama pull qwen3.5:0.8b # download a model +ollama run qwen3.5:0.8b # interactive chat (pulls first if missing) +ollama list # downloaded models +ollama ps # models loaded in memory +ollama stop qwen3.5:0.8b # unload a model +``` + +## OpenAI-compatible endpoint + +The endpoint is `http://localhost:11434/v1`; any non-empty API key is accepted (conventionally `ollama`): + +```bash +curl http://localhost:11434/v1/models +``` + +## Context length + +The default context window is small, and agent sessions need a large one. Raise it in the server's environment: + +```bash +OLLAMA_CONTEXT_LENGTH=32768 ollama serve # systemd service: set it via `systemctl edit ollama` +``` + +Or bake it into a model variant with a Modelfile: + +``` +FROM qwen3.5:0.8b +PARAMETER num_ctx 32768 +``` + +```bash +ollama create qwen3.5-32k -f Modelfile +``` + +## Register with PenguinHarness + +Model configuration is the penguin CLI's job — `penguin config model add` registers an endpoint and `penguin config model list` shows what has been registered. A pulled Ollama model is not visible to Penguin until you add it: + +```bash +penguin config model add --provider custom --client-type openai \ + --base-url http://localhost:11434/v1 --model-id qwen3.5:0.8b --api-key ollama +penguin config model list # the new entry should now be listed +``` diff --git a/packages/skills/skills/ollama/icon.svg b/packages/skills/skills/ollama/icon.svg new file mode 100644 index 0000000..bdaa5b9 --- /dev/null +++ b/packages/skills/skills/ollama/icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/packages/skills/skills/penguin-cli/SKILL.md b/packages/skills/skills/penguin-cli/SKILL.md index 8d04a40..6a536a4 100644 --- a/packages/skills/skills/penguin-cli/SKILL.md +++ b/packages/skills/skills/penguin-cli/SKILL.md @@ -3,13 +3,13 @@ name: penguin-cli description: Manage model API keys, default models and per-agent vault secrets with the penguin CLI. short_description: Manage models and secrets with the penguin CLI. short_description_zh: 用 penguin CLI 管理模型与密钥。 -version: 3 -updated: 2026-07-21T00:00:00Z +version: 4 +updated: 2026-07-22T00:00:00Z --- # Penguin CLI -The `penguin` CLI manages model credentials, default models and per-agent vault secrets. Configuration goes through the CLI only — never read or hand-edit the underlying hidden files. +The `penguin` CLI manages model credentials, default models and per-agent vault secrets. Its primary job is model configuration: `penguin config model add` registers a model and `penguin config model list` shows the models currently available. Configuration goes through the CLI only — never read or hand-edit the underlying hidden files. ## Before you start @@ -30,7 +30,10 @@ penguin config model add --provider --model-id [--api-key - For any OpenAI chat-completion compatible endpoint use `--client-type openai --base-url `; omit `--client-type` to auto-route by model id. - Prices are USD per million tokens (cache read / cache write / output). - `--vision` / `--no-vision` mark whether the model accepts images; omitting both keeps the current value (default is vision-capable). -- All `penguin config model ...` and `penguin config vault ...` commands accept `--root ` to target another data root (default `PENGUIN_HOME`, then `~/.penguin/data`). **When configuring models for an AI app you are building, always pass `--root ` pointing at the app's own data directory inside the current working directory** (e.g. `--root ./penguin_data`, the same path the app gives `createAgent({ root })`); running without `--root` writes to the global `~/.penguin/data`, which belongs to the person running Penguin — not to the app. +- All `penguin config model ...` and `penguin config vault ...` commands accept `--root ` to target another data root (default `PENGUIN_HOME`, then `~/.penguin/data`). Two configuration targets — treat the difference as a hard rule: + - **Penguin's own model** (self-configuration: the model Penguin itself runs on): the default root without `--root` is correct. + - **An AI app you are building**: `--root` **must** point at the app's own data directory inside the project (e.g. `--root ./penguin_data`, the same path the app gives `createAgent({ root })`) unless the user explicitly chose another location — never write an app's models or keys into the global `~/.penguin/data`, which belongs to the person running Penguin, not to the app. + - While developing an app, review regularly: `penguin config model list --root ` should show the app's entries, and the global list (no `--root`) should stay clean. Other model commands: diff --git a/packages/skills/skills/vllm/SKILL.md b/packages/skills/skills/vllm/SKILL.md new file mode 100644 index 0000000..cbd3679 --- /dev/null +++ b/packages/skills/skills/vllm/SKILL.md @@ -0,0 +1,94 @@ +--- +name: vllm +description: Deploy and serve LLMs with vLLM behind an OpenAI-compatible endpoint, with tool calling enabled for agent workloads. +short_description: Serve models locally with vLLM. +short_description_zh: 用 vLLM 部署本地模型服务。 +version: 1 +updated: 2026-07-22T00:00:00Z +--- + +# vLLM Serving + +vLLM serves open-weight LLMs on local GPUs with high-throughput inference behind an OpenAI-compatible API, ready for chat and agent workloads. + +## Before you start + +If the user's message only invokes this skill (e.g. "use vllm skill") without a concrete request, ask the user what they want. Do not run any command until the goal is clear. + +Ask the user which model to serve; if they have no preference, recommend the small default [Qwen/Qwen3.5-0.8B](https://huggingface.co/Qwen/Qwen3.5-0.8B). Also ask what context length the workload needs. + +vLLM needs an NVIDIA or AMD GPU. Engine choice follows the user's preference: Ollama also runs on GPUs and is the simpler default — pick vLLM for high-throughput serving, and Ollama on macOS or CPU-only machines, which vLLM does not serve. Confirm the hardware first: + +```bash +nvidia-smi # NVIDIA: GPU model and free VRAM (AMD ROCm: rocm-smi) +python3 --version # a recent Python is required +``` + +The model must fit the available VRAM — model size and context length drive the serve flags below. + +## Suggested workflow + +1. Ask the user which model to serve; with no preference, recommend [Qwen/Qwen3.5-0.8B](https://huggingface.co/Qwen/Qwen3.5-0.8B). +2. Pick the engine the user prefers: vLLM for high-throughput GPU serving; Ollama is the simple default and the choice on macOS or CPU-only machines. +3. Serve on a free port, with the tool-calling flags whenever agents will call it (see below). +4. Verify with `curl http://localhost:8000/v1/models`. +5. Register the endpoint: `penguin config model add ... --client-type openai --base-url http://localhost:8000/v1` — a served model is not visible to Penguin until added. +6. Confirm the new entry with `penguin config model list`. + +## Install + +Use a fresh virtual environment (or `uv`): + +```bash +python3 -m venv .venv && source .venv/bin/activate +pip install vllm +``` + +## Serve + +```bash +vllm serve Qwen/Qwen3.5-0.8B --port 8000 +``` + +This exposes an OpenAI-compatible API at `http://localhost:8000/v1`. Key flags: + +- `--served-model-name ` — the model id clients request (defaults to the model path). +- `--api-key ` — require this bearer token on every request. +- `--max-model-len ` — context window; agent sessions need a large one. +- `--gpu-memory-utilization <0..1>` — fraction of VRAM to claim (default 0.9). +- `--tensor-parallel-size ` — shard across `n` GPUs. +- `--dtype ` and `--quantization ` — precision and quantized weights. + +If the port is taken, pick a free one — never kill a process already listening on it. + +## Tool calling — required for agents + +Agent harnesses (PenguinHarness included) send `tools` with their requests. vLLM must opt in at startup: + +```bash +vllm serve Qwen/Qwen3.5-0.8B --enable-auto-tool-choice --tool-call-parser hermes +``` + +Choose the parser for the model family — e.g. `hermes` for Qwen models, `llama3_json` for Llama models. Without these flags, requests that set tool_choice fail with `400 "auto" tool choice requires --enable-auto-tool-choice and --tool-call-parser to be set`. + +## Verify + +```bash +curl http://localhost:8000/v1/models +``` + +## Register with PenguinHarness + +Model configuration is the penguin CLI's job — `penguin config model add` registers an endpoint and `penguin config model list` shows what has been registered. A served model is not visible to Penguin until you add it: + +```bash +penguin config model add --provider custom --client-type openai \ + --base-url http://localhost:8000/v1 --model-id --api-key +penguin config model list # the new entry should now be listed +``` + +## Troubleshooting + +- Out of memory at startup: lower `--gpu-memory-utilization` or `--max-model-len`, or serve a quantized model. +- Long prompts truncated or context-length errors: raise `--max-model-len` (bounded by VRAM). +- `400` on tool calls: restart the server with the tool-calling flags above. diff --git a/packages/skills/skills/vllm/icon.svg b/packages/skills/skills/vllm/icon.svg new file mode 100644 index 0000000..c6c89b9 --- /dev/null +++ b/packages/skills/skills/vllm/icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/skills/src/index.ts b/packages/skills/src/index.ts index 38724a4..2c1f0c9 100644 --- a/packages/skills/src/index.ts +++ b/packages/skills/src/index.ts @@ -154,7 +154,7 @@ export const SKILL_GROUPS: SkillGroupInfo[] = [ id: "ai-app-development", title: "AI App Development", titleZh: "AI 应用开发", - skills: ["penguin-sdk", "penguin-cli", "agenthub-models"], + skills: ["penguin-sdk", "penguin-cli", "agenthub-models", "vllm", "ollama", "llamafactory"], }, { id: "agent-tuning", diff --git a/packages/skills/test/skills.test.ts b/packages/skills/test/skills.test.ts index b2e8933..b584544 100644 --- a/packages/skills/test/skills.test.ts +++ b/packages/skills/test/skills.test.ts @@ -104,6 +104,9 @@ describe("loadSkillGroups / groupSkills", () => { "penguin-sdk", "penguin-cli", "agenthub-models", + "vllm", + "ollama", + "llamafactory", ]); expect(groups[2]!.title).toBe("AI App Development"); expect(groups[2]!.titleZh).toBe("AI 应用开发"); @@ -159,7 +162,7 @@ describe("loadSkillGroups / groupSkills", () => { { id: "software-development", skills: ["web-design", "software-engineering"] }, { id: "ai-app-development", - skills: ["penguin-sdk", "penguin-cli", "agenthub-models"], + skills: ["penguin-sdk", "penguin-cli", "agenthub-models", "vllm", "ollama", "llamafactory"], }, { id: "agent-tuning",