更新三候选优化对比设计
This commit is contained in:
@@ -14,11 +14,16 @@ The MVP is a local web application:
|
|||||||
2. System extracts a candidate fact card.
|
2. System extracts a candidate fact card.
|
||||||
3. User confirms or edits the fact card.
|
3. User confirms or edits the fact card.
|
||||||
4. Confirmed fact card is saved as a reusable local brand template.
|
4. Confirmed fact card is saved as a reusable local brand template.
|
||||||
5. System optimizes the article under fact-card constraints.
|
5. System generates three optimization candidates under fact-card constraints:
|
||||||
6. System runs quality gates.
|
`标准GEO版`, `去AI味版`, and `综合增强版`.
|
||||||
7. Failed checks trigger targeted rewriting for up to two rounds.
|
6. System runs quality gates for each candidate.
|
||||||
8. User previews optimized content and QA report.
|
7. Failed checks trigger targeted rewriting for up to two rounds inside each
|
||||||
9. User downloads Markdown and a basic Word document.
|
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
|
## Explicitly Out Of Scope
|
||||||
|
|
||||||
@@ -36,12 +41,15 @@ The MVP is a local web application:
|
|||||||
flowchart TD
|
flowchart TD
|
||||||
A["Input Article"] --> B["Auto Analyze"]
|
A["Input Article"] --> B["Auto Analyze"]
|
||||||
B --> C["Confirm Fact Card"]
|
B --> C["Confirm Fact Card"]
|
||||||
C --> D["Optimize Article"]
|
C --> D["Generate Three Candidates"]
|
||||||
D --> E["Quality Check"]
|
D --> E1["标准GEO版 QA"]
|
||||||
E -->|Pass| F["Preview Result"]
|
D --> E2["去AI味版 QA"]
|
||||||
E -->|Fail| G["Targeted Rewrite"]
|
D --> E3["综合增强版 QA"]
|
||||||
G --> D
|
E1 --> F["Compare Results"]
|
||||||
F --> H["Download Markdown / Word"]
|
E2 --> F
|
||||||
|
E3 --> F
|
||||||
|
F --> G["Select Candidate"]
|
||||||
|
G --> H["Download Markdown / Word / QA"]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Page Areas
|
## Page Areas
|
||||||
@@ -78,17 +86,24 @@ Fields:
|
|||||||
|
|
||||||
The user must resolve uncertain items before optimization starts.
|
The user must resolve uncertain items before optimization starts.
|
||||||
|
|
||||||
### Optimized Result
|
### Candidate Comparison
|
||||||
|
|
||||||
Display:
|
Display:
|
||||||
|
|
||||||
|
- Candidate label: `标准GEO版`, `去AI味版`, or `综合增强版`.
|
||||||
|
- Method summary that explains what this candidate optimized for.
|
||||||
- Optimized title.
|
- Optimized title.
|
||||||
- Summary.
|
- Summary.
|
||||||
- Optimized body.
|
- Optimized body.
|
||||||
- Image suggestions.
|
- QA status and failed/warned rule count.
|
||||||
|
- GEO score.
|
||||||
|
- AI-flavor/style score.
|
||||||
|
- Timing.
|
||||||
- Changed sections.
|
- 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
|
### Quality Report
|
||||||
|
|
||||||
@@ -98,9 +113,11 @@ Display each gate as pass, warn, or fail, with evidence, reason, suggested fix,
|
|||||||
|
|
||||||
Downloads:
|
Downloads:
|
||||||
|
|
||||||
- `optimized.md`
|
- Selected candidate: `optimized.md`, `optimized.docx`, `qa_report.json`.
|
||||||
- `optimized.docx`
|
- Full comparison: `variant_comparison.json`.
|
||||||
- `qa_report.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
|
## 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
|
flowchart LR
|
||||||
A["InputNormalizer"] --> B["FactExtractor"]
|
A["InputNormalizer"] --> B["FactExtractor"]
|
||||||
B --> C["UserConfirmedFactCard"]
|
B --> C["UserConfirmedFactCard"]
|
||||||
C --> D["ArticleOptimizer"]
|
C --> D["OptimizationVariantPlanner"]
|
||||||
D --> E["QualityInspector"]
|
D --> E1["标准GEO版 ArticleOptimizer"]
|
||||||
E -->|fail| F["TargetedRewriter"]
|
D --> E2["去AI味版 ArticleOptimizer"]
|
||||||
F --> E
|
D --> E3["综合增强版 ArticleOptimizer"]
|
||||||
E -->|pass/warn| G["Exporter"]
|
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
|
### LLM Provider Integration
|
||||||
@@ -133,12 +162,14 @@ DEEPSEEK_THINKING=disabled
|
|||||||
|
|
||||||
Rules:
|
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.
|
- `LLM_PROVIDER` defaults to `deepseek` when unset.
|
||||||
- DeepSeek is accessed through the OpenAI-compatible SDK with `baseURL` set to `https://api.deepseek.com`.
|
- 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.
|
- `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.
|
- 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.
|
- Provider errors are normalized inside the LLM client before they reach workflow nodes or API routes.
|
||||||
|
|
||||||
### InputNormalizer
|
### InputNormalizer
|
||||||
@@ -212,6 +243,49 @@ Forbidden:
|
|||||||
- Change industry.
|
- Change industry.
|
||||||
- Add exaggerated marketing promises.
|
- 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
|
### QualityInspector
|
||||||
|
|
||||||
Purpose: convert the document's issue list into executable quality gates.
|
Purpose: convert the document's issue list into executable quality gates.
|
||||||
@@ -236,6 +310,53 @@ Examples:
|
|||||||
- Delete or mark unsupported claims for hallucination risk.
|
- Delete or mark unsupported claims for hallucination risk.
|
||||||
- Warn instead of rewriting when image-text confidence is low.
|
- 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
|
## Quality Gates
|
||||||
|
|
||||||
| Rule ID | Issue Prevented | First Version Behavior |
|
| Rule ID | Issue Prevented | First Version Behavior |
|
||||||
@@ -276,15 +397,25 @@ Examples:
|
|||||||
|
|
||||||
The first version uses local SQLite plus an export folder.
|
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
|
```text
|
||||||
data/
|
data/
|
||||||
app.db
|
app.db
|
||||||
exports/
|
exports/
|
||||||
job_xxx/
|
job_xxx/
|
||||||
original.md
|
|
||||||
optimized.md
|
optimized.md
|
||||||
optimized.docx
|
optimized.docx
|
||||||
qa_report.json
|
qa_report.json
|
||||||
|
variant_comparison.json
|
||||||
|
standard-geo.md
|
||||||
|
anti-ai-flavor.md
|
||||||
|
integrated-enhanced.md
|
||||||
```
|
```
|
||||||
|
|
||||||
### `brand_template`
|
### `brand_template`
|
||||||
@@ -358,6 +489,9 @@ One revision of optimized content.
|
|||||||
{
|
{
|
||||||
"job_id": "job_xxx",
|
"job_id": "job_xxx",
|
||||||
"revision": 2,
|
"revision": 2,
|
||||||
|
"variant_key": "integrated_enhanced",
|
||||||
|
"variant_label": "综合增强版",
|
||||||
|
"method_summary": "同时优化GEO信息密度、事实可信度、平台适配和表达自然度。",
|
||||||
"title": "Optimized title",
|
"title": "Optimized title",
|
||||||
"summary": "Optimized summary",
|
"summary": "Optimized summary",
|
||||||
"body_markdown": "Optimized body in Markdown",
|
"body_markdown": "Optimized body in Markdown",
|
||||||
@@ -367,7 +501,22 @@ One revision of optimized content.
|
|||||||
"suggestion": "Use product dashboard screenshot; avoid unrelated people photos"
|
"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
|
### 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
|
## Acceptance Criteria
|
||||||
|
|
||||||
@@ -420,9 +573,14 @@ The MVP is complete when:
|
|||||||
2. System can extract a fact card and require user confirmation.
|
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.
|
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.
|
4. System can generate an optimized article without changing confirmed facts.
|
||||||
5. System can generate a structured QA report for the 10 quality gates.
|
5. System can generate exactly three labeled candidates: `标准GEO版`,
|
||||||
6. Hard failures block export until fixed or manually reviewed.
|
`去AI味版`, and `综合增强版`.
|
||||||
7. User can download Markdown and a basic Word document.
|
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
|
## Minimum Test Samples
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user