Blog Generation
Overview
Blog generation has AI produce longer-form blog articles, in two families.
| Family | Description | Entry point |
|---|---|---|
| Rewrite | Rewrites an imported past blog without changing its content | Past blog detail screen |
| Original | Writes a new blog from race data (race recap / race prediction) | Race detail screen |
Both are marked "generating" while in flight and become a "draft" when complete. Publishing is an operator action.
Generated blogs are assembled using oddspark's real article designs, switching between the prediction, race result and generic templates depending on the category.
Rewriting
An imported past blog (old_blog) is rewritten for readability without changing its content.
flowchart TD
Import([Import a past blog]) --> Request([Operator requests a rewrite])
Request --> Generating[Blog is created as "generating"]
Generating --> Race{Is it tied to a race?}
Race -->|yes| Analyze[AI reads the race result, video and course image]
Race -->|no| Skip[Proceed with no race information]
Analyze --> Rewrite
Skip --> Rewrite[Rewrite, preserving content and voice]
Rewrite --> Summary[Generate the 10-second summary at the top]
Summary --> Build[Build the HTML with the design for the category]
Build --> Saved[Saved as a draft]
Rewriting policy
- Do not change the content โ preserve the original information and the author's voice
- Follow oddspark's tone-of-voice guideline
- Structure the text into building blocks matched to the content: headings, paragraphs, lists, prediction marks, interview Q&A, and so on
- For race-linked blogs, remove entry-list enumerations from the body (entrant and finishing-order data is rendered separately from the official data)
Blogs not tied to a race
Past blogs are not always tied to a race. When they are not, race video and result analysis is skipped and only a content-preserving rewrite is performed.
Original writing (race recaps and predictions)
Writes a blog from race data with no source article.
| Kind | When | Input | Precondition |
|---|---|---|---|
| Race recap | After the race | Race result, race video, course image (horse racing only) | The race has a finishing order |
| Race prediction | Before the race | Entry list and AI prediction marks | Prediction data is registered |
Predictions skip race video analysis, since the race has not run, and they never use result-derived information such as finishing order, payouts or times.
If the title is omitted, it is composed from the race name ("โฆใฎใฌใผในๅ้กง" / "โฆใฎใฌใผในไบๆณ"). The category is linked automatically too ("ใฌใผใน็ตๆใปๅ้กง" for recaps, "ใฌใผในไบๆณใปๆค่จผ" for predictions).
Prediction blogs need prediction data
Writing a prediction requires the pre-race entry list and AI prediction marks to be registered. Races without them cannot be generated.
How factual accuracy is protected
Original writing uses the same protections as article generation.
| Mechanism | Description |
|---|---|
| Eligibility check | Recaps are not generated for races with no finishing order (void / cancelled) |
| Value substitution | Entrant names, payout amounts, combinations and popularity are filled in from the official data |
| Fact checking | The text is checked for contradictions with the official race result |
| NG word screening | The text is scanned for prohibited words |
Anything detected triggers a rewrite (up to twice); if it still cannot be resolved, generation fails and nothing is published.
Rewrites are screened for NG words too, but words already present in the source past blog are excluded โ a rewrite preserves the content, so words that came from the source (e.g. part of a jockey's name) can never be removed by regenerating.
Blog status
| Status | Description |
|---|---|
| Generating | The request has been accepted and AI is producing the blog |
| Draft | Generated or manually created, not yet published |
| Published | An operator has published it |
Blogs have no 'failed' state
Unlike articles, a blog whose generation fails to the end is deleted entirely. A blog with an empty body lingering in the list would get in the way of re-running the rewrite.
What can be done after generation
| Action | Description |
|---|---|
| Edit the body or title | Edited directly by the operator; changing the title also updates the heading in the body |
| Thumbnail generation | Creates a thumbnail from the race video and embeds it in the body |
| Related information | Inserts links to the two most similar blogs at the bottom of the article |
Related information
Blogs are compared by "embedding vectors" โ numeric representations of what the text means โ and the two closest are inserted at the bottom of the article as "้ข้ฃๆ ๅ ฑ".
Candidates considered the same article are excluded.
| Exclusion | Reason |
|---|---|
| Blogs rewritten from the same past blog | Their vectors are identical |
| Blogs with an identical title | Duplicate registration of the same article |
| Blogs with effectively identical content | Treated as duplicates |
For race-linked blogs, a card pointing to the race result page is shown first.
Related features
- Article Generation: the 10-second race result summary
- Thumbnail Generation: creating a thumbnail from the race video
- Odds PoC: managing blogs and past blogs