subx_cli/services/ai/
prompts.rs1use crate::Result;
2use crate::error::SubXError;
3use crate::services::ai::{AnalysisRequest, ConfidenceScore, MatchResult, VerificationRequest};
4use serde_json;
5
6impl super::OpenAIClient {
7 pub fn build_analysis_prompt(&self, request: &AnalysisRequest) -> String {
9 let mut prompt = String::new();
10 prompt.push_str("請分析以下影片和字幕檔案的匹配關係:\n\n");
11
12 prompt.push_str("影片檔案:\n");
13 for video in &request.video_files {
14 prompt.push_str(&format!("- {}\n", video));
15 }
16
17 prompt.push_str("\n字幕檔案:\n");
18 for subtitle in &request.subtitle_files {
19 prompt.push_str(&format!("- {}\n", subtitle));
20 }
21
22 if !request.content_samples.is_empty() {
23 prompt.push_str("\n字幕內容預覽:\n");
24 for sample in &request.content_samples {
25 prompt.push_str(&format!("檔案: {}\n", sample.filename));
26 prompt.push_str(&format!("內容: {}\n\n", sample.content_preview));
27 }
28 }
29
30 prompt.push_str(
31 "請根據檔名模式等因素,提供匹配建議。\n\
32 回應格式為 JSON:\n\
33 {\n\
34 \"matches\": [\n\
35 {\n\
36 \"video_file\": \"影片檔名\",\n\
37 \"subtitle_file\": \"字幕檔名\",\n\
38 \"confidence\": 0.95,\n\
39 \"match_factors\": [\"檔名相似\"]\n\
40 }\n\
41 ],\n\
42 \"confidence\": 0.9,\n\
43 \"reasoning\": \"匹配原因說明\"\n\
44 }",
45 );
46
47 prompt
48 }
49
50 pub fn parse_match_result(&self, response: &str) -> Result<MatchResult> {
52 let json_start = response.find('{').unwrap_or(0);
53 let json_end = response.rfind('}').map(|i| i + 1).unwrap_or(response.len());
54 let json_str = &response[json_start..json_end];
55
56 serde_json::from_str(json_str)
57 .map_err(|e| SubXError::AiService(format!("AI 回應解析失敗: {}", e)))
58 }
59
60 pub fn build_verification_prompt(&self, request: &VerificationRequest) -> String {
62 let mut prompt = String::new();
63 prompt.push_str("請根據以下匹配資訊評估信心度:\n");
64 prompt.push_str(&format!("影片檔案: {}\n", request.video_file));
65 prompt.push_str(&format!("字幕檔案: {}\n", request.subtitle_file));
66 prompt.push_str("匹配因素:\n");
67 for factor in &request.match_factors {
68 prompt.push_str(&format!("- {}\n", factor));
69 }
70 prompt.push_str(
71 "\n請以 JSON 格式回應,格式如下:\n{\n \"score\": 0.9,\n \"factors\": [\"...\"]\n}",
72 );
73 prompt
74 }
75
76 pub fn parse_confidence_score(&self, response: &str) -> Result<ConfidenceScore> {
78 let json_start = response.find('{').unwrap_or(0);
79 let json_end = response.rfind('}').map(|i| i + 1).unwrap_or(response.len());
80 let json_str = &response[json_start..json_end];
81
82 serde_json::from_str(json_str)
83 .map_err(|e| SubXError::AiService(format!("AI 信心度解析失敗: {}", e)))
84 }
85}