mirror of
https://github.com/Tencent/WeKnora.git
synced 2026-06-04 13:30:32 +08:00
feat(graph): enhance graph extraction prompt rendering and language context handling
- Added a new method to render graph extraction prompts with shared placeholders for language. - Updated entity and relationship extraction methods to utilize the new rendering function, improving prompt customization. - Enhanced question generation task to include language context, ensuring prompts are generated in the correct language. - Improved error handling for empty prompt configurations in question generation, enhancing robustness.
This commit is contained in:
@@ -85,6 +85,14 @@ func NewGraphBuilder(config *config.Config, chatModel chat.Chat) types.GraphBuil
|
||||
}
|
||||
}
|
||||
|
||||
// renderGraphExtractionPrompt applies shared placeholders (e.g. {{language}}, {{lang}}) to graph extraction templates.
|
||||
func (b *graphBuilder) renderGraphExtractionPrompt(ctx context.Context, template string) string {
|
||||
lang := types.LanguageNameFromContext(ctx)
|
||||
return types.RenderPromptPlaceholders(template, types.PlaceholderValues{
|
||||
"language": lang,
|
||||
})
|
||||
}
|
||||
|
||||
// extractEntities extracts entities from text chunks
|
||||
// It uses LLM to analyze text content and identify relevant entities
|
||||
func (b *graphBuilder) extractEntities(ctx context.Context, chunk *types.Chunk) ([]*types.Entity, error) {
|
||||
@@ -101,7 +109,7 @@ func (b *graphBuilder) extractEntities(ctx context.Context, chunk *types.Chunk)
|
||||
messages := []chat.Message{
|
||||
{
|
||||
Role: "system",
|
||||
Content: b.config.Conversation.ExtractEntitiesPrompt,
|
||||
Content: b.renderGraphExtractionPrompt(ctx, b.config.Conversation.ExtractEntitiesPrompt),
|
||||
},
|
||||
{
|
||||
Role: "user",
|
||||
@@ -212,7 +220,7 @@ func (b *graphBuilder) extractRelationships(ctx context.Context,
|
||||
messages := []chat.Message{
|
||||
{
|
||||
Role: "system",
|
||||
Content: b.config.Conversation.ExtractRelationshipsPrompt,
|
||||
Content: b.renderGraphExtractionPrompt(ctx, b.config.Conversation.ExtractRelationshipsPrompt),
|
||||
},
|
||||
{
|
||||
Role: "user",
|
||||
|
||||
@@ -1910,11 +1910,13 @@ func (s *knowledgeService) enqueueQuestionGenerationTask(ctx context.Context,
|
||||
kbID, knowledgeID string, questionCount int,
|
||||
) {
|
||||
tenantID := ctx.Value(types.TenantIDContextKey).(uint64)
|
||||
lang, _ := types.LanguageFromContext(ctx)
|
||||
payload := types.QuestionGenerationPayload{
|
||||
TenantID: tenantID,
|
||||
KnowledgeBaseID: kbID,
|
||||
KnowledgeID: knowledgeID,
|
||||
QuestionCount: questionCount,
|
||||
Language: lang,
|
||||
}
|
||||
|
||||
payloadBytes, err := json.Marshal(payload)
|
||||
@@ -2160,6 +2162,14 @@ func (s *knowledgeService) ProcessQuestionGeneration(ctx context.Context, t *asy
|
||||
|
||||
// Set tenant context
|
||||
ctx = context.WithValue(ctx, types.TenantIDContextKey, payload.TenantID)
|
||||
if payload.Language != "" {
|
||||
ctx = context.WithValue(ctx, types.LanguageContextKey, payload.Language)
|
||||
}
|
||||
|
||||
if strings.TrimSpace(s.config.Conversation.GenerateQuestionsPrompt) == "" {
|
||||
logger.Errorf(ctx, "GenerateQuestionsPrompt is empty: configure conversation.generate_questions_prompt_id")
|
||||
return fmt.Errorf("generate questions prompt not configured")
|
||||
}
|
||||
|
||||
// Get knowledge base
|
||||
kb, err := s.kbService.GetKnowledgeBaseByID(ctx, payload.KnowledgeBaseID)
|
||||
@@ -2324,10 +2334,9 @@ func (s *knowledgeService) generateQuestionsWithContext(ctx context.Context,
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Build prompt with context
|
||||
prompt := s.config.Conversation.GenerateQuestionsPrompt
|
||||
prompt := strings.TrimSpace(s.config.Conversation.GenerateQuestionsPrompt)
|
||||
if prompt == "" {
|
||||
prompt = defaultQuestionGenerationPrompt
|
||||
return nil, fmt.Errorf("generate questions prompt not configured")
|
||||
}
|
||||
|
||||
// Build context section
|
||||
@@ -2343,11 +2352,14 @@ func (s *knowledgeService) generateQuestionsWithContext(ctx context.Context,
|
||||
contextSection += "\n"
|
||||
}
|
||||
|
||||
// Replace placeholders
|
||||
prompt = strings.ReplaceAll(prompt, "{{question_count}}", fmt.Sprintf("%d", questionCount))
|
||||
prompt = strings.ReplaceAll(prompt, "{{content}}", content)
|
||||
prompt = strings.ReplaceAll(prompt, "{{context}}", contextSection)
|
||||
prompt = strings.ReplaceAll(prompt, "{{doc_name}}", docName)
|
||||
langName := types.LanguageNameFromContext(ctx)
|
||||
prompt = types.RenderPromptPlaceholders(prompt, types.PlaceholderValues{
|
||||
"question_count": fmt.Sprintf("%d", questionCount),
|
||||
"content": content,
|
||||
"context": contextSection,
|
||||
"doc_name": docName,
|
||||
"language": langName,
|
||||
})
|
||||
|
||||
thinking := false
|
||||
response, err := chatModel.Chat(ctx, []chat.Message{
|
||||
@@ -2385,40 +2397,6 @@ func (s *knowledgeService) generateQuestionsWithContext(ctx context.Context,
|
||||
return questions, nil
|
||||
}
|
||||
|
||||
// Default prompt for question generation with context support
|
||||
const defaultQuestionGenerationPrompt = `You are a professional question generation assistant. Your task is to generate related questions that users might ask based on the given [Main Content].
|
||||
|
||||
{{context}}
|
||||
## Main Content (generate questions based on this content)
|
||||
Document name: {{doc_name}}
|
||||
Document content:
|
||||
{{content}}
|
||||
|
||||
## Core Requirements
|
||||
- Generated questions must be directly related to the [Main Content]
|
||||
- Questions must NOT use any pronouns or referential words (such as "it", "this", "that document", "this article", "the text", "its", etc.); use specific names instead
|
||||
- Questions must be complete and self-contained, understandable without additional context
|
||||
- Questions should be natural questions that users would likely ask in real scenarios
|
||||
- Questions should be diverse, covering different aspects of the content
|
||||
- Each question should be concise and clear, within 30 words
|
||||
- Generate {{question_count}} questions
|
||||
|
||||
## Suggested Question Types
|
||||
- Definition: What is...? What does... mean?
|
||||
- Reason: Why...? What is the reason for...?
|
||||
- Method: How to...? What is the way to...?
|
||||
- Comparison: What is the difference between... and...?
|
||||
- Application: What scenarios can... be used for?
|
||||
|
||||
## Output Format
|
||||
Output the question list directly, one question per line, without numbering or other prefixes.
|
||||
|
||||
## CRITICAL: Language Rule
|
||||
- Generate questions in the SAME LANGUAGE as the source document
|
||||
- If the document is in Korean, generate questions in Korean
|
||||
- If the document is in English, generate questions in English
|
||||
- If the document is in Chinese, generate questions in Chinese`
|
||||
|
||||
// GetKnowledgeFile retrieves the physical file associated with a knowledge entry
|
||||
func (s *knowledgeService) GetKnowledgeFile(ctx context.Context, id string) (io.ReadCloser, string, error) {
|
||||
// Get knowledge record
|
||||
|
||||
Reference in New Issue
Block a user