fix2
This commit is contained in:
parent
eef4a0f985
commit
cdda235597
|
|
@ -45,6 +45,13 @@ func MinBreadthGraphNodes() int {
|
||||||
return minBreadthNodes
|
return minBreadthNodes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func KnowledgeGraphJSONOnlyRetryPrompt() string {
|
||||||
|
return strings.TrimSpace(`上次回覆沒有包含可解析的 JSON。請**只**輸出一個 JSON 物件:
|
||||||
|
- 直接以 { 開頭、以 } 結尾,不要任何思考過程、說明文字或 markdown 圍欄
|
||||||
|
- 結構需含 nodes 與 edges 陣列,欄位齊全
|
||||||
|
- 不要使用 ... 省略,也不要加註解或尾端逗號`)
|
||||||
|
}
|
||||||
|
|
||||||
func KnowledgeGraphRetryUserPrompt() string {
|
func KnowledgeGraphRetryUserPrompt() string {
|
||||||
return strings.TrimSpace(`上次產出過於簡略或節點不足。請重新產出完整 TKG JSON:
|
return strings.TrimSpace(`上次產出過於簡略或節點不足。請重新產出完整 TKG JSON:
|
||||||
- 節點總數 **24~32 個**,L1≥8、L2≥12(廣度優先,多方向觸及)
|
- 節點總數 **24~32 個**,L1≥8、L2≥12(廣度優先,多方向觸及)
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,13 @@ func BuildResearchMapUserPrompt(in ResearchMapInput) string {
|
||||||
return BuildResearchMapFinalizeUserPrompt(in, "")
|
return BuildResearchMapFinalizeUserPrompt(in, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ResearchMapJSONOnlyRetryPrompt() string {
|
||||||
|
return strings.TrimSpace(`上次回覆沒有包含可解析的 JSON。請**只**輸出一個 JSON 物件:
|
||||||
|
- 直接以 { 開頭、以 } 結尾,不要任何思考過程、說明文字或 markdown 圍欄
|
||||||
|
- 需含 audienceSummary、contentGoal、questions、pillars、exclusions、patrolKeywords 欄位
|
||||||
|
- 不要使用 ... 省略,也不要加註解或尾端逗號`)
|
||||||
|
}
|
||||||
|
|
||||||
func ResearchMapRetryUserPrompt() string {
|
func ResearchMapRetryUserPrompt() string {
|
||||||
return strings.TrimSpace(`上次產出過於簡略或項目不足。請重新產出完整 JSON,密度對齊系統 prompt 優秀範例:
|
return strings.TrimSpace(`上次產出過於簡略或項目不足。請重新產出完整 JSON,密度對齊系統 prompt 優秀範例:
|
||||||
- 必須緊扣【輸入資料】中的品牌、產品與主題目標,不可照搬範例用字
|
- 必須緊扣【輸入資料】中的品牌、產品與主題目標,不可照搬範例用字
|
||||||
|
|
|
||||||
|
|
@ -265,13 +265,38 @@ func runExpandGraph(ctx context.Context, step StepContext, deps ExpandGraphDeps)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
graph, err := libkg.ParseSynthOutput(result.Text, libkg.SynthInput{
|
synthIn := libkg.SynthInput{
|
||||||
Seed: seed,
|
Seed: seed,
|
||||||
ProductBrief: productBrief,
|
ProductBrief: productBrief,
|
||||||
TargetAudience: brand.TargetAudience,
|
TargetAudience: brand.TargetAudience,
|
||||||
}, braveSources)
|
}
|
||||||
|
graph, err := libkg.ParseSynthOutput(result.Text, synthIn, braveSources)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return app.For(code.AI).SvcThirdParty("延伸知識產生失敗,請重試:" + err.Error())
|
// The model occasionally replies with reasoning/prose and no JSON
|
||||||
|
// object. Retry once, explicitly demanding a raw JSON object.
|
||||||
|
jsonOnlyReq := placement.ResearchGenerateRequest(domai.GenerateRequest{
|
||||||
|
Provider: providerID,
|
||||||
|
Model: credential.Model,
|
||||||
|
Credential: domai.Credential{
|
||||||
|
APIKey: credential.APIKey,
|
||||||
|
},
|
||||||
|
System: systemPrompt,
|
||||||
|
Messages: []domai.Message{
|
||||||
|
{Role: "user", Content: userPrompt},
|
||||||
|
{Role: "assistant", Content: result.Text},
|
||||||
|
{Role: "user", Content: libkg.KnowledgeGraphJSONOnlyRetryPrompt()},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
retryResult, retryErr := deps.AI.GenerateText(ctx, jsonOnlyReq)
|
||||||
|
if retryErr != nil {
|
||||||
|
return app.For(code.AI).SvcThirdParty("延伸知識產生失敗,請重試:" + err.Error())
|
||||||
|
}
|
||||||
|
retryGraph, retryParseErr := libkg.ParseSynthOutput(retryResult.Text, synthIn, braveSources)
|
||||||
|
if retryParseErr != nil {
|
||||||
|
return app.For(code.AI).SvcThirdParty("延伸知識產生失敗,請重試:" + retryParseErr.Error())
|
||||||
|
}
|
||||||
|
graph = retryGraph
|
||||||
|
result = retryResult
|
||||||
}
|
}
|
||||||
if libkg.GraphTooThin(graph) {
|
if libkg.GraphTooThin(graph) {
|
||||||
retryReq := placement.ResearchGenerateRequest(domai.GenerateRequest{
|
retryReq := placement.ResearchGenerateRequest(domai.GenerateRequest{
|
||||||
|
|
@ -288,11 +313,7 @@ func runExpandGraph(ctx context.Context, step StepContext, deps ExpandGraphDeps)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if retryResult, retryErr := deps.AI.GenerateText(ctx, retryReq); retryErr == nil {
|
if retryResult, retryErr := deps.AI.GenerateText(ctx, retryReq); retryErr == nil {
|
||||||
if retryGraph, parseErr := libkg.ParseSynthOutput(retryResult.Text, libkg.SynthInput{
|
if retryGraph, parseErr := libkg.ParseSynthOutput(retryResult.Text, synthIn, braveSources); parseErr == nil && !libkg.GraphTooThin(retryGraph) {
|
||||||
Seed: seed,
|
|
||||||
ProductBrief: productBrief,
|
|
||||||
TargetAudience: brand.TargetAudience,
|
|
||||||
}, braveSources); parseErr == nil && !libkg.GraphTooThin(retryGraph) {
|
|
||||||
graph = retryGraph
|
graph = retryGraph
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -724,7 +745,29 @@ func ensureResearchMap(
|
||||||
|
|
||||||
parsed, err := placement.ParseResearchMapOutput(result.Text)
|
parsed, err := placement.ParseResearchMapOutput(result.Text)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return app.For(code.AI).SvcThirdParty("研究地圖產生失敗,請重試:" + err.Error())
|
// Model sometimes replies with reasoning/prose and no JSON object.
|
||||||
|
// Retry once, explicitly demanding a raw JSON object.
|
||||||
|
jsonOnlyResult, retryErr := deps.AI.GenerateText(ctx, placement.ResearchGenerateRequest(domai.GenerateRequest{
|
||||||
|
Provider: providerID,
|
||||||
|
Model: credential.Model,
|
||||||
|
Credential: domai.Credential{
|
||||||
|
APIKey: credential.APIKey,
|
||||||
|
},
|
||||||
|
System: placement.BuildResearchMapSystemPrompt(),
|
||||||
|
Messages: []domai.Message{
|
||||||
|
{Role: "user", Content: finalPrompt},
|
||||||
|
{Role: "assistant", Content: result.Text},
|
||||||
|
{Role: "user", Content: placement.ResearchMapJSONOnlyRetryPrompt()},
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
if retryErr != nil {
|
||||||
|
return app.For(code.AI).SvcThirdParty("研究地圖產生失敗,請重試:" + err.Error())
|
||||||
|
}
|
||||||
|
parsed, err = placement.ParseResearchMapOutput(jsonOnlyResult.Text)
|
||||||
|
if err != nil {
|
||||||
|
return app.For(code.AI).SvcThirdParty("研究地圖產生失敗,請重試:" + err.Error())
|
||||||
|
}
|
||||||
|
result = jsonOnlyResult
|
||||||
}
|
}
|
||||||
if placement.ResearchMapTooThin(parsed) {
|
if placement.ResearchMapTooThin(parsed) {
|
||||||
if retryResult, retryErr := deps.AI.GenerateText(ctx, placement.ResearchGenerateRequest(domai.GenerateRequest{
|
if retryResult, retryErr := deps.AI.GenerateText(ctx, placement.ResearchGenerateRequest(domai.GenerateRequest{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue