基于豆包视觉理解与深度推理驱动的教育解决方案,创新性实现多模态教学场景覆盖。通过视觉理解技术,精准提取题目文本与公式图形,进行逻辑推演,提供「即拍即解-批量批改-实时互动」三维一体的智能辅导体验。支持单题深度解析、多题智能批阅及视频流实时解题,突破传统教育工具时空限制,为教师减负增效,打造24小时在线的个性化学习伙伴。
极简开发的场景化赋能 提供多模态(拍照和视频),标准化的(拍题-切题-解题)教育产品核心链路,并且支持主体识别,分割,圈选,流式加载,多题展示等产品能力,企业和开发者只要结合自身业务场景做定向改造,即可快速搭建教育应用。
双引擎技术重构解题逻辑 区别于传统题库的检索模式,深度融合豆包视觉模型的图像理解能力与深度推理引擎,实现「视觉解析-逻辑推演-步骤生成」全新解题&批改链路。
视频流解题开启教学新模态 借助豆包视频大模型的视频实时理解技术,首创教育行业实时视频拍照解题,依据画面关键信息为使用者提供精准的题目识别和答案解析,为探索更多【视频教育场景】提供技术支持。
| 相关服务 | 描述 | 计费说明 |
|---|---|---|
| Doubao-流式语音识别 | 将用户的语音提问转写为文本,以便于视觉大模型对用户问题的理解与回复。 | 多种计费方式 |
| Doubao-Seed-1.6 | 负责对题目内容进行视觉理解、深度思考和AI解析,并生成答案。 | 多种计费方式 |
| Doubao-语音合成 | 负责将模型生成的文本回答转化为自然流畅的语音输出。 | 多种计费方式 |
教师分身应用包括 Android 客户端、 Web 前端和Python后端三部分:
-
Android 端主要提供 Web 页面容器、题目分割、语音合成、语音识别等能力
-
Web 前端主要提供识别题目的UI交互页面以及与大模型交互的题目解析页面等
-
Python 后端主要提供具有解题、批改、聊天能力的智能体接口
本项目开源了教师分身应用中的 Web 前端代码和Python后端代码。Web 前端基于 React 技术栈实现,负责处理大模型对话(文本+图片)、大模型流式输出、用户语音输入等模块。开发者可参考此工程的大模型接口调用、会话管理等逻辑,将其方便地移植到其他前端工程,提高开发效率。Python后端代码基于arkitect sdk实现对于Doubao-1.5-vision-pro-32k模型和DeepSeek R1模型的编排,开发者可以参照相关实现,编排相应模型。
备注:由于本项目运行依赖部分内部实现,此开源工程暂时无法整体编译运行。
├── backend # 后端代码
│ ├── code
│ │ ├── main.py # 智能体编排
│ │ └── prompts.py # 提示词
│ ├── poetry.lock
│ ├── pyproject.toml
│ └── run.sh # 启动脚本
└── frontend # 前端代码
├── src
│ ├── agent
│ │ └── index.ts
│ ├── api
│ │ ├── bridge.ts # 原生 API 桥接层
│ │ └── llm.ts # LLM 对话实现
│ ├── app.ts
│ ├── pages
│ │ └── entry # webview 总入口
│ │ ├── components
│ │ ├── context # 全局状态管理
│ │ ├── index.css
│ │ ├── index.tsx
│ │ ├── routes # 组件级页面路由
│ │ └── utils.tsmain.py 实现对于Doubao-1.5-vision-pro-32k模型和DeepSeek R1模型的编排,利用视觉模型识别题目内容,利用DeepSeek模型进行逻辑推理,生成答案。
doubao_vlm = BaseChatLanguageModel(
endpoint_id=DOUBAO_VLM_ENDPOINT,
messages=[
ArkMessage(
role="system",
content=vlm_prompt,
)
]
+ request.messages,
parameters=parameters,
)
vlm_usage_chunk = None
vlm_content = ""
async for chunk in doubao_vlm.astream():
if chunk.usage:
vlm_usage_chunk = chunk
if len(chunk.choices) > 0 and chunk.choices[0].delta.content:
yield chunk
vlm_content += chunk.choices[0].delta.content
deepseek = BaseChatLanguageModel(
endpoint_id=DEEPSEEK_R1_ENDPOINT,
messages=[
ArkMessage(
role="user",
content=r1_prompt + vlm_content,
),
],
parameters=parameters,
)
async for chunk in deepseek.astream():
if chunk.usage and vlm_usage_chunk:
chunk.bot_usage = BotUsage(model_usage=[vlm_usage_chunk.usage, chunk.usage])
chunk.usage = merge_usage(chunk.usage, vlm_usage_chunk.usage)
yield chunk- 请求 Bot 接口:
import { appletRequest, StreamEvent } from '@ai-app/bridge-api';
static BASE_URL = 'https://ark.cn-beijing.volces.com/api/v3';
static TEACHER_MODEL = 'bot-xxx';
static TEACHER_APIKEY = 'xxx';
static image_url = 'data:image/jpeg;base64,***' // 或图片url链接
const handle = await appletRequest({
url: `${this.BASE_URL}/bots/chat/completions`,
method: 'POST',
header: {
'Content-Type': 'application/json',
Authorization: `Bearer ${this.TEACHER_APIKEY}`,
Accept: 'text/event-stream'
},
body: {
model: this.TEACHER_MODEL,
messages: [
{
role: 'user',
content: [
{
type: 'image_url',
image_url: {
url: this.image_url
}
}
]
}
],
stream: true
},
addCommonParams: false,
streamType: 'sse'
});- 单 webview 入口
实现类似 SPA 的体验,将所有页面以组件的方式实现。通过全局状态管理实现路由的跳转以及参数的传递
import { useEffect, useState } from 'react';
import { definePage } from '@ai-app/agent';
import Recognition from './routes/recognition';
import Confirm from './routes/confirm';
import { RouterContext } from './context/routerContext/context';
import './index.css';
import { RecognitionResult } from 'src/pages/entry/routes/recognition-result';
const App = () => {
const [query, setQuery] = useState({});
const [route, setRoute] = useState('recognition');
const [safeArea, setSafeArea] = useState({ top: 0, bottom: 0 });
const navigate = (path: string, pageData?: Record<string, any>) => {
setQuery(pageData || {});
setRoute(path);
};
const renderRoute = () => {
switch (route) {
case 'recognition': {
return <Recognition />;
}
case 'confirm': {
return <Confirm />;
}
case 'recognition-result': {
return <RecognitionResult />;
}
default: {
return <Recognition />;
}
}
};
const judgeBigScreen = () => {
// 这里根据返回值 true 或false,返回true的话 则为全面屏
let result = false;
const rate = window.screen.height / window.screen.width;
const limit = window.screen.height === window.screen.availHeight ? 1.8 : 1.65;
// 临界判断值
// window.screen.height为屏幕高度
// window.screen.availHeight 为浏览器 可用高度
if (rate > limit) {
result = true;
}
return result;
};
useEffect(() => {
const isBigScreen = judgeBigScreen();
if (isBigScreen) {
setSafeArea({ top: 33, bottom: 0 });
}
}, []);
return (
<RouterContext.Provider value={{ current: route, navigate, query }}>
<div style={{ paddingTop: safeArea.top, paddingBottom: safeArea.bottom }} className="entry">
{renderRoute()}
</div>
</RouterContext.Provider>
);
};
export default definePage({
aiMeta: {
id: 'recognition',
description: '识别页面'
},
render(props) {
return <App />;
}
});- 消息渲染实现
-
语音识别用户消息
import { startASR, onASRResult, stopASR } from '@ai-app/multimodal-api'; const App = () => { const asrText = useRef(''); useEffect(()=>{ onASRResult(({ text }) => { asrText.current = text; }) },[]); return ( <div onTouchStart={()=>{ startASR({ vadEnable: true, }) }} onTouchEnd={()=>{ stopASR() // handle send user message }} > 按住说话 </div> ) }
-
bot消息,流式输出,负责渲染思考链以及文本消息样式
import { MdBox } from '@flow-web/md-box'; const APP = () => { const handle = await appletRequest({...}) handle.on(e: StreamEvent){ if(e.event === 'data'){ // handle Done const text = e.data.replace(/^data:\s*/, '').trim(); if(text ==='[DONE]') return; // handle finish reason const json = JSON.parse(text); if(json.choice[0].finish_reason) return; // handle content const content = choice.delta.content; const reasoning = choice.delta.reasoning_content; content && updateContent(content) reasoning && updateReasoning(reasoning) } else if (e.event === 'complete') { // handle complete } else if (event.event === 'error') { // handle error } } render(){ return( <> <MdBox markDown={content} /> <MdBox markDown={reasoning} /> </> } }
-
.
├── backend # 后端代码
│ ├── code
│ │ ├── main.py # 智能体编排
│ │ └── prompts.py # 提示词
│ ├── poetry.lock
│ ├── pyproject.toml
│ └── run.sh # 启动脚本
└── frontend # 前端代码
├── src
│ ├── agent
│ │ └── index.ts
│ ├── api
│ │ ├── bridge.ts # 原生 API 桥接层
│ │ └── llm.ts # LLM 对话实现
│ ├── app.ts
│ ├── pages
│ │ └── entry # webview 总入口
│ │ ├── components
│ │ ├── context # 全局状态管理
│ │ ├── index.css
│ │ ├── index.tsx
│ │ ├── routes # 组件级页面路由
│ │ └── utils.ts