Recently, I completed a batch completion of WordPress historical article excerpts.
This task ultimately processed 42 Chinese historical articles and synchronously completed the excerpts for their corresponding English articles. The final results were:
- Completed: 42/42
- Pending: 0
- Abnormal status: 0
During execution, issues such as GLM request timeouts, WordPress REST API connection drops, Polylang SSH check timeouts, and SlyTranslate returning HTTP 500 occurred. However, they were all safely handled through state logging, checkpoint recovery, and read-only verification mechanisms, without generating duplicate excerpts or mistakenly altering article relationships.
This practice reinforced my conviction: when batch-modifying WordPress historical content, what truly matters is not “whether a large language model can be called to generate a piece of text,” but whether a production workflow can be established that is auditable, recoverable, verifiable, and incapable of damaging existing content.
1. Why Complete Historical Article Excerpts
My WordPress website has accumulated a large number of technical articles.
Some early articles did not have their excerpts filled in. When the Chinese article’s excerpt was empty, the corresponding English translation article’s excerpt was usually empty as well.
This causes several problems:
- Article list pages can only temporarily truncate the body text as an excerpt.
- SEO plugins may not be able to directly use stable article excerpts.
- English site articles lack controllable English summaries.
- When subsequently performing article recommendations, content aggregation, and structured output, the excerpt field cannot be used directly.
- If batch content maintenance continues in the future, empty excerpts will become a long-standing legacy issue.
The simplest approach is to iterate over all articles with empty excerpts, call a large language model to generate excerpts, and then write them to the database.
However, this approach carries high risks.
Not all articles with empty excerpts on the website are suitable for direct modification. Some articles might lack English translations, some might have abnormal Chinese-English relationships, and others might use special Gutenberg blocks, Code Block Pro code blocks, or other complex content structures.
Therefore, instead of starting directly with “batch writing,” I first performed a comprehensive read-only inventory.
2. Establish a Fixed Candidate List First
The first phase only reads production environment data and performs no writes.
Candidate articles must simultaneously meet the following conditions:
- The Chinese article has been published;
- The Chinese excerpt is empty;
- Uses the Gutenberg editor;
- The body contains structures requiring special protection, such as Code Block Pro;
- A corresponding English translation article exists;
- The English article has been published;
- The English excerpt is empty;
- The Polylang Chinese-English relationship is correct;
- The Chinese and English article IDs are explicit;
- A fixed hash can be calculated from the article’s current status, body, and title.
After filtering, a fixed candidate list of 42 pairs of Chinese and English articles was obtained.
Additionally, there were 46 articles that already had Chinese excerpts. These articles were explicitly excluded from the candidate list, and subsequent scripts will not modify them.
The significance of the fixed candidate list is that during formal execution, the entire WordPress database is no longer rescanned. Instead, only the article IDs confirmed during the audit phase are allowed to be processed.
Even if new articles are added to the website later, or the status of other articles changes, they will not be automatically included in this batch process.
3. Different Processing Methods for Chinese and English Excerpts
This workflow does not simply have one model generate both Chinese and English excerpts simultaneously.
The actual processing is divided into two phases.
1. Using GLM 4.7 to Generate Chinese Excerpts
GLM 4.7 is solely responsible for generating Chinese excerpts based on the Chinese article’s title and body.
Excerpt requirements include:
- Return only a single paragraph of plain text;
- Do not use Markdown;
- Do not use bullet points;
- Do not add extra explanations beyond “This article introduces”;
- Keep the length around 160–240 Chinese characters;
- Minimum length must not be less than 80 characters;
- Maximum length must not exceed 300 characters;
- Do not include code, commands, or Gutenberg block markers;
- Maintain the authentic and restrained tone of a personal technical blog, avoiding marketing language.
Before generating the excerpt, the script first removes the following from the body text:
- Gutenberg block comments;
- HTML tags;
- Code Block Pro code content;
- Standard code blocks;
- Shortcodes;
- URLs;
- File paths;
- Other structures unsuitable as excerpt context.
This reduces the probability of the model writing code, commands, or HTML fragments into the excerpt.
2. Using SlyTranslate and GLM 5.2 to Update English Articles
After the Chinese excerpt is successfully written, GLM 4.7 is no longer called separately to generate the English excerpt.
The script calls the existing SlyTranslate overwrite translation interface, using GLM 5.2 to reprocess the corresponding English article.
The request uses overwrite mode:
{
"input": {
"post_id": 18150,
"source_language": "zh",
"target_language": "en",
"post_status": "publish",
"overwrite": true,
"translate_title": true,
"model_slug": "glm-5.2"
}
}
This approach has several benefits:
- Continues to reuse the already tuned SlyTranslate translation pipeline;
- Preserves the original Gutenberg block protection logic;
- Preserves Code Block Pro code blocks;
- Preserves HTML, shortcodes, URLs, paths, and product names;
- Directly updates the existing English article;
- Does not create new English articles;
- Does not change the article’s publication status;
- Does not break Polylang Chinese-English associations.
4. Why Direct Batch Execution Is Not Acceptable
The truly dangerous part is not the model generating the excerpt, but the writing to the production environment.
A complete workflow involves at least the following operations:
- Read the Chinese article.
- Read the English article.
- Verify article status.
- Verify current title and body hash.
- Load WordPress via SSH.
- Verify Polylang language and bidirectional associations.
- Call GLM 4.7.
- Validate the generated excerpt.
- Back up article data before writing.
- Update the Chinese excerpt via REST API.
- Read the Chinese article again to confirm the write result.
- Verify Polylang relationships again.
- Call SlyTranslate for overwrite translation.
- Read the English article to confirm the English excerpt.
- Verify article status and Chinese-English relationship again.
- Mark the execution status as completed.
At any point during these 16 steps, a network timeout, API error, or server-side connection drop can occur.
If executed using a simple loop, it is difficult to determine upon failure:
- Whether the Chinese excerpt has already been written;
- Whether the English overwrite translation has already been executed;
- Whether SlyTranslate actually succeeded, but the response was not returned;
- Whether the Chinese excerpt should be regenerated;
- Whether the overwrite translation should be called again;
- Whether two writes might be executed on the same article.
Therefore, I established an independent execution status file for each candidate article.
5. Save Execution Status for Each Article
Each Chinese article has an independent status file, for example:
data/backups/single-candidate/chinese-18150.execution.json
The status file records:
- Chinese article ID;
- English article ID;
- Pre-write backup path;
- Task start time;
- Generated Chinese excerpt;
- Number of excerpt generation attempts;
- Current execution status;
- Completion time;
- Final English article ID;
- Network or API error messages.
The main statuses include:
prepared
excerpt_rejected
chinese_excerpt_saved
translation_started
translation_failed
completed
These statuses exist not just to display progress, but to determine where the task should resume from after a failure.
For example:
prepared: The Chinese excerpt has not been written yet, so GLM can be called again;chinese_excerpt_saved: The Chinese excerpt has been written and cannot be regenerated; only the English overwrite can continue;translation_failed: The overwrite translation explicitly failed, so SlyTranslate can be called again;translation_started: The overwrite request was sent, but the final result is uncertain, requiring read-only verification first;completed: All checks passed, so subsequent batches will skip it directly.
6. Back Up Each Article Individually Before Writing
When each article enters the actual execution workflow for the first time, a pre-write backup is saved:
data/backups/single-candidate/chinese-18150.pre-write.json
The backup file permissions are fixed to:
0600
The backup includes the article data read before execution and the fields required for safety checks.
Neither the status file nor the backup file will save:
- Zhipu API Key;
- WordPress login cookies;
- REST API nonces;
- Authorization request headers;
- Other authentication information.
Even if the logs or backup files are copied, they will not directly expose production environment credentials.
7. Only Retry the Generation Phase When Excerpt Validation Fails
In early testing, GLM occasionally returned excerpts with bullet points or Markdown-like formatting.
For example, the model might return:
- First item content
- Second item content
Although this content is readable, it does not meet the requirement that the WordPress excerpt field should only store a single paragraph of plain text.
Therefore, the script performs strict validation on the generated results.
GLM is only called again if an excerpt format validation error occurs, with a maximum of 3 attempts.
Rejected results are saved separately in:
data/backups/single-candidate/rejected/
File permissions are also 0600.
Other types of errors, such as WordPress status changes, content hash mismatches, or abnormal Polylang relationships, do not trigger a model retry; instead, they halt the task immediately.
This prevents genuine safety anomalies from being misidentified as standard model output issues.
8. Recovery Mode No Longer Depends on the GLM API Key
A recovery logic issue occurred during execution.
A certain article had successfully written the Chinese excerpt, but SlyTranslate returned HTTP 500. At this point, the status was:
translation_failed
The correct operation should be to execute:
python3 bin/execute-single-candidate.py \
--post-id 17945 \
--execute \
--resume
The recovery process does not need to regenerate the Chinese excerpt, so it should not use GLM 4.7.
However, the initial command-line program would construct the GLM client directly before entering the recovery logic, causing it to still require the environment variable even when using --resume:
ZHIPU_API_KEY
Later, the GLM client was changed to lazy import and lazy instantiation:
- Construct the GLM client only for standard
--execute; - Pass
--execute --resumeintoglm=None; - The recovery process does not read the Zhipu API Key at all;
- Standard execution still refuses to run when the API Key is missing.
After this fix was completed, all targeted tests and full tests passed, totaling 204 items.
9. The Most Dangerous Status: translation_started
While executing article 18150 → 18156, a more complex edge case occurred.
The workflow had already completed:
- GLM 4.7 generating the Chinese excerpt;
- Writing the Chinese excerpt to WordPress;
- SlyTranslate overwrite translation;
- The English excerpt had actually been generated.
However, after the overwrite translation completed, when the program read the English article again for final verification, the connection was dropped by the server:
RemoteDisconnected
The status file remained at:
translation_started
At this point, it cannot be directly concluded that the overwrite translation failed.
If SlyTranslate were simply executed again on translation_started, it might repeatedly overwrite an already successfully translated English article.
Therefore, I performed a read-only check first.
The check results were:
zh_id: 18150
zh_status: publish
zh_excerpt_length: 154
en_id: 18156
en_status: publish
en_excerpt_length: 459
The Polylang bidirectional relationship was also completely correct:
{
"zh_language": "zh",
"en_language": "en",
"zh_translations": {
"zh": 18150,
"en": 18156
},
"en_translations": {
"en": 18156,
"zh": 18150
}
}
This indicates that SlyTranslate had actually succeeded; only the final REST read failed.

