318 lines
8.6 KiB
Markdown
318 lines
8.6 KiB
Markdown
Oto przykładowy plik SKILL.md dla skilla GEO w formacie zgodnym z AgentSkills i OpenClaw:
|
||
|
||
````yaml
|
||
---
|
||
name: geo-optimizer
|
||
description: Audyt i optymalizacja treści technicznych pod kątem Generative Engine Optimization (GEO)
|
||
homepage: https://geo-skill.docs.example.com
|
||
user-invocable: true
|
||
disable-model-invocation: false
|
||
command-dispatch: tool
|
||
command-tool: geo-audit
|
||
command-arg-mode: raw
|
||
metadata:
|
||
openclaw:
|
||
requires:
|
||
bins: ["node", "python3"]
|
||
env: ["GEO_OPENAI_KEY"]
|
||
config: ["geo.enabled"]
|
||
primaryEnv: GEO_OPENAI_KEY
|
||
---
|
||
# GEO Optimizer Skill
|
||
|
||
Ten skill analizuje i optymalizuje treści techniczne (np. dokumentacje API, artykuły inżynierskie, poradniki) pod kątem **Generative Engine Optimization (GEO)** – czyli zwiększenia szansy na cytowanie przez systemy AI (ChatGPT, Perplexity, Google SGE itp.).
|
||
|
||
## Jak używać
|
||
|
||
Aby uruchomić skill ręcznie:
|
||
|
||
```bash
|
||
/geo-optimize <ścieżka_do_pliku.md>
|
||
````
|
||
|
||
Skill wykona:
|
||
|
||
1. Analizę struktury dokumentu (nagłówki, listy, kod, FAQ).
|
||
2. Ocenę zgodności z checklistą GEO.
|
||
3. Wygeneruje raport z rekomendacjami GEO.
|
||
4. (Opcjonalnie) zaproponuje poprawki: Quick Answer, schema.org JSON-LD, FAQ.
|
||
5. (Opcjonalnie) zastosuje poprawki automatycznie (jeśli `--apply`).
|
||
|
||
## Przykład użycia
|
||
|
||
```bash
|
||
/geo-optimize docs/architektura-baz-danych.md
|
||
```
|
||
|
||
## Parametry
|
||
|
||
* `--apply`: automatycznie zastosuj poprawki (jeśli możliwe).
|
||
* `--report-only`: wygeneruj tylko raport (domyślnie).
|
||
* `--format=json|markdown`: format raportu (domyślnie: markdown).
|
||
* `--lang=pl|en`: język raportu (domyślnie: pl).
|
||
|
||
## Wymagania
|
||
|
||
* Node.js i Python 3 (do przetwarzania treści i generowania JSON-LD).
|
||
* Klucz API OpenAI (`GEO_OPENAI_KEY`) – do generowania propozycji Quick Answer, FAQ, rewritingu.
|
||
* Konfiguracja `geo.enabled: true` w `openclaw.json`.
|
||
|
||
## Bezpieczeństwo
|
||
|
||
* Skill działa w sandboxie.
|
||
* Nie wysyła danych poufnych do zewnętrznych API.
|
||
* Wspiera tryb dry-run i loguje wszystkie działania.
|
||
|
||
## Autorzy
|
||
|
||
Zespół Inżynierii Dokumentacji i AI
|
||
|
||
```
|
||
|
||
Jeśli chcesz, mogę również przygotować plik `geo-audit.js` lub `geo-audit.py`, który będzie implementował logikę działania skilla zgodnie z opisanym wcześniej planem. Czy chcesz, abym przygotował taki kod?
|
||
```
|
||
Oto przykładowy plik geo-audit.js – implementacja skilla GEO dla OpenClaw w Node.js. Skrypt analizuje dokument Markdown lub HTML pod kątem zgodności z najlepszymi praktykami GEO i generuje raport z rekomendacjami.
|
||
|
||
📁 Plik: geo-audit.js
|
||
|
||
```js
|
||
#!/usr/bin/env node
|
||
|
||
/**
|
||
* GEO Optimizer Skill – geo-audit.js
|
||
* Audyt treści technicznych pod kątem Generative Engine Optimization (GEO)
|
||
* Autor: Zespół Inżynierii Dokumentacji i AI
|
||
*/
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
const { JSDOM } = require('jsdom');
|
||
const { marked } = require('marked');
|
||
const { Configuration, OpenAIApi } = require('openai');
|
||
|
||
// Konfiguracja środowiska
|
||
const OPENAI_KEY = process.env.GEO_OPENAI_KEY;
|
||
const openai = OPENAI_KEY
|
||
? new OpenAIApi(new Configuration({ apiKey: OPENAI_KEY }))
|
||
: null;
|
||
|
||
// Pomocnicze funkcje
|
||
function isQuestion(text) {
|
||
return /\?$/.test(text.trim());
|
||
}
|
||
|
||
function extractQuickAnswer(html) {
|
||
const dom = new JSDOM(html);
|
||
const firstParagraph = dom.window.document.querySelector('p');
|
||
return firstParagraph ? firstParagraph.textContent.trim() : null;
|
||
}
|
||
|
||
function extractHeadings(html) {
|
||
const dom = new JSDOM(html);
|
||
const headings = [...dom.window.document.querySelectorAll('h1, h2, h3')];
|
||
return headings.map(h => ({
|
||
level: h.tagName,
|
||
text: h.textContent.trim(),
|
||
isQuestion: isQuestion(h.textContent),
|
||
}));
|
||
}
|
||
|
||
function extractLists(html) {
|
||
const dom = new JSDOM(html);
|
||
const lists = [...dom.window.document.querySelectorAll('ul, ol')];
|
||
return lists.length;
|
||
}
|
||
|
||
function extractCodeBlocks(html) {
|
||
const dom = new JSDOM(html);
|
||
return [...dom.window.document.querySelectorAll('pre code')].length;
|
||
}
|
||
|
||
function extractFAQ(html) {
|
||
const dom = new JSDOM(html);
|
||
const faqs = [...dom.window.document.querySelectorAll('h2, h3')]
|
||
.filter(h => /faq|najczęściej zadawane/i.test(h.textContent));
|
||
return faqs.length;
|
||
}
|
||
|
||
async function generateQuickAnswer(text) {
|
||
if (!openai) return null;
|
||
const prompt = `Streszcz poniższy tekst w 2-3 zdaniach jako odpowiedź na pytanie:\n\n${text}`;
|
||
const res = await openai.createChatCompletion({
|
||
model: 'gpt-4',
|
||
messages: [{ role: 'user', content: prompt }],
|
||
temperature: 0.5,
|
||
});
|
||
return res.data.choices[0].message.content.trim();
|
||
}
|
||
|
||
// Główna funkcja audytu
|
||
async function audit(filePath) {
|
||
const raw = fs.readFileSync(filePath, 'utf-8');
|
||
const html = marked.parse(raw);
|
||
|
||
const headings = extractHeadings(html);
|
||
const quickAnswer = extractQuickAnswer(html);
|
||
const lists = extractLists(html);
|
||
const codeBlocks = extractCodeBlocks(html);
|
||
const faqCount = extractFAQ(html);
|
||
|
||
const report = [];
|
||
|
||
// Tytuł jako pytanie
|
||
if (!headings[0]?.isQuestion) {
|
||
report.push(`🔶 Tytuł (H1) nie jest pytaniem: "${headings[0]?.text}"`);
|
||
}
|
||
|
||
// Quick Answer
|
||
if (!quickAnswer || quickAnswer.length > 300) {
|
||
const suggestion = await generateQuickAnswer(raw.slice(0, 1000));
|
||
report.push(`🔶 Brak lub zbyt długi Quick Answer. Propozycja:\n> ${suggestion}`);
|
||
}
|
||
|
||
// Listy
|
||
if (lists < 1) {
|
||
report.push('🔶 Brak list punktowanych lub numerowanych – rozważ dodanie.');
|
||
}
|
||
|
||
// Kod
|
||
if (codeBlocks < 1) {
|
||
report.push('🔶 Brak przykładów kodu – rozważ dodanie fragmentów kodu.');
|
||
}
|
||
|
||
// FAQ
|
||
if (faqCount < 1) {
|
||
report.push('🔶 Brak sekcji FAQ – rozważ dodanie najczęstszych pytań i odpowiedzi.');
|
||
}
|
||
|
||
// Podsumowanie
|
||
console.log(`📄 Audyt GEO: ${path.basename(filePath)}\n`);
|
||
if (report.length === 0) {
|
||
console.log('✅ Treść spełnia większość zaleceń GEO. Świetna robota!');
|
||
} else {
|
||
report.forEach(r => console.log(r));
|
||
}
|
||
}
|
||
|
||
// Uruchomienie
|
||
const args = process.argv.slice(2);
|
||
if (!args[0]) {
|
||
console.error('❌ Podaj ścieżkę do pliku Markdown jako argument.');
|
||
process.exit(1);
|
||
}
|
||
|
||
audit(args[0]);
|
||
```
|
||
|
||
📦 Wymagania:
|
||
|
||
* Node.js
|
||
* Zainstalowane pakiety: `jsdom`, `marked`, `openai`
|
||
* Klucz API OpenAI w zmiennej środowiskowej `GEO_OPENAI_KEY` (opcjonalnie)
|
||
|
||
🛠 Instalacja zależności:
|
||
|
||
```bash
|
||
npm install jsdom marked openai
|
||
```
|
||
|
||
Czy chcesz, abym przygotował również wersję tego skilla w Pythonie lub dodał obsługę JSON-LD schema.org?
|
||
Aby uruchomić skrypt geo-audit.js i przeprowadzić audyt treści technicznej pod kątem Generative Engine Optimization (GEO), wykonaj poniższe kroki:
|
||
|
||
***
|
||
|
||
## ✅ Krok po kroku: Jak uruchomić geo-audit.js
|
||
|
||
### 1. Zainstaluj Node.js (jeśli jeszcze nie masz)
|
||
|
||
Jeśli nie masz Node.js, pobierz i zainstaluj go ze strony:
|
||
👉 <https://nodejs.org/>
|
||
|
||
Po instalacji sprawdź wersję:
|
||
|
||
```bash
|
||
node -v
|
||
```
|
||
|
||
***
|
||
|
||
### 2. Przygotuj katalog skilla
|
||
|
||
Utwórz folder na skill GEO, np.:
|
||
|
||
```bash
|
||
mkdir geo-skill
|
||
cd geo-skill
|
||
```
|
||
|
||
W tym folderze umieść:
|
||
|
||
* plik `geo-audit.js` (zawartość podałem wcześniej),
|
||
* plik `SKILL.md` (zdefiniowany wcześniej),
|
||
* ewentualnie plik testowy `.md` do analizy (np. `przyklad.md`).
|
||
|
||
***
|
||
|
||
### 3. Zainstaluj zależności
|
||
|
||
W katalogu skilla zainstaluj wymagane biblioteki:
|
||
|
||
```bash
|
||
npm init -y
|
||
npm install jsdom marked openai
|
||
```
|
||
|
||
***
|
||
|
||
### 4. Ustaw klucz OpenAI (opcjonalnie)
|
||
|
||
Jeśli chcesz, aby skill generował propozycje Quick Answer lub FAQ, potrzebujesz klucza OpenAI.
|
||
|
||
Ustaw go jako zmienną środowiskową:
|
||
|
||
```bash
|
||
export GEO_OPENAI_KEY=sk-... # Twój klucz OpenAI
|
||
```
|
||
|
||
Możesz też dodać go do pliku `.env` i użyć biblioteki dotenv (jeśli chcesz, mogę dodać obsługę dotenv do skryptu).
|
||
|
||
***
|
||
|
||
### 5. Uruchom audyt
|
||
|
||
W katalogu skilla uruchom skrypt z podaniem ścieżki do pliku Markdown:
|
||
|
||
```bash
|
||
node geo-audit.js przyklad.md
|
||
```
|
||
|
||
📄 Wyniki audytu pojawią się w konsoli – będą zawierać rekomendacje GEO, np. brak Quick Answer, brak FAQ, zbyt długie akapity itp.
|
||
|
||
***
|
||
|
||
## 🔁 Przykład działania
|
||
|
||
```bash
|
||
node geo-audit.js docs/architektura-baz-danych.md
|
||
```
|
||
|
||
Wynik:
|
||
|
||
📄 Audyt GEO: architektura-baz-danych.md
|
||
|
||
🔶 Tytuł (H1) nie jest pytaniem: "Architektura baz danych w systemach rozproszonych"
|
||
🔶 Brak lub zbyt długi Quick Answer. Propozycja:
|
||
> Architektura baz danych w systemach rozproszonych to sposób organizacji danych, który zapewnia skalowalność i odporność na awarie...
|
||
🔶 Brak sekcji FAQ – rozważ dodanie najczęstszych pytań i odpowiedzi.
|
||
|
||
***
|
||
|
||
Jeśli chcesz, mogę też przygotować:
|
||
|
||
* wersję z automatycznym generowaniem JSON-LD schema.org,
|
||
* wersję z obsługą plików HTML,
|
||
* wersję w Pythonie.
|
||
|
||
Czy chcesz rozszerzyć ten skill o automatyczne poprawki lub integrację z repozytorium (np. generowanie pull requestów)?
|
||
|