Question generation: scenario-based 3-step prompt with technique labeling, key_points constrained to KB source, temperature 0.1. Generator node: two-step extraction prompt for assessment flow.
This commit is contained in:
@@ -89,96 +89,82 @@ export const questionGeneratorNode = async (
|
|||||||
.map((q, i) => `Q${i + 1}: ${q.questionText}`)
|
.map((q, i) => `Q${i + 1}: ${q.questionText}`)
|
||||||
.join('\n');
|
.join('\n');
|
||||||
|
|
||||||
const systemPromptZh = `你是一位严格的知识评估专家。你必须**仅基于**下方提供的知识库内容来生成测试题目。
|
const systemPromptZh = `你是一个信息提取工具。严格按以下步骤操作。
|
||||||
|
|
||||||
### 核心铁律(违反将导致题目无效):
|
### 第一步:提取知识点
|
||||||
1. **所有题目必须直接来源于提供的知识库内容**,每个题目必须能找到对应的原文依据
|
阅读下方 Human 消息中的【知识库内容】,逐条列出其中包含的所有可考核知识点。
|
||||||
2. **绝对禁止**编造知识库内容中未提及的概念、术语、流程或数据
|
每条以"知识点N:"开头,引用原文语句。如果不足,诚实报告。
|
||||||
3. **绝对禁止**使用你自身知识库中的内容来编造题目
|
|
||||||
4. 如果知识库内容不足以出题,诚实地报告而不是编造
|
|
||||||
|
|
||||||
### 强制性语言规则:
|
### 第二步:从知识点生成考题
|
||||||
**必须使用中文 (Simplified Chinese) 进行回复**。
|
仅用第一步提取的知识点生成 1 道题。必须引用知识点编号。
|
||||||
|
|
||||||
### 多样性规则:
|
### 绝对禁止:
|
||||||
${rulesZh}
|
- 禁止使用知识库内容中不存在的任何概念、术语、数据
|
||||||
|
- 禁止使用你自己的知识
|
||||||
|
${existingQuestionsText ? `- 禁止与已出题目重复:${existingQuestionsText}` : ''}
|
||||||
|
|
||||||
### 禁止重复列表(已出过):
|
### 输出(纯 JSON 数组):
|
||||||
${existingQuestionsText || '无'}
|
|
||||||
|
|
||||||
### 任务:
|
|
||||||
${hasKeywords ? `目标关键词:${keywordText}\n` : ''}出题风格:${style}
|
|
||||||
难度:${difficultyText}
|
|
||||||
|
|
||||||
请以 JSON 数组格式返回 1 个问题:
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"question_text": "...",
|
"knowledge_points": ["知识点引用"],
|
||||||
"key_points": ["点1", "点2"],
|
"question_text": "基于知识点的题目",
|
||||||
"difficulty": "...",
|
"key_points": ["评分要点"],
|
||||||
"dimension": "prompt/llm/ide/devPattern/workCapability",
|
"difficulty": "STANDARD|ADVANCED|SPECIALIST",
|
||||||
"basis": "【必须填写】从知识库中引用与此题相关的原文内容,用引号标注来源段落"
|
"dimension": "prompt|llm|ide|devPattern|workCapability",
|
||||||
|
"basis": "知识库原文"
|
||||||
}
|
}
|
||||||
]`;
|
]`;
|
||||||
// dimension取值:prompt=提示词, llm=LLM原理, ide=IDE协作, devPattern=开发范式, workCapability=工作能力
|
// dimension取值:prompt=提示词, llm=LLM原理, ide=IDE协作, devPattern=开发范式, workCapability=工作能力
|
||||||
|
|
||||||
const systemPromptJa = `あなたは厳格な知識評価の専門家です。提供されたナレッジベースの内容**のみ**に基づいて問題を作成してください。
|
const systemPromptJa = `あなたは情報抽出ツールです。以下の手順に厳密に従ってください。
|
||||||
|
|
||||||
### 核心鉄則(違反した問題は無効):
|
### 第一歩:知識ポイントの抽出
|
||||||
1. **すべての問題は提供されたナレッジベースから直接導出**し、各問題に原文の根拠が必要
|
Human メッセージ内の【ナレッジベース内容】を読み、含まれるすべての評価可能な知識ポイントを箇条書きで抽出。
|
||||||
2. **絶対禁止**:ナレッジベースに記載されていない概念、用語、プロセス、データを作り出すこと
|
各項目は「知識ポイントN:」で始め、原文を引用。不足している場合は正直に報告。
|
||||||
3. **絶対禁止**:自身の知識ベースの内容を問題として使用すること
|
|
||||||
4. 内容が不十分な場合は、正直に報告し、捏造しないこと
|
|
||||||
|
|
||||||
### 言語ルール(最重要):
|
### 第二歩:知識ポイントから問題を作成
|
||||||
**必ず日本語で作成してください**。中国語が混ざらないように厳格に注意してください。
|
第一歩で抽出した知識ポイントのみを使用して 1 問作成。知識ポイント番号を引用すること。
|
||||||
|
|
||||||
### 多様性ルール:
|
### 絶対禁止:
|
||||||
${rulesJa}
|
- ナレッジベースに存在しない概念、用語、データの使用
|
||||||
|
- 自身の知識の使用
|
||||||
|
${existingQuestionsText ? `- 作成済み問題との重複禁止:${existingQuestionsText}` : ''}
|
||||||
|
|
||||||
### 作成済み問題リスト:
|
### 出力(純粋な JSON 配列):
|
||||||
${existingQuestionsText || 'なし'}
|
|
||||||
|
|
||||||
### 任務:
|
|
||||||
${hasKeywords ? `目標キーワード:${keywordText}\n` : ''}出題スタイル:${style}
|
|
||||||
難易度:${difficultyText}
|
|
||||||
|
|
||||||
以下のJSON配列形式で問題を1つ返してください:
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"question_text": "...",
|
"knowledge_points": ["知識ポイント参照"],
|
||||||
"key_points": ["ポイント1", "ポイント2"],
|
"question_text": "知識ポイントに基づく問題",
|
||||||
"difficulty": "...",
|
"key_points": ["採点ポイント"],
|
||||||
"dimension": "prompt/llm/ide/devPattern/workCapability",
|
"difficulty": "STANDARD|ADVANCED|SPECIALIST",
|
||||||
"basis": "【必須】ナレッジベースから関連する原文を引用し、出典段落を明記"
|
"dimension": "prompt|llm|ide|devPattern|workCapability",
|
||||||
|
"basis": "ナレッジベースの原文"
|
||||||
}
|
}
|
||||||
]`;
|
]`;
|
||||||
|
|
||||||
const systemPromptEn = `You are a strict knowledge assessment expert. You MUST generate questions **ONLY** from the provided knowledge base content below.
|
const systemPromptEn = `You are an information extraction tool. Follow these steps exactly.
|
||||||
|
|
||||||
### Core Rules (violations invalidate the question):
|
### Step 1: Extract Knowledge Points
|
||||||
1. **All questions MUST directly derive from the provided content**, each question requires a verifiable source reference
|
Read the knowledge base content in the Human message. List ALL assessable knowledge points found.
|
||||||
2. **ABSOLUTELY FORBIDDEN**: inventing concepts, terminology, processes, or data not in the provided content
|
Each point must start with "KP N:" and quote the source text. If insufficient, honestly report.
|
||||||
3. **ABSOLUTELY FORBIDDEN**: using your own knowledge to fabricate questions
|
|
||||||
4. If content is insufficient, honestly report rather than fabricate
|
|
||||||
|
|
||||||
### Language Rule:
|
### Step 2: Generate Question from Points
|
||||||
**You MUST generate the question and key points in English.**
|
Use ONLY the knowledge points from Step 1 to generate 1 question. Must reference KP numbers.
|
||||||
|
|
||||||
### Diversity Rules:
|
### Absolutely Forbidden:
|
||||||
${rulesEn}
|
- Using any concept, term, or data NOT present in the knowledge base content
|
||||||
|
- Using your own knowledge
|
||||||
|
${existingQuestionsText ? `- Repeating previous questions: ${existingQuestionsText}` : ''}
|
||||||
|
|
||||||
### Previous Questions (DO NOT REPEAT):
|
### Output (pure JSON array only):
|
||||||
${existingQuestionsText || 'None'}
|
|
||||||
|
|
||||||
Return 1 question as a JSON array with format:
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"question_text": "...",
|
"knowledge_points": ["KP reference"],
|
||||||
"key_points": ["point1", "point2"],
|
"question_text": "Question based on the knowledge points",
|
||||||
"difficulty": "...",
|
"key_points": ["scoring points"],
|
||||||
"dimension": "prompt/llm/ide/devPattern/workCapability",
|
"difficulty": "STANDARD|ADVANCED|SPECIALIST",
|
||||||
"basis": "【REQUIRED】Cite the specific source text from the knowledge base, noting the source paragraph"
|
"dimension": "prompt|llm|ide|devPattern|workCapability",
|
||||||
|
"basis": "Source text from knowledge base"
|
||||||
}
|
}
|
||||||
]`;
|
]`;
|
||||||
|
|
||||||
|
|||||||
@@ -295,45 +295,43 @@ export class QuestionBankService {
|
|||||||
const model = new ChatOpenAI({
|
const model = new ChatOpenAI({
|
||||||
apiKey: modelConfig.apiKey || 'ollama',
|
apiKey: modelConfig.apiKey || 'ollama',
|
||||||
modelName: modelConfig.modelId,
|
modelName: modelConfig.modelId,
|
||||||
temperature: 0.3,
|
temperature: 0.1,
|
||||||
configuration: {
|
configuration: {
|
||||||
baseURL: modelConfig.baseUrl || 'https://api.deepseek.com/v1',
|
baseURL: modelConfig.baseUrl || 'https://api.deepseek.com/v1',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const systemPrompt = `你是一位严格的知识评估专家。你必须**仅基于**下方 Human 消息中提供的【知识库内容】来生成题目。
|
const systemPrompt = `你是一个实战考核设计专家。你要做三件事(在脑中完成,不要输出中间过程)。
|
||||||
|
|
||||||
### 核心铁律(违反将导致题目无效):
|
### 内部步骤(不要输出):
|
||||||
1. **所有题目必须直接来源于提供的知识库内容**,每个题目必须能找到对应的原文依据
|
1. 从知识库提取可考核的实战知识点
|
||||||
2. **绝对禁止**编造知识库内容中未提及的概念、术语、流程或数据
|
2. 确定该知识点对应的**具体技巧或方法**,这将成为考核目标
|
||||||
3. **绝对禁止**使用你自身知识库中的内容来编造题目
|
3. 围绕该技巧设计一个真实工作场景
|
||||||
4. 如果知识库内容不足以生成 ${count} 道有意义的题目,可以生成少于 ${count} 道,但题目质量优先
|
|
||||||
|
|
||||||
### 格式要求:
|
### 出题规则:
|
||||||
请以 JSON 数组格式返回题目:
|
- 题目格式:"【场景】具体场景描述 【问题】请描述你会如何处理"
|
||||||
|
- 场景中暗示需要什么能力,但不要说破
|
||||||
|
- **绝对禁止**概念题、选择题
|
||||||
|
|
||||||
|
### 评分标准来源(严格遵守):
|
||||||
|
- key_points 必须从知识库原文中提取,不得自行编造评分标准
|
||||||
|
- 每个 key_point 必须是知识库中明确提及的要素
|
||||||
|
- **禁止**添加知识库中没有的方法、工具、格式(如 Markdown)
|
||||||
|
|
||||||
|
### 只输出 JSON:
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"question_text": "基于知识库内容的实际问题",
|
"knowledge_points": ["知识点原文"],
|
||||||
"key_points": ["评分要点1", "评分要点2"],
|
"technique": "此题考查的具体技巧名称",
|
||||||
"difficulty": "STANDARD|ADVANCED|SPECIALIST",
|
"scenario": "实战场景",
|
||||||
|
"question_text": "【场景】... 【问题】请描述你会如何...",
|
||||||
|
"key_points": ["知识库中的评分要素", "知识库中的评分要素"],
|
||||||
|
"difficulty": "STANDARD",
|
||||||
"dimension": "prompt|llm|ide|devPattern|workCapability",
|
"dimension": "prompt|llm|ide|devPattern|workCapability",
|
||||||
"basis": "【必须填写】从知识库中引用与此题相关的原文内容,用引号标注来源段落"
|
"basis": "知识库原文依据"
|
||||||
}
|
}
|
||||||
]
|
]`;
|
||||||
|
const humanMsg = `【知识库内容 - 唯一来源】\n\n--- 开始 ---\n${knowledgeBaseContent}\n--- 结束 ---\n\n请按三步流程生成 ${count} 道简答题。难度以 STANDARD 为主。`;
|
||||||
### 维度说明(根据题目内容归类):
|
|
||||||
- prompt: 关于提示词设计、AI交互优化
|
|
||||||
- llm: 关于大语言模型原理、架构、参数
|
|
||||||
- ide: 关于开发工具使用、协作效率
|
|
||||||
- devPattern: 关于开发方法论、工程范式
|
|
||||||
- workCapability: 关于工作能力、综合素养
|
|
||||||
|
|
||||||
### 出题规范:
|
|
||||||
1. 每个题目必须标注 basis,引用知识库中的具体原文作为依据
|
|
||||||
2. 题目难度分布合理,覆盖 STANDARD/ADVANCED/SPECIALIST
|
|
||||||
3. 不同维度各出一部分,不要集中在一个维度`;
|
|
||||||
|
|
||||||
const humanMsg = `【知识库内容 - 以下是你出题的唯一依据】\n\n--- 知识库开始 ---\n${knowledgeBaseContent}\n--- 知识库结束 ---\n\n请严格基于以上知识库内容生成题目。`;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await model.invoke([
|
const response = await model.invoke([
|
||||||
@@ -369,12 +367,16 @@ export class QuestionBankService {
|
|||||||
for (const q of parsedQuestions) {
|
for (const q of parsedQuestions) {
|
||||||
const dimension = dimensionMap[q.dimension?.toLowerCase()] || 'WORK_CAPABILITY';
|
const dimension = dimensionMap[q.dimension?.toLowerCase()] || 'WORK_CAPABILITY';
|
||||||
const difficulty = difficultyMap[q.difficulty?.toUpperCase()] || 'STANDARD';
|
const difficulty = difficultyMap[q.difficulty?.toUpperCase()] || 'STANDARD';
|
||||||
|
const techniqueTag = q.technique ? `【考查技巧】${q.technique}` : null;
|
||||||
|
const keyPoints = techniqueTag
|
||||||
|
? [techniqueTag, ...(q.key_points || [])]
|
||||||
|
: (q.key_points || []);
|
||||||
|
|
||||||
const item = this.itemRepository.create({
|
const item = this.itemRepository.create({
|
||||||
bankId,
|
bankId,
|
||||||
questionText: q.question_text,
|
questionText: q.question_text,
|
||||||
questionType: QuestionType.SHORT_ANSWER,
|
questionType: QuestionType.SHORT_ANSWER,
|
||||||
keyPoints: q.key_points || [],
|
keyPoints,
|
||||||
difficulty: difficulty as QuestionDifficulty,
|
difficulty: difficulty as QuestionDifficulty,
|
||||||
dimension: dimension as QuestionDimension,
|
dimension: dimension as QuestionDimension,
|
||||||
basis: q.basis,
|
basis: q.basis,
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user