AIQuestionStructService.php 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. <?php
  2. namespace App\Services;
  3. class AiQuestionStructService
  4. {
  5. public function buildQuestionFromSourcePrompt(string $sourceText): string
  6. {
  7. return app(QuestionPromptService::class)->buildQuestionFromSourcePrompt($sourceText);
  8. }
  9. public function detectQuestionBlocks(string $rawMarkdown): array
  10. {
  11. return [
  12. [
  13. 'raw_markdown' => $rawMarkdown,
  14. 'index' => 1,
  15. ],
  16. ];
  17. }
  18. public function extractFields(string $questionText): array
  19. {
  20. return [
  21. 'stem' => trim($questionText),
  22. 'options' => $this->extractOptions($questionText),
  23. 'answer' => null,
  24. 'solution' => null,
  25. ];
  26. }
  27. public function classifyQuestionType(string $questionText, array $options = []): string
  28. {
  29. if (!empty($options)) {
  30. return 'choice';
  31. }
  32. if (preg_match('/\b填空\b|\b选择\b/u', $questionText)) {
  33. return 'fill';
  34. }
  35. return 'answer';
  36. }
  37. public function estimateDifficulty(string $questionText, array $meta = []): int
  38. {
  39. $length = mb_strlen($questionText);
  40. if ($length <= 60) {
  41. return 1;
  42. }
  43. if ($length <= 120) {
  44. return 2;
  45. }
  46. return 3;
  47. }
  48. public function buildStructuredQuestion(array $raw, array $context = []): array
  49. {
  50. $fields = $this->extractFields((string) ($raw['raw_markdown'] ?? ''));
  51. $questionType = $this->classifyQuestionType((string) ($fields['stem'] ?? ''), $fields['options'] ?? []);
  52. return array_merge($raw, [
  53. 'question_type' => $questionType,
  54. 'difficulty' => $this->estimateDifficulty((string) ($fields['stem'] ?? ''), $context),
  55. ], $fields);
  56. }
  57. private function extractOptions(string $text): array
  58. {
  59. $options = [];
  60. preg_match_all('/^\s*([A-D])[\\.|.、\\)]\\s*(.+)$/m', $text, $matches, PREG_SET_ORDER);
  61. foreach ($matches as $match) {
  62. $options[] = [
  63. 'label' => $match[1],
  64. 'text' => trim($match[2]),
  65. ];
  66. }
  67. return $options;
  68. }
  69. }