mirror of
https://github.com/JefferyHcool/BiliNote.git
synced 2026-07-12 16:11:34 +08:00
feat: 新增模型管理和供应商配置功能
### v1.1.0 - #### Added - 新增 AI 笔记风格选择 - 新增 AI 笔记返回格式选择 - 添加 AI 自定义笔记备注 Prompt - 添加任务失败重试 - 添加全局设置页,可在设置页进行模型设置 - #### Optimize - 优化前端样式,优化用户体验 - 增加生成中间产物,可用于失败后加快生成速度 - #### Fix - 修复视频截图视频过早删除错误
This commit is contained in:
@@ -9,5 +9,5 @@ from app.models.model_config import ModelConfig
|
||||
class GPTFactory:
|
||||
@staticmethod
|
||||
def from_config(config: ModelConfig) -> GPT:
|
||||
client = OpenAICompatibleProvider(api_key=config.api_key, base_url=config.base_url).get_client()
|
||||
client = OpenAICompatibleProvider(api_key=config.api_key, base_url=config.base_url).get_client
|
||||
return UniversalGPT(client=client, model=config.model_name)
|
||||
100
backend/app/gpt/prompt_builder.py
Normal file
100
backend/app/gpt/prompt_builder.py
Normal file
@@ -0,0 +1,100 @@
|
||||
from app.gpt.prompt import BASE_PROMPT
|
||||
|
||||
note_formats = [
|
||||
{'label': '目录', 'value': 'toc'},
|
||||
{'label': '原片跳转', 'value': 'link'},
|
||||
{'label': '原片截图', 'value': 'screenshot'},
|
||||
{'label': 'AI总结', 'value': 'summary'}
|
||||
]
|
||||
|
||||
note_styles = [
|
||||
{'label': '精简', 'value': 'minimal'},
|
||||
{'label': '详细', 'value': 'detailed'},
|
||||
{'label': '学术', 'value': 'academic'},
|
||||
{"label": '教程',"value": 'tutorial', },
|
||||
{'label': '小红书', 'value': 'xiaohongshu'},
|
||||
{'label': '生活向', 'value': 'life_journal'},
|
||||
{'label': '任务导向', 'value': 'task_oriented'},
|
||||
{'label': '商业风格', 'value': 'business'},
|
||||
{'label': '会议纪要', 'value': 'meeting_minutes'}
|
||||
]
|
||||
|
||||
|
||||
# 生成 BASE_PROMPT 函数
|
||||
def generate_base_prompt(title, segment_text, tags, _format=None, style=None, extras=None):
|
||||
# 生成 Base Prompt 开头部分
|
||||
prompt = BASE_PROMPT.format(
|
||||
video_title=title,
|
||||
segment_text=segment_text,
|
||||
tags=tags
|
||||
)
|
||||
|
||||
# 添加用户选择的格式
|
||||
if _format:
|
||||
prompt += "\n" + "\n".join([get_format_function(f) for f in _format])
|
||||
|
||||
# 根据用户选择的笔记风格添加描述
|
||||
if style:
|
||||
prompt += "\n" + get_style_format(style)
|
||||
|
||||
# 添加额外内容
|
||||
if extras:
|
||||
prompt += f"\n{extras}"
|
||||
|
||||
return prompt
|
||||
|
||||
|
||||
# 获取格式函数
|
||||
def get_format_function(format_type):
|
||||
format_map = {
|
||||
'toc': get_toc_format,
|
||||
'link': get_link_format,
|
||||
'screenshot': get_screenshot_format,
|
||||
'summary': get_summary_format
|
||||
}
|
||||
return format_map.get(format_type, lambda: '')()
|
||||
|
||||
|
||||
# 风格描述的处理
|
||||
def get_style_format(style):
|
||||
style_map = {
|
||||
'minimal': '1. **精简信息**: 仅记录最重要的内容,简洁明了。',
|
||||
'detailed': '2. **详细记录**: 包含完整的时间戳和每个部分的详细讨论。',
|
||||
'academic': '3. **学术风格**: 适合学术报告,正式且结构化。',
|
||||
|
||||
'xiaohongshu': '4. **小红书风格**: 适合社交平台分享,亲切、口语化。',
|
||||
'life_journal': '5. **生活向**: 记录个人生活感悟,情感化表达。',
|
||||
'task_oriented': '6. **任务导向**: 强调任务、目标,适合工作和待办事项。',
|
||||
'business': '7. **商业风格**: 适合商业报告、会议纪要,正式且精准。',
|
||||
'meeting_minutes': '8. **会议纪要**: 适合商业报告、会议纪要,正式且精准。',
|
||||
"tutorial":"9.**教程笔记**:尽可能详细的记录教程,特别是关键点和一些重要的结论步骤"
|
||||
}
|
||||
return style_map.get(style, '')
|
||||
|
||||
|
||||
# 格式化输出内容
|
||||
def get_toc_format():
|
||||
return '''
|
||||
9. **目录**: 自动生成一个基于 `##` 级标题的目录。不需要插入原片跳转
|
||||
'''
|
||||
|
||||
|
||||
def get_link_format():
|
||||
return '''
|
||||
10. **原片跳转**: 为每个主要章节添加时间戳,使用格式 `*Content-[mm:ss]`。
|
||||
重要:**始终**在章节标题前加上 `*Content` 前缀,例如:`AI 的发展史 *Content-[01:23]`。一定是标题在前 插入标记在后
|
||||
'''
|
||||
|
||||
|
||||
def get_screenshot_format():
|
||||
return '''
|
||||
11. **原片截图**: 如果某个部分涉及**视觉演示**或任何能帮助理解的内容,插入截图提示:
|
||||
- 格式:`*Screenshot-[mm:ss]`
|
||||
至少插入 1-3张截图
|
||||
'''
|
||||
|
||||
|
||||
def get_summary_format():
|
||||
return '''
|
||||
12. **AI总结**: 在笔记末尾加入简短的AI生成总结,并且二级标题 就是 AI 总结 例如 ## AI 总结。
|
||||
'''
|
||||
@@ -1,4 +1,5 @@
|
||||
from app.gpt.base import GPT
|
||||
from app.gpt.prompt_builder import generate_base_prompt
|
||||
from app.models.gpt_model import GPTSource
|
||||
from app.gpt.prompt import BASE_PROMPT, AI_SUM, SCREENSHOT, LINK
|
||||
from app.gpt.utils import fix_markdown
|
||||
@@ -28,29 +29,35 @@ class UniversalGPT(GPT):
|
||||
return [TranscriptSegment(**seg) if isinstance(seg, dict) else seg for seg in segments]
|
||||
|
||||
def create_messages(self, segments: List[TranscriptSegment],**kwargs):
|
||||
content = BASE_PROMPT.format(
|
||||
video_title=kwargs.get('title'),
|
||||
print("UniversalGPT",kwargs)
|
||||
content =generate_base_prompt(
|
||||
title=kwargs.get('title'),
|
||||
segment_text=self._build_segment_text(segments),
|
||||
tags=kwargs.get('tags')
|
||||
tags=kwargs.get('tags'),
|
||||
_format=kwargs.get('_format'),
|
||||
style=kwargs.get('style'),
|
||||
extras=kwargs.get('extras')
|
||||
)
|
||||
if self.screenshot:
|
||||
print(":需要截图")
|
||||
content += SCREENSHOT
|
||||
if self.link:
|
||||
print(":需要链接")
|
||||
content += LINK
|
||||
|
||||
print(content)
|
||||
return [{"role": "user", "content": content + AI_SUM}]
|
||||
return [{"role": "user", "content": content }]
|
||||
|
||||
def list_models(self):
|
||||
return self.client.list_models()
|
||||
return self.client.models.list()
|
||||
def summarize(self, source: GPTSource) -> str:
|
||||
self.screenshot = source.screenshot
|
||||
self.link = source.link
|
||||
source.segment = self.ensure_segments_type(source.segment)
|
||||
messages = self.create_messages(source.segment, source.title,source.tags)
|
||||
response = self.client.chat(
|
||||
|
||||
messages = self.create_messages(
|
||||
source.segment,
|
||||
title=source.title,
|
||||
tags=source.tags
|
||||
,
|
||||
_format=source._format,
|
||||
style=source.style,
|
||||
extras=source.extras
|
||||
)
|
||||
response = self.client.chat.completions.create(
|
||||
model=self.model,
|
||||
messages=messages,
|
||||
temperature=0.7
|
||||
|
||||
Reference in New Issue
Block a user