feat: use llm for fact extraction

This commit is contained in:
Codex
2026-06-21 23:43:02 +08:00
parent 864b1c72f9
commit 0c36f4b8a3
2 changed files with 83 additions and 0 deletions
@@ -0,0 +1,67 @@
import { afterEach, describe, expect, it, vi } from "vitest";
const llmMocks = vi.hoisted(() => ({
generateValidatedJson: vi.fn(),
}));
vi.mock("../../llm/client", async () => {
const actual = await vi.importActual<typeof import("../../llm/client")>(
"../../llm/client",
);
return {
...actual,
generateValidatedJson: llmMocks.generateValidatedJson,
};
});
import { extractCandidateFactCard } from "../fact-extractor";
describe("LLM workflow integration", () => {
afterEach(() => {
llmMocks.generateValidatedJson.mockReset();
});
it("uses LLM output for candidate fact extraction when valid", async () => {
llmMocks.generateValidatedJson.mockResolvedValueOnce({
company_full_name: "DeepSeek Example Co., Ltd.",
company_short_names: ["DeepSeek Example"],
brand_names: ["DSExample"],
product_names: ["DS GEO"],
target_industry: "GEO optimization",
target_audience: "Marketing teams",
experience_years: 9,
core_claims: ["9 years of GEO optimization experience"],
forbidden_claims: ["industry first"],
image_topics: ["dashboard"],
uncertain_items: [],
is_ready_for_optimization: true,
});
const card = await extractCandidateFactCard({
title: "Example source",
body: "Fallback Technology Co., Ltd. has 8 years of GEO optimization experience.",
images: [{ type: "description", content: "dashboard" }],
platform: "official_site",
user_instructions: "",
});
expect(card.company_full_name).toBe("DeepSeek Example Co., Ltd.");
expect(card.experience_years).toBe(9);
expect(llmMocks.generateValidatedJson).toHaveBeenCalledOnce();
});
it("falls back to deterministic candidate extraction when LLM returns null", async () => {
llmMocks.generateValidatedJson.mockResolvedValueOnce(null);
const card = await extractCandidateFactCard({
title: "Fallback Technology Co., Ltd. GEO guide",
body: "Fallback Technology Co., Ltd. has 8 years of GEO optimization experience.",
images: [{ type: "description", content: "dashboard" }],
platform: "official_site",
user_instructions: "",
});
expect(card.company_full_name).toBe("Fallback Technology Co., Ltd.");
expect(card.experience_years).toBe(8);
});
});
+16
View File
@@ -1,9 +1,25 @@
import type { ArticleInput, CandidateFactCard } from "../domain/types";
import { candidateFactCardSchema } from "../domain/validation";
import { generateValidatedJson } from "../llm/client";
import {
FACT_EXTRACTOR_SYSTEM_PROMPT,
buildFactExtractorPrompt,
} from "../llm/prompts";
export async function extractCandidateFactCard(
input: ArticleInput,
): Promise<CandidateFactCard> {
const llmCard = await generateValidatedJson({
schema: candidateFactCardSchema,
system: FACT_EXTRACTOR_SYSTEM_PROMPT,
prompt: buildFactExtractorPrompt(input),
temperature: 0.1,
});
return llmCard ?? extractCandidateFactCardFallback(input);
}
function extractCandidateFactCardFallback(input: ArticleInput): CandidateFactCard {
const text = `${input.title}\n${input.body}`;
const uncertainItems: string[] = [];
const companyFullName = findCompanyFullName(text);