10. Adding Read-Only Convergence for translation_started
To solve this problem, the recovery logic was adjusted again.
Now, when encountering translation_started, it does not immediately call SlyTranslate again. Instead, it first performs a read-only convergence check.
The check includes:
- Chinese article ID matches the fixed list;
- English article ID matches the fixed list;
- Chinese and English articles remain in the expected publication status;
- Chinese title and body have not changed;
- The written Chinese excerpt matches the status file;
- English title and body are not empty;
- Whether the English excerpt has already been generated;
- Chinese article language is
zh; - English article language is
en; - Polylang relationship from Chinese to English is correct;
- Reverse Polylang relationship from English to Chinese is correct.
If all verifications pass, and the English excerpt is already non-empty:
- Do not call SlyTranslate again;
- Directly write the status as
completed; - Write
completed_at; - Write
translated_post_id.
Only if the English excerpt is still empty is calling the overwrite translation interface allowed again.
If there are anomalies in the article ID, publication status, content hash, or Polylang relationships, recovery is refused, SlyTranslate is not called, and nothing is written to WordPress.
After this fix was completed, the total number of full tests increased to 208, all passing.
11. Real Failures Encountered During Batch Execution
The final batch process was not an entirely error-free execution.
During the batch processing of the remaining articles, three main types of temporary failures occurred.
1. GLM Request Timeout
When generating excerpts for articles 18488 → 18513 and 18534 → 18610 for the first time, the GLM request encountered:
TimeoutError: The read operation timed out
At this point, the status remained:
prepared
Indicating:
- The Chinese excerpt had not been generated yet;
- WordPress had not been written to yet;
- SlyTranslate had not been called yet.
After the batch process waited 10 seconds, it re-executed in normal mode based on the latest status, and both succeeded on the second attempt.
2. Final REST Read Connection Drop
Article 18726 → 18746 had already executed the overwrite translation, but when finally reading the English article, the following occurred:
RemoteDisconnected
The status became:
translation_started
After the batch process waited 10 seconds, it automatically switched to --resume.
The new read-only convergence logic confirmed that the English excerpt already existed, so it did not call SlyTranslate again and directly marked the task as completed.
3. SlyTranslate Returns HTTP 500
Article 18815 → 18825 returned the following during the overwrite translation phase:
HTTP request failed with status 500
The status became:
translation_failed
After the batch process waited 10 seconds, it executed recovery mode, calling the overwrite translation again, and succeeded on the second attempt.
These failures demonstrate that batch tasks cannot simply interpret a “non-zero command exit” as “nothing was done to the article.”
The next operation must be determined based on the persisted status.


