Agar siz yarim tunda maqola parchasini shoshilinch ravishda meta tavsifga joylashtirgan bo'lsangiz, muammoni bilasiz: u takroriy, ko'pincha juda uzun va ba'zan mavzudan tashqariga chiqadi. Boshqa tomondan, avtomatik xulosa ishonchli bo'lishi mumkin... agar u to'g'ri ulangan bo'lsa WordPress 6.9.4, keshlash, himoya choralari va ochiq API kalitlarisiz.
Ehtiyoj / Foydalanish holati
Veb-sayt WordPress U kontent bilan gullab-yashnaydi. Lekin o'quvchi skanerlaydi. Qisqa va lo'nda xulosa (2-3 jumla) quyidagilarni yaxshilaydi:
- Kategoriya sahifalari (maqolalarning bir hil umumiy ko'rinishi).
- relizlar (qo'lda qayta yozmasdan tezkor tizerlar).
- "Tavsiya etilgan" sahifalar (sozlama (oldinga o'qish osonroq).
- Ko'p muallifli veb-saytlar : xulosaning bir xil uslubi, bir xil uzunlik.
Oxir-oqibat, sizda quyidagi tizim bo'ladi:
- maqola saqlanganda AI xulosasini yaratadi,
- uni saqlang huzur (WordPress ma'lumotlar bazasida)
- Ikki marta to'lamaslik uchun uni (Transients) keshlaydi.
- uni qisqa kod orqali ko'rsatadi (Divi 5, Elementor, Avada bilan mos keladi),
- saytingizni buzmasdan xatolarni (vaqtinchalik vaqt tugashi, kvota, noto'g'ri JSON) hal qiladi.
Tez xulosa
- Siz API kalitini saqlaysiz WP-config.php (hech qachon qattiq kodlanmagan).
- Un mu-plagin orqali xulosa yaratadi wp_remote_post() OpenAI API ga.
- Xulosa qayd etilgan post meta (
_ai_summary) va qayta ishlatilgan. - Un o'tkinchi Bu takroriy qo'ng'iroqlarning oldini oladi va xarajatlarni cheklaydi.
- Qisqa kod
[ai_summary]Divi 5 / Elementor / Avada ko'rsatish imkonini beradi. - Sizda nosozliklarni tuzatish rejimi, jurnallarni tozalash va diagnostika boshqaruv paneli mavjud.
Buning uchun qachon AI dan foydalanish kerak
Saytda ushbu cheklovlardan kamida bittasi mavjud bo'lganda, men ushbu turdagi avtomatik xulosani faollashtiraman:
- Ko'plab maqolalar (chuqur arxivlar, juda faol toifalar).
- Bir nechta muharrirlar va yagona formatga ehtiyoj.
- Uzoq kontent (qo'llanmalar, fayllar, tadqiqotlar) bu yerda inson shlyapasi ko'pincha unutiladi.
- Qayta ishlash : axborot byulleteni, push-bildirishnomalar, “eng yaxshi maqolalar” sahifalari.
Bu shuningdek, Divi 5, Elementor yoki Avada dan foydalanadigan saytlar uchun juda yaxshi ishlaydi: biz xulosani quruvchiga tegmasdan qisqa kod orqali namoyish qilamiz.
Qachon AI dan foydalanmaslik kerak
Agar mahalliy yechim yetarli bo'lsa, API uchun pul to'lamang. Odatdagi holatlar:
- Sizda allaqachon WordPress parchasi bor ("Ko'chirma" maydoni) va jamoangiz uni to'g'ri to'ldiradi.
- Maqolalaringiz qisqa (300–500 so'z): qisqartirilgan parcha yetarli bo'lishi mumkin.
- Sizda kuchli qonuniy cheklovlar mavjud (tibbiy/huquqiy mazmun): AI xulosasi "talqin qilishi" va xatolarga olib kelishi mumkin.
- Siz 100% deterministik xulosani xohlaysiz Sun'iy intellekt qat'iy parametrlar bilan ham farq qiladi.
Oddiy alternativa (sun'iy intellektsiz): parchani namoyish qilish yoki tarkibni qisqartirish orqali "xulosa" yaratish (masalan, wp_trim_words()Bu bepul, tezkor va ko'pincha yetarli.
qo'ymaydi
Versiyalar va muhit
- WordPress : 6.9.4 (2026-yil aprel) yoki undan keyingi versiyalari.
- PHP 8.1+ (tavsiya etiladi). Agar siz 7.x versiyasida bo'lsangiz, zamonaviy kodda halokatli xatolarga duch kelasiz.
- HTTPS sayt tomonida (juda tavsiya etiladi) administrator sessiyalarini oddiy matnda uzatmaslik uchun.
API: oddiy ta'rif (kod yozishdan oldin foydali)
mashxurlikka API (Ilova dasturlash interfeysi) - bu HTTP orqali kirish mumkin bo'lgan xizmat. Amalda, WordPress HTTP so'rovini (ko'pincha JSON formatida) URL manziliga yuboradi, xizmat JSON bilan javob beradi va sizning kodingiz bu javobni foydalanishga yaroqli matnga aylantiradi.
WordPressda bu HTTP API orqali to'g'ri bajariladi: wp_remote_post() et wp_remote_get()Rasmiy manba: HTTP API (developer.wordpress.org).
API kaliti va xotira (wp-config.php)
Sizga AI provayderidan API kaliti kerak. Bu yerda men OpenAI ni ko'rsatyapman, chunki API barqaror va yaxshi hujjatlashtirilgan, ammo Anthropic/Mistral/Google uchun tuzilma o'xshash bo'ladi.
- Kalit yarating: OpenAI API hujjatlari
Keyin, kalitni qo'shing WP-config.php (yuqorida “Bo‘ldi, tahrirlashni to‘xtating!” deyilgan). Uni hech qachon plaginga, hech qachon umumiy parchaga, hech qachon Git omboriga joylashtirmang.
define( 'BPCAB_OPENAI_API_KEY', 'sk-votre-cle-ici' );
Diqqat, xarajatlar: Har bir xulosa pullik chaqiruvdir. Siz buni keshlash va faqat ma'lum tadbirlar (nashr/yangilanish) davomida xulosa chiqarish bilan cheklaysiz.
Kodni qayerga joylashtirish kerak
Ushbu turdagi funksiyalar uchun men qochaman functions.php (mavzuni yangilash paytida sindirish juda oson). Ikkita ishonchli variant:
- mu-plagin (tavsiya etiladi): faylga
wp-content/mu-plugins/, avtomatik ravishda yuklanadi. - maxsus plagin : faylga
wp-content/plugins/, yoqilishi/o'chirilishi mumkin.
Men ketyapman mu-plaginchunki men saytlarning o'z parchalarini "yo'qotishini" ko'p ko'rganman. après mavzu o'zgarishi yoki o'chirilgan snippetlar plagini.
Yechim arxitekturasi
Oqim (matn sxemasi)
WordPress muharriri → maqolani saqlash → ilmoq save_post → Kontentni olish → Tekshiruvlar (turi, holati, avtomatik saqlash) → Vaqtinchalik kesh (ikki marta qo'ng'iroq qilishdan saqlanish) → wp_remote_post() → AI API → JSON tahlili → sanitariya → post meta saqlash _ai_summary → Qisqa kod orqali ko'rsatish.
Nima uchun bu dizayn?
- Meta-da saqlang : xulosa doimiy, indekslanadigan va har bir displeyda API chaqirmasdan qayta ishlatilishi mumkin.
- Vaqtinchalik : agar siz "Yangilash" tugmasini bir necha marta bossangiz yoki plagin bir nechta zaxira nusxalarini ishga tushirsa, bir nechta qo'ng'iroqlardan qochadi.
- shortcode : maxsus ishlab chiqmasdan Divi 5 / Elementor / Avada bilan mos keladi.
To'liq kod - bosqichma-bosqich
1-qadam — mu-plaginni yarating
Jildni yarating wp-content/mu-plugins/ Agar u mavjud bo'lmasa, fayl qo'shing:
wp-content/mu-plugins/ai-auto-summary.php
Quyidagi asosni yopishtiring:
<?php
/**
* Plugin Name: AI Auto Summary (mu-plugin)
* Description: Génère et stocke un résumé IA des articles WordPress.
* Version: 1.0.0
* Requires at least: 6.9
* Requires PHP: 8.1
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
2-qadam — Konstantalar va sozlamalarni aniqlang
Sozlamalar markazlashtirilgan: uzunlik, model, vaqt tugashi. Siz ularni butun mantiqni o'zgartirmasdan sozlashingiz mumkin.
const BPCAB_AI_SUMMARY_META_KEY = '_ai_summary';
const BPCAB_AI_SUMMARY_MODEL = 'gpt-4.1-mini'; // Modèle “mini” : bon compromis coût/qualité (à ajuster)
const BPCAB_AI_TIMEOUT_SECONDS = 20;
const BPCAB_AI_MAX_INPUT_CHARS = 12000; // Limite simple pour éviter d'envoyer des romans entiers
3-qadam — Generatsiya kancasini kerakli vaqtda qo'shing
Un qayrilma qoziq kengaytma nuqtasidir. A harakat kodni ma'lum bir vaqtda bajaradi (masalan, postni saqlash). A filtri qiymatni o'zgartiradi (masalan, namoyishdan oldingi tarkib). Bu yerda biz a dan foydalanamiz harakat : save_post.
Klassik tuzoq: foydalanish the_content Xulosa yaratish uchun AI har safar ko'rsatilganda ishga tushiriladi. Natija: API to'lovlari va veb-saytning sekin ishlashi. U renderlash paytida emas, balki saqlash vaqtida yaratiladi.
add_action( 'save_post', 'bpcab_ai_maybe_generate_summary', 20, 3 );
/**
* Déclenche la génération du résumé lors de l'enregistrement.
*
* @param int $post_id ID du post.
* @param WP_Post $post Objet post.
* @param bool $update True si mise à jour, false si création.
*/
function bpcab_ai_maybe_generate_summary( int $post_id, $post, bool $update ): void {
// 1) Éviter les autosaves/révisions (sinon vous payez pour rien)
if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
return;
}
// 2) Vérifier le type de contenu : ici, uniquement les articles
if ( $post->post_type !== 'post' ) {
return;
}
// 3) Générer seulement quand l'article est publié (ou en passe de l'être)
$status = get_post_status( $post_id );
if ( $status !== 'publish' ) {
return;
}
// 4) Si un résumé existe déjà, ne pas écraser (vous pourrez ajouter un bouton “Regénérer” plus tard)
$existing = get_post_meta( $post_id, BPCAB_AI_SUMMARY_META_KEY, true );
if ( is_string( $existing ) && $existing !== '' ) {
return;
}
// 5) Vérifier la présence de la clé API
if ( ! defined( 'BPCAB_OPENAI_API_KEY' ) || ! is_string( BPCAB_OPENAI_API_KEY ) || BPCAB_OPENAI_API_KEY === '' ) {
error_log( '[AI Summary] Clé API absente. Ajoutez BPCAB_OPENAI_API_KEY dans wp-config.php.' );
return;
}
$content = bpcab_ai_get_post_text_for_summary( $post_id );
if ( $content === '' ) {
return;
}
// 6) Anti double-facturation : transient de verrouillage pendant 10 minutes
$lock_key = 'bpcab_ai_summary_lock_' . $post_id;
if ( get_transient( $lock_key ) ) {
return;
}
set_transient( $lock_key, 1, 10 * MINUTE_IN_SECONDS );
$summary = bpcab_ai_generate_summary_via_openai( $content, get_the_title( $post_id ) );
// En cas d'échec, on libère le lock plus tôt (sinon il expire tout seul)
if ( $summary === '' ) {
delete_transient( $lock_key );
return;
}
// 7) Sanitation : on stocke du texte simple
$summary = sanitize_text_field( $summary );
update_post_meta( $post_id, BPCAB_AI_SUMMARY_META_KEY, $summary );
}
4-qadam — Maqoladan "toza" matnni ajratib oling
WordPress kontenti bloklar, HTML va qisqa kodlarni o'z ichiga olishi mumkin. Ushbu xom ashyoni AIga yuborish ko'pincha g'alati xulosalarga olib keladi (u maket parchalarini "umumlashtiradi". Biz uni tozalaymiz:
- qisqa kodlarni olib tashlash
- HTML teglarini olib tashlash,
- o'lcham chegarasi.
/**
* Récupère un texte propre à résumer (sans HTML/shortcodes).
*/
function bpcab_ai_get_post_text_for_summary( int $post_id ): string {
$post = get_post( $post_id );
if ( ! $post instanceof WP_Post ) {
return '';
}
$text = $post->post_content;
// Retirer les shortcodes (souvent présents avec Divi/Avada et certains builders)
$text = strip_shortcodes( $text );
// Retirer le HTML
$text = wp_strip_all_tags( $text );
// Normaliser les espaces
$text = preg_replace( '/s+/', ' ', $text );
$text = trim( (string) $text );
if ( $text === '' ) {
return '';
}
// Limiter la taille envoyée à l'API (simple et efficace)
if ( mb_strlen( $text ) > BPCAB_AI_MAX_INPUT_CHARS ) {
$text = mb_substr( $text, 0, BPCAB_AI_MAX_INPUT_CHARS );
}
return $text;
}
5-qadam — OpenAI API-ni wp_remote_post() yordamida chaqiring
Biz "Javoblar" so'nggi nuqtasiga (zamonaviy API) HTTP POST so'rovini yuboramiz. Biz quyidagilarni bajaramiz:
- vaqt tugadi (aks holda saqlash faylingiz "tiqilib qolgan" ko'rinishi mumkin),
- HTTP kodlari (401, 429, 500…),
- JSON noto'g'ri,
- kesh (kontent xeshiga asoslangan vaqtinchalik).
/**
* Génère un résumé via l'API OpenAI.
*
* @param string $content Texte à résumer.
* @param string $title Titre de l'article (aide au contexte).
* @return string Résumé ou chaîne vide si échec.
*/
function bpcab_ai_generate_summary_via_openai( string $content, string $title = '' ): string {
// Cache “fonctionnel” : si le contenu est identique, on réutilise le résumé
$hash = hash( 'sha256', $title . '|' . $content );
$cache_key = 'bpcab_ai_summary_' . substr( $hash, 0, 32 );
$cached = get_transient( $cache_key );
if ( is_string( $cached ) && $cached !== '' ) {
return $cached;
}
$endpoint = 'https://api.openai.com/v1/responses';
// Prompt : court, contraint, stable
$instruction = "Vous êtes un assistant de rédaction. Résumez l'article en français en 2 à 3 phrases maximum. " .
"Ton neutre. Pas de listes. Pas de titre. Pas de conclusion. " .
"Ne mentionnez pas que vous êtes une IA.";
$input = "Titre : " . $title . "nnTexte :n" . $content;
$body = array(
'model' => BPCAB_AI_SUMMARY_MODEL,
'input' => array(
array(
'role' => 'system',
'content' => $instruction,
),
array(
'role' => 'user',
'content' => $input,
),
),
// Paramètres de génération : limiter la longueur et la variabilité
'max_output_tokens' => 160,
'temperature' => 0.2,
);
$args = array(
'timeout' => BPCAB_AI_TIMEOUT_SECONDS,
'headers' => array(
'Authorization' => 'Bearer ' . BPCAB_OPENAI_API_KEY,
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( $body ),
);
$response = wp_remote_post( $endpoint, $args );
if ( is_wp_error( $response ) ) {
error_log( '[AI Summary] wp_remote_post error: ' . $response->get_error_message() );
return '';
}
$code = (int) wp_remote_retrieve_response_code( $response );
$raw = (string) wp_remote_retrieve_body( $response );
if ( $code < 200 || $code >= 300 ) {
error_log( '[AI Summary] HTTP ' . $code . ' - Réponse: ' . $raw );
return '';
}
$data = json_decode( $raw, true );
if ( ! is_array( $data ) ) {
error_log( '[AI Summary] JSON invalide. Body: ' . $raw );
return '';
}
/*
* Parsing : l'API Responses peut renvoyer un tableau "output" avec des items.
* On récupère le texte de sortie de manière prudente, sans supposer un format unique.
*/
$summary = bpcab_ai_extract_text_from_openai_responses( $data );
$summary = trim( (string) $summary );
if ( $summary === '' ) {
error_log( '[AI Summary] Résumé vide. Body: ' . $raw );
return '';
}
// Sanitation côté affichage : on stocke du texte simple, mais on reste prudent
$summary = wp_strip_all_tags( $summary );
// Cache 30 jours : un résumé ne change pas souvent
set_transient( $cache_key, $summary, 30 * DAY_IN_SECONDS );
return $summary;
}
/**
* Extrait le texte depuis la réponse OpenAI "Responses API".
* Cette fonction est volontairement défensive.
*/
function bpcab_ai_extract_text_from_openai_responses( array $data ): string {
// Cas fréquent : output[0].content[0].text
if ( isset( $data['output'] ) && is_array( $data['output'] ) ) {
foreach ( $data['output'] as $output_item ) {
if ( ! is_array( $output_item ) ) {
continue;
}
if ( ! isset( $output_item['content'] ) || ! is_array( $output_item['content'] ) ) {
continue;
}
foreach ( $output_item['content'] as $content_item ) {
if ( is_array( $content_item ) && isset( $content_item['text'] ) && is_string( $content_item['text'] ) ) {
return $content_item['text'];
}
}
}
}
// Fallback : certains formats renvoient "output_text"
if ( isset( $data['output_text'] ) && is_string( $data['output_text'] ) ) {
return $data['output_text'];
}
return '';
}
6-qadam — Xulosa (qisqa kod) ni ko'rsatish
Qisqa kod - bu kvadrat qavs ichida joylashgan kichik kod bo'lagi bo'lib, uni WordPress kontent bilan almashtiradi. Bu integratsiya qilishning eng oddiy usuli:
- 5-bo'lim : “Kod” yoki “Matn” moduli (matn rejimida) bilan
[ai_summary]. - Elementor : “Qisqa kod” vidjeti.
- Avada : “Qisqa kod” elementi (Fusion Builder).
add_shortcode( 'ai_summary', 'bpcab_ai_summary_shortcode' );
/**
* Shortcode: [ai_summary id="123"]
* Sans id, affiche le résumé du post courant.
*/
function bpcab_ai_summary_shortcode( array $atts ): string {
$atts = shortcode_atts(
array(
'id' => 0,
),
$atts,
'ai_summary'
);
$post_id = (int) $atts['id'];
if ( $post_id <= 0 ) {
$post_id = get_the_ID();
}
if ( ! $post_id ) {
return '';
}
$summary = get_post_meta( $post_id, BPCAB_AI_SUMMARY_META_KEY, true );
if ( ! is_string( $summary ) || $summary === '' ) {
return '';
}
// Affichage : on autorise uniquement du texte (pas de HTML)
$summary = esc_html( $summary );
return '<div class="ai-summary">' . $summary . '</div>';
}
Agar siz minimal HTML (masalan, kursiv) xohlasangiz, xom, nazoratsiz HTMLni saqlamang. Foydalaning wp_kses_post() namoyish vaqtida va qat'iy oq ro'yxatda. Yangi boshlovchi uchun men tavsiya qilaman: oddiy matn.
To'liq yig'ilgan kod
Ushbu butun faylni nusxalash va joylashtirish wp-content/mu-plugins/ai-auto-summary.phpKeyin, API kaliti doimiysini qo'shing wp-config.php.
<?php
/**
* Plugin Name: AI Auto Summary (mu-plugin)
* Description: Génère et stocke un résumé IA des articles WordPress.
* Version: 1.0.0
* Requires at least: 6.9
* Requires PHP: 8.1
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
const BPCAB_AI_SUMMARY_META_KEY = '_ai_summary';
const BPCAB_AI_SUMMARY_MODEL = 'gpt-4.1-mini';
const BPCAB_AI_TIMEOUT_SECONDS = 20;
const BPCAB_AI_MAX_INPUT_CHARS = 12000;
add_action( 'save_post', 'bpcab_ai_maybe_generate_summary', 20, 3 );
add_shortcode( 'ai_summary', 'bpcab_ai_summary_shortcode' );
/**
* Déclenche la génération du résumé lors de l'enregistrement.
*
* @param int $post_id ID du post.
* @param WP_Post $post Objet post.
* @param bool $update True si mise à jour, false si création.
*/
function bpcab_ai_maybe_generate_summary( int $post_id, $post, bool $update ): void {
if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
return;
}
if ( ! ( $post instanceof WP_Post ) ) {
return;
}
if ( $post->post_type !== 'post' ) {
return;
}
$status = get_post_status( $post_id );
if ( $status !== 'publish' ) {
return;
}
$existing = get_post_meta( $post_id, BPCAB_AI_SUMMARY_META_KEY, true );
if ( is_string( $existing ) && $existing !== '' ) {
return;
}
if ( ! defined( 'BPCAB_OPENAI_API_KEY' ) || ! is_string( BPCAB_OPENAI_API_KEY ) || BPCAB_OPENAI_API_KEY === '' ) {
error_log( '[AI Summary] Clé API absente. Ajoutez BPCAB_OPENAI_API_KEY dans wp-config.php.' );
return;
}
$content = bpcab_ai_get_post_text_for_summary( $post_id );
if ( $content === '' ) {
return;
}
$lock_key = 'bpcab_ai_summary_lock_' . $post_id;
if ( get_transient( $lock_key ) ) {
return;
}
set_transient( $lock_key, 1, 10 * MINUTE_IN_SECONDS );
$summary = bpcab_ai_generate_summary_via_openai( $content, get_the_title( $post_id ) );
if ( $summary === '' ) {
delete_transient( $lock_key );
return;
}
$summary = sanitize_text_field( $summary );
update_post_meta( $post_id, BPCAB_AI_SUMMARY_META_KEY, $summary );
}
/**
* Récupère un texte propre à résumer (sans HTML/shortcodes).
*/
function bpcab_ai_get_post_text_for_summary( int $post_id ): string {
$post = get_post( $post_id );
if ( ! $post instanceof WP_Post ) {
return '';
}
$text = (string) $post->post_content;
$text = strip_shortcodes( $text );
$text = wp_strip_all_tags( $text );
$text = preg_replace( '/s+/', ' ', $text );
$text = trim( (string) $text );
if ( $text === '' ) {
return '';
}
if ( mb_strlen( $text ) > BPCAB_AI_MAX_INPUT_CHARS ) {
$text = mb_substr( $text, 0, BPCAB_AI_MAX_INPUT_CHARS );
}
return $text;
}
/**
* Génère un résumé via l'API OpenAI.
*/
function bpcab_ai_generate_summary_via_openai( string $content, string $title = '' ): string {
$hash = hash( 'sha256', $title . '|' . $content );
$cache_key = 'bpcab_ai_summary_' . substr( $hash, 0, 32 );
$cached = get_transient( $cache_key );
if ( is_string( $cached ) && $cached !== '' ) {
return $cached;
}
$endpoint = 'https://api.openai.com/v1/responses';
$instruction = "Vous êtes un assistant de rédaction. Résumez l'article en français en 2 à 3 phrases maximum. " .
"Ton neutre. Pas de listes. Pas de titre. Pas de conclusion. " .
"Ne mentionnez pas que vous êtes une IA.";
$input = "Titre : " . $title . "nnTexte :n" . $content;
$body = array(
'model' => BPCAB_AI_SUMMARY_MODEL,
'input' => array(
array(
'role' => 'system',
'content' => $instruction,
),
array(
'role' => 'user',
'content' => $input,
),
),
'max_output_tokens' => 160,
'temperature' => 0.2,
);
$args = array(
'timeout' => BPCAB_AI_TIMEOUT_SECONDS,
'headers' => array(
'Authorization' => 'Bearer ' . BPCAB_OPENAI_API_KEY,
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( $body ),
);
$response = wp_remote_post( $endpoint, $args );
if ( is_wp_error( $response ) ) {
error_log( '[AI Summary] wp_remote_post error: ' . $response->get_error_message() );
return '';
}
$code = (int) wp_remote_retrieve_response_code( $response );
$raw = (string) wp_remote_retrieve_body( $response );
if ( $code < 200 || $code >= 300 ) {
error_log( '[AI Summary] HTTP ' . $code . ' - Réponse: ' . $raw );
return '';
}
$data = json_decode( $raw, true );
if ( ! is_array( $data ) ) {
error_log( '[AI Summary] JSON invalide. Body: ' . $raw );
return '';
}
$summary = bpcab_ai_extract_text_from_openai_responses( $data );
$summary = trim( (string) $summary );
if ( $summary === '' ) {
error_log( '[AI Summary] Résumé vide. Body: ' . $raw );
return '';
}
$summary = wp_strip_all_tags( $summary );
set_transient( $cache_key, $summary, 30 * DAY_IN_SECONDS );
return $summary;
}
/**
* Extrait le texte depuis la réponse OpenAI "Responses API".
*/
function bpcab_ai_extract_text_from_openai_responses( array $data ): string {
if ( isset( $data['output'] ) && is_array( $data['output'] ) ) {
foreach ( $data['output'] as $output_item ) {
if ( ! is_array( $output_item ) ) {
continue;
}
if ( ! isset( $output_item['content'] ) || ! is_array( $output_item['content'] ) ) {
continue;
}
foreach ( $output_item['content'] as $content_item ) {
if ( is_array( $content_item ) && isset( $content_item['text'] ) && is_string( $content_item['text'] ) ) {
return $content_item['text'];
}
}
}
}
if ( isset( $data['output_text'] ) && is_string( $data['output_text'] ) ) {
return $data['output_text'];
}
return '';
}
/**
* Shortcode: [ai_summary id="123"]
*/
function bpcab_ai_summary_shortcode( array $atts ): string {
$atts = shortcode_atts(
array(
'id' => 0,
),
$atts,
'ai_summary'
);
$post_id = (int) $atts['id'];
if ( $post_id <= 0 ) {
$post_id = get_the_ID();
}
if ( ! $post_id ) {
return '';
}
$summary = get_post_meta( $post_id, BPCAB_AI_SUMMARY_META_KEY, true );
if ( ! is_string( $summary ) || $summary === '' ) {
return '';
}
return '<div class="ai-summary">' . esc_html( $summary ) . '</div>';
}
Kodning izohi
Nima uchun saqlash_post (va the_content emas)?
save_post Bu WordPress kontentni saqlaganida ishga tushadi. Bu sizga sun'iy intellektga bir marta qo'ng'iroq qilish, natijani saqlash va uni o'z holiga qoldirish uchun "tabiiy" lahzani beradi.
Men ko'pincha "namoyishda" degan ma'lumotlarni umumlashtiruvchi qo'llanmalarni ko'rganman the_contentKesh o'chirilgan yoki skanerlovchi botga ega saytda siz API uchun sikl davomida to'lovni amalga oshirasiz. Va o'quvchi har safar yuklanganda turli xil xulosani ko'rishi mumkin.
Vaqtinchalik qulf (ikki marta qarshi qo'ng'iroq)
WordPress bir necha marta saqlashi mumkin (avtomatik saqlash, yangilanishlar, SEO plaginlari). bpcab_ai_summary_lock_{ID} 30 soniyada AI ni 3 marta ishga tushirishdan saqlaydi.
Kontent xeshi keshi
Biz sarlavha va kontentning SHA-256 xeshini hisoblaymiz. Agar bir xil matn takrorlansa (nusxa ko'chirilgan, tiklangan), biz vaqtinchalik xeshdan qayta foydalanamiz. Bu to'g'ridan-to'g'ri xarajatlarni tejashga olib keladi.
Dezinfeksiya: biz nimani himoya qilamiz
sanitize_text_field(): belgilarni olib tashlaydi va oddiy matnni normallashtiradi.wp_strip_all_tags(): yaratilgan bo'lishi mumkin bo'lgan har qanday HTML teglarini olib tashlaydi.esc_html()displey: har qanday HTML/JS in'ektsiyasini oldini oladi.
Haqiqiy xavf: agar siz sun'iy intellekt javobini qochishsiz namoyish qilsangiz, siz in'ektsiya uchun eshik ochasiz (kamdan-kam hollarda, lekin men buni ilgari sun'iy intellektni HTML ishlab chiqarishga "majburlaydigan" kontent orqali ko'rganman).
API xarajatlari va optimallashtirish
Narxlar muntazam ravishda o'zgarib turadi. Joylashtirishdan oldin rasmiy sahifani tekshirishni odat qiling: OpenAI narxlari.
Oddiy taxmin (kattalik tartibida)
2-3 ta jumladan iborat xulosa ko'pincha quyidagicha bo'ladi:
- Kirish narxi: 1000 dan 3000 gacha tokenlar (maqola uzunligiga qarab),
- Chiqish: 80 dan 160 tagacha token.
Oylik hisoblash misoli:
- Oyiga 200 ta umumlashtirilgan maqola
- O'rtacha 2000 ta kirish tokeni + 120 ta chiqish tokeni
Siz tanlangan modelning narxiga ko'paytirasiz. Asosiy nuqta: xarajatlar asosan kirish qismidaShuning uchun chegara BPCAB_AI_MAX_INPUT_CHARS.
Haqiqatan ham ishlaydigan optimallashtirishlar
- Yuborilgan matnni cheklash Ko'pincha 8000–12000 belgi yetarli bo'ladi.
- "Mini" model Xulosa uchun: 3 ta jumla uchun noqulay shablon uchun pul to'lashning hojati yo'q.
- Faqat bir marta yarating va metama'lumotlarda saqlang.
- Qo'lda regeneratsiya (kengaytirilgan variant) har bir yangilanish bilan qayta yaratish o'rniga.
Murakkab variantlar va foydalanish holatlari
1) Maqola yangilanganda xulosani qayta yarating
Odatiy bo'lib, kod mavjud xulosani almashtirmaydi. Agar uni har bir yangilanish bilan qayta yaratmoqchi bo'lsangiz, ushbu blokni o'chiring:
// 4) Si un résumé existe déjà, ne pas écraser
$existing = get_post_meta( $post_id, BPCAB_AI_SUMMARY_META_KEY, true );
if ( is_string( $existing ) && $existing !== '' ) {
return;
}
Lekin men buni ko'pgina saytlarda qilmayman: muallif 10 ta kichik tuzatish kiritishi mumkin, siz esa 10 barobar ko'p to'laysiz.
2) Shuningdek, sahifalarni umumlashtiring (post_type = page)
Siz ruxsat berishingiz mumkin page :
if ( ! in_array( $post->post_type, array( 'post', 'page' ), true ) ) {
return;
}
3) Divi 5 / Elementor / Avada integratsiyasi (amaliy)
- 5-bo'lim : “Kod” modulini qo'shing va qo'ying
[ai_summary]Agar siz Mavzu Quruvchisi shablonidan foydalanayotgan bo'lsangiz, maqola maketiga qisqa kodni qo'ying. - Elementor : Yagona Post shablonidagi “Shortcode” vidjeti, keyin
[ai_summary]. - Avada : Builderda yoki global shablonda "Qisqa kod" elementi.
Agar quruvchingiz qisqa kodni "tozalasa" (bu ba'zi matn modullarida sodir bo'ladi), maxsus "Qisqa kod" vidjeti/elementidan foydalaning.
Xavfsizlik va eng yaxshi amaliyotlar
API kalitini mijoz tomonida hech qachon oshkor qilmang
Brauzerda JavaScript orqali OpenAI qo'ng'iroqlarini amalga oshirmang. Kalitni "yashirsangiz" ham, u oxir-oqibat ko'rinadigan bo'lib qoladi. Qo'ng'iroq server tomonida (PHP) qolishi kerak. wp_remote_post().
Avlodni qo'zg'atishi mumkin bo'lgan narsalarni cheklash
Ilgak save_post tahrirlash amallari bilan ishga tushiriladi. Administrator maydonida u allaqachon WordPress imkoniyatlari bilan himoyalangan. Agar keyinchalik "Qayta tiklash" tugmasini qo'shsangiz, quyidagilardan foydalaning:
- un nuncio (CSRFga qarshi token)
current_user_can( 'edit_post', $post_id ).
Malumot: Nonces (developer.wordpress.org).
Stavkalarni cheklash (suiiste'molga qarshi / kutilmagan holatlarga qarshi qonun loyihasi)
Agar bir nechta mualliflar ommaviy ravishda nashr etsa, siz global o'tish davri yordamida xulosalarni soatiga X bilan cheklashingiz mumkin. Masalan, hisoblagichni saqlang va ma'lum bir chegaradan oshib ketgan xabarlarni rad eting. Bu oddiy, ammo "Men 2000 ta postni import qildim va ularning barchasini birdaniga umumlashtirdim" stsenariysining oldini oladi.
GDPR: ma'lumotlar uchinchi tomonga yuboriladi
Siz kontentni tashqi provayderga yubormoqdasiz. Vaziyatingizga qarab:
- Maxfiylik siyosatingizni yangilang,
- Keraksiz shaxsiy ma'lumotlarni yuborishdan saqlaning.
- Maxfiy ma'lumotlarni o'z ichiga olgan kontentni avtomatik ravishda umumlashtirmang.
Qanday qilib sinovdan o'tkazish va disk raskadrovka qilish kerak
1) WordPress jurnallarini yoqish
yilda wp-config.php (sinov muhitida), quyidagilarni yoqing:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
Xatolar ichida bo'ladi wp-content/debug.log.
2) Minimal sinov
- Yangi maqola yarating.
- Matnning 2-3 paragrafini qo'shing (faqat sarlavha emas).
- Nashr qilish.
- Meta-ni tekshiring
_ai_summary("Query Monitor" kabi plagin yordamida yoki meta vositasi bo'lsa, muharrir orqali). - qo'shish
[ai_summary]shabloningizda yoki kontentingizda ko'rsating va displeyni tekshiring.
3) HTTP qo'ng'iroqlarini tekshiring
Agar siz tanaffusga duch kelsangiz, avval tanaffusni vaqtincha oshirishdan boshlang. BPCAB_AI_TIMEOUT_SECONDS 30 da. Keyin xosting provayderingiz chiquvchi so'rovlarni bloklayotganini tekshiring.
WordPress HTTP API bo'yicha rasmiy hujjatlar: HTTP API.
Agar bu ishlamasa
Diagnostika jadvali
| alomat | Ehtimoliy sabab | tekshiruv | qaror |
|---|---|---|---|
| Xulosa hech qachon ko'rinmaydi | Kod noto'g'ri joyga joylashtirildi / mu-plagin yuklanmadi | Faylning ichida ekanligini tekshiring wp-content/mu-plugins/ |
Faylni ko'chiring, ruxsatnomalarni tekshiring, administrator panelini qayta yuklang. |
| xato Nashr qilingan paytda administratorda 500 ta | PHP xatosi (nuqta-vergul, qavs yo'q) | Consult wp-content/debug.log |
Sintaksisni to'g'rilang yoki zaxira nusxasini tiklang |
| Jurnallarda HTTP 401 xatosi | API kaliti noto'g'ri | ko'rinish debug.log (API javobi) |
Kalitni qayta yarating, uni joylashtiring wp-config.php |
| Jurnallarda HTTP 429 xatosi | Kvotadan oshib ketdi / yetkazib beruvchi narxining chegarasi | Yetkazib beruvchi boshqaruv paneli | Kuting, qo'ng'iroqlarni kamaytiring, tezlikni cheklash + kesh qo'shing |
| Vaqt tugashi / nashr "bloklangan" | Vaqt tugashi juda past, sekin xosting, chiquvchi xavfsizlik devori | Vaqt tugashini oshiring, boshqa serverdan sinovdan o'tkazing | Vaqt tugashi 30 soniya, xosting provayderiga murojaat qiling, oxirgi nuqtani avtorizatsiya qiling |
| Bo'sh xulosa | Juda qisqa yoki juda "quruvchiga o'xshash" kontent (qisqa kodlar) | Tozalashdan keyin matnni tekshiring | Haqiqiy matn qo'shing, tozalashni sozlang, parchani umumlashtiring |
| Siz maqolani tahrirlaysiz, ammo xulosa o'zgarmaydi | Agar metama'lumotlar allaqachon mavjud bo'lsa, kod qayta yaratilmaydi. | Mavjudligini tekshiring _ai_summary |
Meta tegni olib tashlang yoki qo'lda regeneratsiyani amalga oshiring. |
Men tez-tez ko'radigan realistik xatolar (va ulardan qanday qochish kerak)
- Zaxira nusxasisiz ishlab chiqarishda sinovdan o'tkazish : bosqichma-bosqich sinovni o'tkazing. PHP sintaksis xatosi butun boshqaruv panelini blokirovka qilishi mumkin.
- Harakat va filtr o'rtasidagi chalkashlik :
save_postbu harakat. Qiymatni o'zgartirish uchun biror narsani "qaytarishga" urinmang. - Noto'g'ri ilmoq : oldini olish
the_contentqimmat vazifa uchun. - Kesh plagini : agar siz qisqacha ma'lumotni qisqa kod orqali ko'rsatsangiz va sizda agressiv kesh bo'lsa, uni birinchi avloddan keyin tozalang.
- PHP juda eski Agar xosting provayderingiz PHP 7.4 dan foydalanayotgan bo'lsa, 8.1+ ga yangilang. Malumot uchun: PHP tomonidan qo'llab-quvvatlanadigan versiyalar (php.net).
resurslari
- WordPress HTTP API (developer.wordpress.org)
- Nonces va xavfsizlik (developer.wordpress.org)
- Transients API (developer.wordpress.org)
- OpenAI API haqida umumiy ma'lumot
- OpenAI Javoblar API ma'lumotnomasi
- WordPress ishlab chiqishning GitHub oynasi (wordpress-develop)
- WordPress Core Trac (chiptalarni kuzatish)
- cURL kengaytmasi (php.net)
FAQ
1) Elementor / Divi 5 / Avada bilan ishlaydimi?
Ha. Qisqa kod [ai_summary] eng oddiy usul. Builderingizda "Shortcode" vidjeti/elementidan foydalaning.
2) Nima uchun functions.php o'rniga mu-plagin?
Chunki functions.php Bu mavzuga bog'liq. Agar siz mavzuni o'zgartirsangiz, funksiya yo'qoladi. Mu-plagin mavzudan qat'i nazar, avtomatik ravishda yuklanadi.
3) Bu maqola nashr etilishini sekinlashtiradimi?
Ha, biroz: saqlash jarayonida (vaqtinchalik tugagunga qadar) API javobini kutasiz. Juda faol saytlarda men ko'pincha bu ishlov berishni asinxron vazifaga (WP-Cron yoki Action Scheduler) o'tkazaman, ammo bu yanada rivojlangan yondashuv.
4) Faqat bitta parchani (dastlabki 2 ta xatboshi) umumlashtira olamanmi?
Ha. Tahrirlash bpcab_ai_get_post_text_for_summary() faqat birinchi X belgilarni olish yoki tozalashdan oldin paragraflarga bo'lish.
5) Nima uchun displeyda qayta hisoblash o'rniga post-meta ichida saqlash kerak?
Har bir sahifa ko'rinishida API uchun pul to'lamaslik va barqaror xulosani kafolatlash uchun siz faqat displeyda tezkor ma'lumotlar bazasini o'qiysiz.
6) Xulosa arxivlarda (kategoriyalarda) avtomatik ravishda ko'rsatilishi mumkinmi?
Ha. Siz qisqa kodni arxiv shabloniga qo'shishingiz mumkin (yoki agar mavzuingiz imkon bersa, konstruktor orqali). Yana bir variant: filtrni biriktirish the_excerpt parchani meta bilan almashtirish uchun, lekin men buni faqat sayt aniq strategiyaga ega bo'lsa qilaman (aks holda bu mualliflarni hayratda qoldiradi).
7) WordPress 6.9.4 HTTP so'rovlarini amalga oshirishning o'ziga xos usulini joriy qiladimi?
Yo'q: tavsiya etilgan yondashuv saqlanib qolmoqda wp_remote_post() HTTP API orqali. Bu barqaror va PHPda cURLga to'g'ridan-to'g'ri kirish imkoni bo'lmagan muhitlar bilan mos keladi.
8) Qanday qilib allaqachon umumlashtirilgan maqola uchun qayta tiklashni "majburlash" mumkin?
Meta-ni olib tashlang _ai_summary (meta vositasi yoki kichik administrator skripti orqali), keyin maqolani yangilang. Tozaroq alternativa: nonce va imkoniyatga ega "Qayta tiklash" tugmasini qo'shing.
9) Sun'iy intellekt xulosa shaklida ma'lumot ixtiro qila oladimi?
Ha, mumkin. Haroratni pasaytirish yordam beradi, lekin xatolik yo'qligini kafolatlamaydi. Maxfiy kontent uchun inson tekshiruvini davom ettiring yoki sun'iy intellektdan foydalanmang.
10) Nima uchun tokenlarni sanash o'rniga BPCAB_AI_MAX_INPUT_CHARS ni cheklash kerak?
Tokenlarni aniq sanash uchun maxsus kutubxona kerak. Yangi boshlovchi sayt uchun belgilar chegarasi oddiy, ishonchli va allaqachon xarajatlarni sezilarli darajada kamaytiradi.