# 大模型多模态能力(图片分析)调用示例总结(适配Claude Code规则) 本示例基于 **Angular框架** + **fmode-ng SDK**,调用多模态大模型(`fmode-1.6-cn`)的「视觉识别+文本理解」能力,实现**道德与法治题目图片的全流程处理**(图片OCR识别→结构化提取→答案解析→追问互动),核心是通过「视觉模态」突破纯文本输入限制,实现图片内容的语义化解析。 ## 一、核心基础信息 ### 1.1 技术栈与依赖 | 类别 | 具体内容 | |--------------|--------------------------------------------------------------------------| | 框架 | Angular(依赖注入`@Injectable`,服务级复用) | | 核心SDK | `fmode-ng`(提供多模态调用`completionJSON`、聊天流式输出`FmodeChatCompletion`) | | 数据存储 | Parse(`SurveyItem`存储题目/解析,`SurveyLog`存储搜题日志) | | 多模态模型 | `fmode-1.6-cn`(支持视觉+文本双模态,核心用于图片题目识别) | ### 1.2 关键常量定义(固定配置) ```typescript // 1. 多模态任务模板(关联后端模板逻辑) export const DaofaQuestionRecognitionTplCode = 'daofa-question-recognition-tpl'; // 题目识别模板 export const DaofaQATplCode = 'daofa-qa-tpl'; // 问答/追问模板 // 2. 多模态模型标识(必须指定支持视觉的模型) export const DaofaModel = 'fmode-1.6-cn'; ``` ## 二、多模态核心能力:图片题目识别(核心流程) ### 2.1 功能描述 通过大模型「视觉能力」解析上传的题目图片(如试卷、练习册拍照),将图片中的文字(题干、选项、材料)转化为**结构化JSON数据**(题型、关键词、选项等),是整个流程的「多模态入口」。 ### 2.2 代码实现与规则要点 ```typescript /** * 多模态核心:识别题目图片(视觉+文本) * @param options.images 图片数组(需为Base64格式,大模型视觉输入标准格式) * @param options.onProgressChange 进度回调(如“正在识别题目内容...”) * @returns 结构化存储的题目对象(SurveyItem) */ async recognizeQuestion(options: { images: string[]; // 关键:图片输入(Base64字符串数组,支持多图) onProgressChange?: (progress: string) => void; loading?: any; }): Promise { return new Promise(async (resolve, reject) => { try { // 1. 多模态提示词设计(规则1:结构化提示,强制输出JSON格式) const prompt = `请识别图片中的道德与法治题目,并按以下JSON格式输出: { "questionType": "题型(single-choice/multi-choice/judge/short-answer/material-analysis)", "title": "题目标题或简述", "content": "完整的题目内容", "options": [{"label": "A", "value": "选项内容"}], "material": "材料内容(如有)", "keywords": ["关键词1", "关键词2"] // 如“宪法、权利、义务” } 要求: 1. 准确识别题干、选项、材料的文字(含标点); 2. 严格匹配题型枚举值,不可自定义; 3. 关键词需贴合道德与法治学科核心概念。`; // 2. 输出格式约束(规则2:提供JSON示例,降低大模型输出偏差) const output = `{ "questionType": "single-choice", "title": "宪法基本权利题", "content": "下列属于公民基本权利的是?", "options": [{"label": "A", "value": "依法纳税"}], "material": "", "keywords": ["公民基本权利", "宪法"] }`; // 3. 调用多模态能力(规则3:视觉识别必须配置vision=true + 传入images) const questionData = await completionJSON( prompt, // 文本提示词 output, // 输出格式示例 (content) => { // 增量回调(可选,用于进度更新) options.loading?.message = `正在识别题目...${content?.length || 0}字`; }, 2, // 重试次数 { model: DaofaModel, // 指定多模态模型 vision: true, // 启用视觉能力(核心开关) images: options.images // 传入图片数组(Base64) } ); // 4. 结果校验(规则4:多模态输出必须先判空,避免后续流程异常) if (!questionData || !questionData.content) { throw new Error('题目识别结果为空(图片无有效文字或识别失败)'); } // 5. 数据持久化(规则5:识别结果映射到标准存储对象SurveyItem) const surveyItem = await this.saveSurveyItem({ type: 'daofa', // 学科标识 title: questionData.title || '未命名道德与法治题目', content: questionData.content, // 识别后的题干 images: options.images, // 关联原始图片 keywords: questionData.keywords || [], options: questionData.options || [], createOptions: { tpl: DaofaQuestionRecognitionTplCode, params: { questionType: questionData.questionType, recognitionMode: 'image-ocr', // 标记为“图片OCR识别”来源 material: questionData.material } } }); resolve(surveyItem); } catch (err: any) { reject(new Error(`图片识别失败:${err.message || '未知错误'}`)); } }); } ``` ## 三、配套能力:基于多模态结果的文本延伸 ### 3.1 功能1:答案与解析生成(纯文本模态,依赖图片识别结果) 将图片识别后的结构化题目(题干、选项、题型)传入大模型,生成符合「道德与法治学科规范」的解析(含标准答案、知识点、易错点等),支持**流式输出**(实时更新内容)。 ```typescript async generateAnswer(options: { surveyItem: FmodeObject; // 图片识别后的题目对象 onContentChange?: (content: string) => void; // 流式内容回调 }): Promise { return new Promise(async (resolve, reject) => { try { // 1. 从图片识别结果中提取关键信息(规则:复用多模态输出的结构化数据) const { content: questionContent, options: questionOptions } = options.surveyItem.attributes; const questionType = options.surveyItem.get('createOptions').params.questionType; // 2. 结构化提示词(规则:按学科要求分模块,确保解析专业度) const prompt = `作为道德与法治教师,解析以下题目: 题目类型:${questionType} 题目内容:${questionContent} ${questionOptions.length ? `选项:\n${questionOptions.map(opt => `${opt.label}. ${opt.value}`).join('\n')}` : ''} 要求按以下格式输出: 【标准答案】(选择题需标注选项,如“A”;简答题需分点) 【知识点】(关联教材章节/法律条文,如“《宪法》第33条 公民在法律面前一律平等”) 【解题思路】(初中生易懂,结合生活实例) 【易错点】(如“混淆‘权利’与‘义务’,依法纳税是义务而非权利”) 【知识拓展】(关联时政热点,如“2024年法治宣传周主题”)`; // 3. 流式调用(规则:使用FmodeChatCompletion实现实时内容更新) const completion = new (await import('fmode-ng/lib/core/agent')).FmodeChatCompletion( [{ role: 'user', content: prompt }], // 上下文 { model: DaofaModel } ); const subscription = completion.sendCompletion({ isDirect: true }).subscribe({ next: (message: any) => { const content = message.content || ''; options.onContentChange?.(content); // 实时更新前端解析内容 // 当输出完成时,保存解析结果并标记选择题正确答案 if (message.complete && content) { options.surveyItem.set('answer', content); // 提取正确答案(如从“【标准答案】A”中匹配选项) if (questionType.includes('choice')) { const correctLabel = this.extractCorrectAnswer(content); if (correctLabel) { const updatedOptions = questionOptions.map(opt => ({ ...opt, check: opt.label === correctLabel // 标记正确选项 })); options.surveyItem.set('options', updatedOptions); } } options.surveyItem.save().then(resolve); } }, error: (err) => reject(new Error(`解析生成失败:${err.message}`)) }); } catch (err: any) { reject(new Error(`解析生成失败:${err.message}`)); } }); } ``` ### 3.2 功能2:用户追问处理(上下文模态,闭环互动) 基于已识别的题目和解析,处理用户的后续疑问(如“为什么这个选项不对?”),需传入历史上下文确保回答连贯性。 ```typescript async handleQuestion(options: { parentQuestion: FmodeObject; // 原始题目(图片识别结果) userQuestion: string; // 用户追问内容 }): Promise { return new Promise(async (resolve, reject) => { try { // 1. 拼接上下文(规则:必须包含原始题目+已有解析,避免回答脱离场景) const parentContent = options.parentQuestion.get('content'); const parentAnswer = options.parentQuestion.get('answer'); const prompt = `基于以下题目和解析,回答学生的追问: 题目内容:${parentContent} 已有解析:${parentAnswer} 学生追问:${options.userQuestion} 要求: 1. 针对追问精准回应,不偏离原始题目; 2. 用“启发式”语言(如“你可以先回顾‘权利与义务的区别’,再看选项是否符合权利的定义”); 3. 引用教材/法律条文时标注出处。`; // 2. 调用大模型并保存追问记录 const completion = new (await import('fmode-ng/lib/core/agent')).FmodeChatCompletion( [{ role: 'user', content: prompt }], { model: DaofaModel } ); completion.sendCompletion({ isDirect: true }).subscribe({ next: async (message: any) => { if (message.complete && message.content) { // 保存追问记录到SurveyItem(类型为daofa-qa) const qaItem = await this.saveQuestionAnswer({ parent: options.parentQuestion, question: options.userQuestion, answer: message.content }); resolve(qaItem); } }, error: (err) => reject(new Error(`追问回答失败:${err.message}`)) }); } catch (err: any) { reject(new Error(`追问处理失败:${err.message}`)); } }); } ``` ## 四、Claude Code 核心规则提炼 ### 4.1 多模态调用强制规则 1. **视觉能力启用**:调用`completionJSON`实现图片识别时,必须在参数中配置 `{ vision: true, images: 图片数组(Base64格式), model: 多模态模型(如fmode-1.6-cn) }`,缺一不可; 2. **图片格式要求**:`images`参数需为「Base64字符串数组」(前端上传图片需先转Base64,不可直接传URL); 3. **输出稳定性**:必须通过「结构化提示词+输出示例」约束大模型输出(如指定JSON字段、枚举值),避免非结构化内容导致解析异常。 ### 4.2 提示词设计规范 1. **学科约束**:针对垂直领域(如道德与法治),需在提示词中明确「专业要求」(如“引用法律条文需标注出处”“符合初中生认知水平”); 2. **格式约束**:输出需分模块/JSON结构时,必须提供「完整示例」(如`output`参数的JSON模板),降低大模型输出偏差; 3. **上下文完整性**:追问/解析生成时,必须包含「原始题目+历史结果」(如`parentContent`+`parentAnswer`),避免回答脱离场景。 ### 4.3 流程链路规则 1. **数据依赖**:图片识别(`recognizeQuestion`)是前置流程,后续的解析生成(`generateAnswer`)、追问(`handleQuestion`)必须依赖其输出的`SurveyItem`对象; 2. **结果校验**:多模态输出(`questionData`)需先校验「非空+关键字段存在」(如`content`、`questionType`),再进入存储/后续流程; 3. **流式处理**:使用`FmodeChatCompletion`时,需通过`next`事件处理增量内容(实时更新UI),`complete`事件触发结果保存,避免数据丢失。 ### 4.4 数据存储规则 1. **对象区分**:`SurveyItem`用于存储「题目/解析/追问」,需通过`type`字段区分(`daofa`=原始题目,`daofa-qa`=追问记录); 2. **日志跟踪**:`SurveyLog`需记录「搜题模式(图片/OCR)、上传图片、识别耗时」,用于后续统计与问题排查; 3. **关联关系**:追问记录(`daofa-qa`类型`SurveyItem`)需通过`parent`字段关联原始题目,确保上下文链路可追溯。 ## 五、完整流程链路 ```mermaid graph TD A[用户上传道德与法治题目图片] --> B[图片转Base64格式] B --> C[调用recognizeQuestion(多模态视觉识别)] C --> D{识别结果校验} D -- 失败 --> E[抛出“识别失败”错误] D -- 成功 --> F[保存为SurveyItem(type=daofa)] F --> G[调用generateAnswer(文本解析生成)] G --> H[流式输出解析内容,标记选择题正确答案] H --> I[用户发起追问(如“为什么B选项错误?”)] I --> J[调用handleQuestion(上下文互动)] J --> K[保存为SurveyItem(type=daofa-qa,关联parent题目)] K --> L[更新SurveyLog(记录追问次数、耗时)] ```