12. How the Final Batch Process Determines Execution Mode
The final batch process does not rigidly execute the same command for each article; instead, it reads the status file first.
The mapping between statuses and execution methods is as follows:
none
prepared
excerpt_rejected
Uses normal execution:
python3 bin/execute-single-candidate.py \
--post-id <ID> \
--execute
The following statuses:
chinese_excerpt_saved
translation_started
translation_failed
Uses recovery execution:
python3 bin/execute-single-candidate.py \
--post-id <ID> \
--execute \
--resume
If the status is already:
completed
It is skipped directly.
Each article is attempted a maximum of 3 times.
It waits 10 seconds between attempts and reselects the execution mode based on the latest status.
Unrecognized statuses are not processed automatically; instead, the entire batch is halted immediately.
The entire batch process runs in a subshell, so even if a task fails, it will not close the current terminal window.
13. Final Execution Results
When the final batch process started, 26 articles remained.
Most articles succeeded on the first execution.
Among them:
- Two articles encountered GLM timeouts and succeeded on the second normal execution;
- One article dropped the connection during final REST verification and succeeded via
translation_startedread-only convergence; - One article encountered a SlyTranslate HTTP 500 and succeeded via
translation_failedrecovery.
The final summary results are:
Completed: 42/42
Pending: 0
Abnormal status: 0

