更新三候选优化对比设计
This commit is contained in:
@@ -14,11 +14,16 @@ The MVP is a local web application:
|
||||
2. System extracts a candidate fact card.
|
||||
3. User confirms or edits the fact card.
|
||||
4. Confirmed fact card is saved as a reusable local brand template.
|
||||
5. System optimizes the article under fact-card constraints.
|
||||
6. System runs quality gates.
|
||||
7. Failed checks trigger targeted rewriting for up to two rounds.
|
||||
8. User previews optimized content and QA report.
|
||||
9. User downloads Markdown and a basic Word document.
|
||||
5. System generates three optimization candidates under fact-card constraints:
|
||||
`标准GEO版`, `去AI味版`, and `综合增强版`.
|
||||
6. System runs quality gates for each candidate.
|
||||
7. Failed checks trigger targeted rewriting for up to two rounds inside each
|
||||
candidate path.
|
||||
8. System scores each candidate for GEO quality and AI-flavor/style quality.
|
||||
9. User compares all candidates side by side, with `综合增强版` highlighted as
|
||||
the recommended default.
|
||||
10. User downloads Markdown, Word, and QA artifacts for the selected candidate
|
||||
or the full comparison.
|
||||
|
||||
## Explicitly Out Of Scope
|
||||
|
||||
@@ -36,12 +41,15 @@ The MVP is a local web application:
|
||||
flowchart TD
|
||||
A["Input Article"] --> B["Auto Analyze"]
|
||||
B --> C["Confirm Fact Card"]
|
||||
C --> D["Optimize Article"]
|
||||
D --> E["Quality Check"]
|
||||
E -->|Pass| F["Preview Result"]
|
||||
E -->|Fail| G["Targeted Rewrite"]
|
||||
G --> D
|
||||
F --> H["Download Markdown / Word"]
|
||||
C --> D["Generate Three Candidates"]
|
||||
D --> E1["标准GEO版 QA"]
|
||||
D --> E2["去AI味版 QA"]
|
||||
D --> E3["综合增强版 QA"]
|
||||
E1 --> F["Compare Results"]
|
||||
E2 --> F
|
||||
E3 --> F
|
||||
F --> G["Select Candidate"]
|
||||
G --> H["Download Markdown / Word / QA"]
|
||||
```
|
||||
|
||||
## Page Areas
|
||||
@@ -78,17 +86,24 @@ Fields:
|
||||
|
||||
The user must resolve uncertain items before optimization starts.
|
||||
|
||||
### Optimized Result
|
||||
### Candidate Comparison
|
||||
|
||||
Display:
|
||||
|
||||
- Candidate label: `标准GEO版`, `去AI味版`, or `综合增强版`.
|
||||
- Method summary that explains what this candidate optimized for.
|
||||
- Optimized title.
|
||||
- Summary.
|
||||
- Optimized body.
|
||||
- Image suggestions.
|
||||
- QA status and failed/warned rule count.
|
||||
- GEO score.
|
||||
- AI-flavor/style score.
|
||||
- Timing.
|
||||
- Changed sections.
|
||||
|
||||
The UI should mark content that needs user confirmation.
|
||||
The UI should mark content that needs user confirmation and should make
|
||||
`综合增强版` visually identifiable as the recommended default without hiding the
|
||||
other two candidates.
|
||||
|
||||
### Quality Report
|
||||
|
||||
@@ -98,9 +113,11 @@ Display each gate as pass, warn, or fail, with evidence, reason, suggested fix,
|
||||
|
||||
Downloads:
|
||||
|
||||
- `optimized.md`
|
||||
- `optimized.docx`
|
||||
- `qa_report.json`
|
||||
- Selected candidate: `optimized.md`, `optimized.docx`, `qa_report.json`.
|
||||
- Full comparison: `variant_comparison.json`.
|
||||
- If all candidate files are exported together, use stable Chinese labels in the
|
||||
metadata and ASCII-safe file names on disk, such as
|
||||
`standard-geo.md`, `anti-ai-flavor.md`, and `integrated-enhanced.md`.
|
||||
|
||||
## Internal Agent Nodes
|
||||
|
||||
@@ -110,11 +127,23 @@ The product is delivered as a simple web app, but the internals are split into e
|
||||
flowchart LR
|
||||
A["InputNormalizer"] --> B["FactExtractor"]
|
||||
B --> C["UserConfirmedFactCard"]
|
||||
C --> D["ArticleOptimizer"]
|
||||
D --> E["QualityInspector"]
|
||||
E -->|fail| F["TargetedRewriter"]
|
||||
F --> E
|
||||
E -->|pass/warn| G["Exporter"]
|
||||
C --> D["OptimizationVariantPlanner"]
|
||||
D --> E1["标准GEO版 ArticleOptimizer"]
|
||||
D --> E2["去AI味版 ArticleOptimizer"]
|
||||
D --> E3["综合增强版 ArticleOptimizer"]
|
||||
E1 --> F1["QualityInspector + StyleScorer"]
|
||||
E2 --> F2["QualityInspector + StyleScorer"]
|
||||
E3 --> F3["QualityInspector + StyleScorer"]
|
||||
F1 -->|fail| G1["TargetedRewriter"]
|
||||
F2 -->|fail| G2["TargetedRewriter"]
|
||||
F3 -->|fail| G3["TargetedRewriter"]
|
||||
G1 --> F1
|
||||
G2 --> F2
|
||||
G3 --> F3
|
||||
F1 --> H["VariantComparator"]
|
||||
F2 --> H
|
||||
F3 --> H
|
||||
H --> I["Exporter"]
|
||||
```
|
||||
|
||||
### LLM Provider Integration
|
||||
@@ -133,12 +162,14 @@ DEEPSEEK_THINKING=disabled
|
||||
|
||||
Rules:
|
||||
|
||||
- `src/lib/llm/client.ts` exposes `generateText`, `generateJson<T>`, `isLlmConfigured`, and `getLlmProviderStatus`.
|
||||
- `src/lib/llm/client.ts` exposes `generateText`, `generateJson<T>`,
|
||||
`generateValidatedJson`, `isLlmConfigured`, and `getLlmProviderStatus`.
|
||||
- `LLM_PROVIDER` defaults to `deepseek` when unset.
|
||||
- DeepSeek is accessed through the OpenAI-compatible SDK with `baseURL` set to `https://api.deepseek.com`.
|
||||
- `generateJson<T>` must use JSON output mode and prompts that explicitly require valid JSON only.
|
||||
- Thinking mode is disabled by default for deterministic article rewrites and structured QA output.
|
||||
- Missing credentials use deterministic local fallbacks so the MVP remains testable and usable without a live API key.
|
||||
- Missing credentials and provider failures surface as explicit API errors; the
|
||||
workflow must not silently fall back when the user expects live LLM behavior.
|
||||
- Provider errors are normalized inside the LLM client before they reach workflow nodes or API routes.
|
||||
|
||||
### InputNormalizer
|
||||
@@ -212,6 +243,49 @@ Forbidden:
|
||||
- Change industry.
|
||||
- Add exaggerated marketing promises.
|
||||
|
||||
### OptimizationVariantPlanner
|
||||
|
||||
Purpose: create a fixed set of candidate methods for one confirmed fact card.
|
||||
|
||||
The first comparison version always creates exactly three candidates:
|
||||
|
||||
| Variant Key | Label | Method |
|
||||
| --- | --- | --- |
|
||||
| `standard_geo` | `标准GEO版` | Current GEO rewrite behavior: fact-card fidelity, platform fit, clear structure, and QA repair. |
|
||||
| `anti_ai_flavor` | `去AI味版` | GEO rewrite plus localized Stop Slop rules to remove AI-flavored prose patterns. |
|
||||
| `integrated_enhanced` | `综合增强版` | Balances GEO density, factual trust, platform fit, readability, and AI-flavor reduction. |
|
||||
|
||||
Candidate generation may run sequentially in the first implementation to avoid
|
||||
provider rate-limit problems and to keep progress events understandable. The
|
||||
API response still returns the three candidates together for side-by-side
|
||||
comparison.
|
||||
|
||||
### Stop Slop / AI-Flavor Rules
|
||||
|
||||
The `hardikpandya/stop-slop` repository is an MIT-licensed writing skill rather
|
||||
than an installable runtime dependency. The original rules are mostly English
|
||||
writing rules, so the product should not copy them blindly into Chinese article
|
||||
optimization.
|
||||
|
||||
The first implementation uses localized guidance derived from the rule intent:
|
||||
|
||||
- Remove template openers and filler transitions, such as generic "本文将",
|
||||
"值得注意的是", "从某种意义上", and repeated "通过...实现..." chains.
|
||||
- Replace empty business language with concrete claims already present in the
|
||||
fact card.
|
||||
- Avoid formulaic contrast paragraphs that first list what something is not and
|
||||
then reveal what it is.
|
||||
- Avoid slogan-like short fragments that sound like pull quotes instead of
|
||||
article prose.
|
||||
- Prefer active, specific Chinese sentences with clear actors when the source
|
||||
facts identify an actor.
|
||||
- Vary paragraph length and sentence rhythm without using theatrical emphasis.
|
||||
|
||||
If substantial text from the upstream Stop Slop files is copied into this
|
||||
repository, add the MIT license notice to the committed artifact. A distilled
|
||||
Chinese rule set written for this product can live in source without vendoring
|
||||
the upstream repository.
|
||||
|
||||
### QualityInspector
|
||||
|
||||
Purpose: convert the document's issue list into executable quality gates.
|
||||
@@ -236,6 +310,53 @@ Examples:
|
||||
- Delete or mark unsupported claims for hallucination risk.
|
||||
- Warn instead of rewriting when image-text confidence is low.
|
||||
|
||||
### StyleScorer
|
||||
|
||||
Purpose: score each candidate for AI-flavor risk and naturalness without turning
|
||||
style concerns into hard QA failures.
|
||||
|
||||
The first version returns a 0-50 score with five 0-10 dimensions:
|
||||
|
||||
| Dimension | Question |
|
||||
| --- | --- |
|
||||
| `directness` | Does the article state concrete points instead of announcing them? |
|
||||
| `rhythm` | Do sentence and paragraph lengths vary naturally? |
|
||||
| `specificity` | Are claims concrete and tied to the fact card? |
|
||||
| `trust` | Does the prose avoid exaggerated intimacy, sweeping claims, and unsupported certainty? |
|
||||
| `density` | Can obvious filler be removed without losing meaning? |
|
||||
|
||||
Scores below 35 should show a visible warning on the candidate card. They should
|
||||
not block export.
|
||||
|
||||
### GeoScore
|
||||
|
||||
Purpose: reuse the existing GEO article performance rubric to score each
|
||||
candidate for fact integrity, platform fit, search intent fit, answer density,
|
||||
trust signal quality, and readability.
|
||||
|
||||
The score is computed from the candidate article plus its QA report. It is a
|
||||
comparison aid for the three candidates, not a publishing guarantee.
|
||||
|
||||
### VariantComparator
|
||||
|
||||
Purpose: assemble the candidate list for the API response and frontend.
|
||||
|
||||
Each candidate result includes:
|
||||
|
||||
- `variant_key`
|
||||
- `variant_label`
|
||||
- `method_summary`
|
||||
- `article`
|
||||
- `qa_report`
|
||||
- `geo_score`
|
||||
- `style_score`
|
||||
- `rewrite_rounds`
|
||||
- `timing`
|
||||
- `is_recommended`
|
||||
|
||||
`integrated_enhanced` is recommended by default unless it has a hard QA failure
|
||||
and another candidate does not.
|
||||
|
||||
## Quality Gates
|
||||
|
||||
| Rule ID | Issue Prevented | First Version Behavior |
|
||||
@@ -276,15 +397,25 @@ Examples:
|
||||
|
||||
The first version uses local SQLite plus an export folder.
|
||||
|
||||
The first implementation can reuse the existing `optimized_articles` and
|
||||
`qa_reports` tables by saving each candidate as a normal article revision with
|
||||
variant metadata inside the JSON payload. The matching QA report is saved
|
||||
against that revision. A separate comparison-run table is out of scope until the
|
||||
product needs historical side-by-side comparison beyond the immediate job
|
||||
result.
|
||||
|
||||
```text
|
||||
data/
|
||||
app.db
|
||||
exports/
|
||||
job_xxx/
|
||||
original.md
|
||||
optimized.md
|
||||
optimized.docx
|
||||
qa_report.json
|
||||
variant_comparison.json
|
||||
standard-geo.md
|
||||
anti-ai-flavor.md
|
||||
integrated-enhanced.md
|
||||
```
|
||||
|
||||
### `brand_template`
|
||||
@@ -358,6 +489,9 @@ One revision of optimized content.
|
||||
{
|
||||
"job_id": "job_xxx",
|
||||
"revision": 2,
|
||||
"variant_key": "integrated_enhanced",
|
||||
"variant_label": "综合增强版",
|
||||
"method_summary": "同时优化GEO信息密度、事实可信度、平台适配和表达自然度。",
|
||||
"title": "Optimized title",
|
||||
"summary": "Optimized summary",
|
||||
"body_markdown": "Optimized body in Markdown",
|
||||
@@ -367,7 +501,22 @@ One revision of optimized content.
|
||||
"suggestion": "Use product dashboard screenshot; avoid unrelated people photos"
|
||||
}
|
||||
],
|
||||
"changed_sections": ["title", "first paragraph"]
|
||||
"changed_sections": ["title", "first paragraph"],
|
||||
"geo_score": {
|
||||
"total": 8.1,
|
||||
"rationale": "事实一致性与答案密度较好,平台适配仍需复核。"
|
||||
},
|
||||
"style_score": {
|
||||
"total": 42,
|
||||
"dimensions": {
|
||||
"directness": 8,
|
||||
"rhythm": 8,
|
||||
"specificity": 9,
|
||||
"trust": 8,
|
||||
"density": 9
|
||||
},
|
||||
"warnings": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -408,9 +557,13 @@ Examples:
|
||||
|
||||
### QA Failure
|
||||
|
||||
Hard failures block export. Warnings allow export with visible confirmation prompts.
|
||||
Hard failures do not block export in the current product direction. The app must
|
||||
preserve export files and show visible warnings so the user can review the
|
||||
candidate manually.
|
||||
|
||||
Failed checks trigger targeted rewrite for up to two rounds. After two failed rounds, the app stops rewriting and shows manual review fields.
|
||||
Failed checks trigger targeted rewrite for up to two rounds inside each
|
||||
candidate. After two failed rounds, the app stops rewriting that candidate and
|
||||
shows manual review fields.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
@@ -420,9 +573,14 @@ The MVP is complete when:
|
||||
2. System can extract a fact card and require user confirmation.
|
||||
3. Confirmed fact card can be saved and reused as a local brand template.
|
||||
4. System can generate an optimized article without changing confirmed facts.
|
||||
5. System can generate a structured QA report for the 10 quality gates.
|
||||
6. Hard failures block export until fixed or manually reviewed.
|
||||
7. User can download Markdown and a basic Word document.
|
||||
5. System can generate exactly three labeled candidates: `标准GEO版`,
|
||||
`去AI味版`, and `综合增强版`.
|
||||
6. System can generate a structured QA report for the 10 quality gates for each
|
||||
candidate.
|
||||
7. System can score and compare the three candidates for AI-flavor/style quality.
|
||||
8. QA failures and low style scores remain visible but do not remove export links.
|
||||
9. User can download Markdown, a basic Word document, QA JSON, and a comparison
|
||||
JSON artifact.
|
||||
|
||||
## Minimum Test Samples
|
||||
|
||||
|
||||
Reference in New Issue
Block a user