This also proves that this workflow can not only run in an ideal network environment but also cope with the temporary failures common in actual production environments.
14. The Most Important Principles in This Implementation
Looking back at the entire process, I believe the following principles are more important than which specific model is used.
1. Audit First, Then Write
Do not let batch scripts decide which production articles to modify on their own.
Generate a fixed candidate list first, and then only allow articles in that list to be processed.
2. One Status File per Article
Do not only display progress in the terminal.
Status must be persisted so that after a program restart, it can still determine which step it stopped at last time.
3. Must Back Up Before Writing
Before the first write to each article, an independent backup is saved.
Backup permissions should be restricted to be readable and writable only by the current user.
4. Recovery Does Not Equal Repeated Execution
The recovery process must decide based on status:
- Whether to call the model again;
- Whether to rewrite the Chinese excerpt;
- Whether to call the overwrite translation again;
- Whether only the final verification needs to be completed.
5. Request Failure Does Not Mean Operation Failure
When a POST request times out or the connection drops, the server may have already completed the operation.
Especially when calling time-consuming translation interfaces, you must first perform a read-only verification of the production results before deciding whether to retry.
6. Bidirectional Verification of Polylang Relationships
It is not enough to just confirm that the Chinese article points to the English article.
You must also confirm that the English article points back to the correct Chinese article.
7. Do Not Cancel Safety Checks for Batch Speed
There were only 42 articles this time, and executing them one by one adds some time.
However, compared to fixing Chinese-English article relationships, recovering incorrect excerpts, or handling duplicate translations, this time cost is completely acceptable.
15. Conclusion for the Current Phase
This excerpt completion was not a simple AI text generation task, but a small-scale WordPress content migration and production data repair.
GLM 4.7 was responsible for generating Chinese excerpts, and SlyTranslate and GLM 5.2 were responsible for updating English translations, but what truly allowed the workflow to land safely was the surrounding engineering controls:
- Fixed candidate list;
- Content hashing;
- Pre-write backups;
- REST API writes;
- Polylang bidirectional checks;
- State persistence;
- Failure classification;
- Safe recovery;
- Read-only convergence;
- Automatic retries;
- Comprehensive testing.
Ultimately, all 42 pairs of Chinese and English articles were completed, articles that already had excerpts were not included in the modification scope, and the Chinese and English article IDs, publication statuses, and Polylang relationships all remained unchanged.
At this point, this WordPress historical article excerpt completion can officially come to a close.
More importantly, this workflow is no longer a one-off temporary script.
It already has the foundation to continue extending to other historical content maintenance tasks, such as:
- Completing excerpts for more types of articles;
- Checking Chinese-English excerpt consistency;
- Auditing historical article Meta Descriptions;
- Batch checking Polylang associations;
- Performing read-only quality assessments on existing excerpts;
- Establishing recoverable AI update workflows for other WordPress content fields.
For AI automation in production environments, I now lean towards a clear judgment:
While model output quality is undoubtedly important, what truly determines whether a solution can run long-term is the safety boundaries, state management, and recovery capabilities outside the model.
需要长期技术维护或远程问题排查?
我是拥有 15+ 年经验的 PHP / Go 后端工程师,长期关注已有系统维护、Bug 修复、性能优化、服务器排查、WordPress 网站维护和小功能迭代。
如果你的项目遇到以下情况,可以先从一次小问题排查开始合作:
- ✅ PHP / Laravel / Yii2 老项目无人维护
- ✅ Go / Gin 后端接口需要排查或优化
- ✅ WordPress 网站访问慢、报错或插件冲突
- ✅ Nginx / MySQL / Redis / Linux 服务器异常
- ✅ CDN / Cloudflare / DNS / HTTPS 配置问题
- ✅ 需要长期远程技术支持或兼职维护
更多介绍请查看:关于我 & 合作
微信:13980074657
邮箱:shuijingwanwq@gmail.com
Telegram:@shuijingwan
GitHub:https://github.com/shuijingwan

发表回复