feat:visual style从配置中移除,改为prompt模板内容

This commit is contained in:
SengokuCola
2026-04-21 18:26:54 +08:00
parent 565aedf9ef
commit 363c0a77b7
8 changed files with 46 additions and 39 deletions

View File

@@ -0,0 +1 @@
Describe the content of this image in English. If there is text, summarize the text. Pay attention to its topic and immediate impression. Output one plain-text paragraph within 30 words. Do not use bullet points.

View File

@@ -0,0 +1 @@
この画像の内容を日本語で説明してください。文字がある場合は、その内容を要約してください。主題と直感的な印象に注意し、30語以内の平文1段落で出力してください。箇条書きにしないでください。

View File

@@ -0,0 +1 @@
请用中文描述这张图片的内容。如果有文字请把文字描述概括出来请留意其主题、直观感受输出为一段平文本最多30字请注意不要分点就输出一段文本

View File

@@ -183,10 +183,16 @@ def patch_external_dependencies(monkeypatch):
sql_mod = types.SimpleNamespace(select=lambda *a, **k: DummySelect()) sql_mod = types.SimpleNamespace(select=lambda *a, **k: DummySelect())
monkeypatch.setitem(sys.modules, "sqlmodel", sql_mod) monkeypatch.setitem(sys.modules, "sqlmodel", sql_mod)
# Patch config values used at import-time # Patch prompt manager used to build image description prompt.
cfg = types.SimpleNamespace(visual=types.SimpleNamespace(visual_style="test-style")) class _PromptManager:
config_mod = types.SimpleNamespace(global_config=cfg) def get_prompt(self, _name):
monkeypatch.setitem(sys.modules, "src.config.config", config_mod) return types.SimpleNamespace()
async def render_prompt(self, _prompt):
return "test-style"
prompt_manager_mod = types.SimpleNamespace(prompt_manager=_PromptManager())
monkeypatch.setitem(sys.modules, "src.prompt.prompt_manager", prompt_manager_mod)
llm_options_mod = types.SimpleNamespace(LLMImageOptions=lambda **kwargs: types.SimpleNamespace(**kwargs)) llm_options_mod = types.SimpleNamespace(LLMImageOptions=lambda **kwargs: types.SimpleNamespace(**kwargs))
monkeypatch.setitem(sys.modules, "src.common.data_models.llm_service_data_models", llm_options_mod) monkeypatch.setitem(sys.modules, "src.common.data_models.llm_service_data_models", llm_options_mod)

View File

@@ -13,7 +13,7 @@ from src.common.logger import get_logger
from src.common.database.database import get_db_session from src.common.database.database import get_db_session
from src.common.database.database_model import Images, ImageType from src.common.database.database_model import Images, ImageType
from src.common.data_models.image_data_model import MaiImage from src.common.data_models.image_data_model import MaiImage
from src.config.config import global_config from src.prompt.prompt_manager import prompt_manager
from src.services.llm_service import LLMServiceClient from src.services.llm_service import LLMServiceClient
install(extra_lines=3) install(extra_lines=3)
@@ -374,7 +374,8 @@ class ImageManager:
logger.info(f"Cleaned mistaken registration state on {fixed_counter} image records") logger.info(f"Cleaned mistaken registration state on {fixed_counter} image records")
async def _generate_image_description(self, image_bytes: bytes, image_format: str) -> str: async def _generate_image_description(self, image_bytes: bytes, image_format: str) -> str:
prompt = global_config.visual.visual_style prompt_template = prompt_manager.get_prompt("image_description")
prompt = await prompt_manager.render_prompt(prompt_template)
image_base64 = base64.b64encode(image_bytes).decode("utf-8") image_base64 = base64.b64encode(image_bytes).decode("utf-8")
generation_result = await vlm.generate_response_for_image( generation_result = await vlm.generate_response_for_image(

View File

@@ -55,7 +55,7 @@ BOT_CONFIG_PATH: Path = (CONFIG_DIR / "bot_config.toml").resolve().absolute()
MODEL_CONFIG_PATH: Path = (CONFIG_DIR / "model_config.toml").resolve().absolute() MODEL_CONFIG_PATH: Path = (CONFIG_DIR / "model_config.toml").resolve().absolute()
LEGACY_ENV_PATH: Path = (PROJECT_ROOT / ".env").resolve().absolute() LEGACY_ENV_PATH: Path = (PROJECT_ROOT / ".env").resolve().absolute()
MMC_VERSION: str = "1.0.0" MMC_VERSION: str = "1.0.0"
CONFIG_VERSION: str = "8.9.6" CONFIG_VERSION: str = "8.9.8"
MODEL_CONFIG_VERSION: str = "1.14.1" MODEL_CONFIG_VERSION: str = "1.14.1"
logger = get_logger("config") logger = get_logger("config")

View File

@@ -382,16 +382,15 @@ def try_migrate_legacy_bot_config_dict(data: dict[str, Any]) -> MigrationResult:
personality = _as_dict(data.get("personality")) personality = _as_dict(data.get("personality"))
visual = _as_dict(data.get("visual")) visual = _as_dict(data.get("visual"))
if visual is None and personality is not None and "visual_style" in personality: if personality is not None and "visual_style" in personality:
visual = {}
data["visual"] = visual
if visual is not None and personality is not None and "visual_style" in personality:
if "visual_style" not in visual:
visual["visual_style"] = personality["visual_style"]
personality.pop("visual_style", None) personality.pop("visual_style", None)
migrated_any = True migrated_any = True
reasons.append("personality.visual_style_moved_to_visual.visual_style") reasons.append("personality.visual_style_removed")
if visual is not None and "visual_style" in visual:
visual.pop("visual_style", None)
migrated_any = True
reasons.append("visual.visual_style_removed")
memory = _as_dict(data.get("memory")) memory = _as_dict(data.get("memory"))
if memory is not None and _migrate_target_item_list(memory, "global_memory_blacklist"): if memory is not None and _migrate_target_item_list(memory, "global_memory_blacklist"):

View File

@@ -75,7 +75,7 @@ class PersonalityConfig(ConfigBase):
__ui_icon__ = "user-circle" __ui_icon__ = "user-circle"
personality: str = Field( personality: str = Field(
default="是一个大二在读女大学生,现在正在上网和群友聊天,有时有点攻击性,有时比较温柔", default="是一个大二女大学生,现在正在上网和群友聊天",
json_schema_extra={ json_schema_extra={
"x-widget": "textarea", "x-widget": "textarea",
"x-icon": "user-circle", "x-icon": "user-circle",
@@ -84,7 +84,7 @@ class PersonalityConfig(ConfigBase):
"""人格建议100字以内描述人格特质和身份特征""" """人格建议100字以内描述人格特质和身份特征"""
reply_style: str = Field( reply_style: str = Field(
default="请不要刻意突出自身学科背景。可以参考贴吧,知乎和微博的回复风格。", default="你的风格平淡简短。可以参考贴吧,知乎和微博的回复风格。不浮夸不长篇大论,不要过分修辞和复杂句。尽量回复的简短一些,平淡一些",
json_schema_extra={ json_schema_extra={
"x-widget": "textarea", "x-widget": "textarea",
"x-icon": "message-square", "x-icon": "message-square",
@@ -93,7 +93,13 @@ class PersonalityConfig(ConfigBase):
"""默认表达风格描述麦麦说话的表达风格表达习惯如要修改可以酌情新增内容建议1-2行""" """默认表达风格描述麦麦说话的表达风格表达习惯如要修改可以酌情新增内容建议1-2行"""
multiple_reply_style: list[str] = Field( multiple_reply_style: list[str] = Field(
default_factory=lambda: [], default_factory=lambda: [
"你的风格平淡但不失讽刺,很简短,很白话。可以参考贴吧,微博的回复风格。",
"用1-2个字进行回复",
"用1-2个符号进行回复",
"言辭凝練古雅,穿插《論語》經句卻不晦澀,以文言短句為基,輔以淺白語意,持長者溫和風範,全用繁體字表達,具先秦儒者談吐韻致。",
"带点翻译腔,但不要太长",
],
json_schema_extra={ json_schema_extra={
"x-widget": "custom", "x-widget": "custom",
"x-icon": "list", "x-icon": "list",
@@ -102,7 +108,7 @@ class PersonalityConfig(ConfigBase):
"""可选的多种表达风格列表,当配置不为空时可按概率随机替换 reply_style""" """可选的多种表达风格列表,当配置不为空时可按概率随机替换 reply_style"""
multiple_probability: float = Field( multiple_probability: float = Field(
default=0.3, default=0.2,
ge=0, ge=0,
le=1, le=1,
json_schema_extra={ json_schema_extra={
@@ -137,15 +143,6 @@ class VisualConfig(ConfigBase):
) )
"""回复器模式auto根据模型信息自动选择text为纯文本模式multimodal为多模态模式""" """回复器模式auto根据模型信息自动选择text为纯文本模式multimodal为多模态模式"""
visual_style: str = Field(
default="请用中文描述这张图片的内容。如果有文字请把文字描述概括出来请留意其主题直观感受输出为一段平文本最多30字请注意不要分点就输出一段文本",
json_schema_extra={
"x-widget": "textarea",
"x-icon": "image",
},
)
"""_wrap_识图提示词不建议修改"""
class TalkRulesItem(ConfigBase): class TalkRulesItem(ConfigBase):
platform: str = "" platform: str = ""
@@ -204,7 +201,7 @@ class ChatConfig(ConfigBase):
"""是否启用回复时附带引用回复""" """是否启用回复时附带引用回复"""
max_context_size: int = Field( max_context_size: int = Field(
default=30, default=40,
json_schema_extra={ json_schema_extra={
"x-widget": "input", "x-widget": "input",
"x-icon": "layers", "x-icon": "layers",
@@ -223,11 +220,12 @@ class ChatConfig(ConfigBase):
"""Planner 连续被新消息打断的最大次数0 表示不启用打断""" """Planner 连续被新消息打断的最大次数0 表示不启用打断"""
group_chat_prompt: str = Field( group_chat_prompt: str = Field(
default=""" default=(
你正在qq群里聊天下面是群里正在聊的内容其中包含聊天记录和聊天中的图片 "你正在qq群里聊天下面是群里正在聊的内容其中包含聊天记录和聊天中的图片和表情包。\n"
回复尽量简短一些。最好一次对一个话题进行回复,免得啰嗦或者回复内容太乱。请注意把握聊天内容。 "回复尽量简短一些。最好一次对一个话题进行回复,但必须考虑不同群友发言之间的交互,免得啰嗦或者回复内容太乱。请注意把握聊天内容。\n"
不要回复的太频繁!控制回复的频率,不要每个人的消息都回复,只回复你感兴趣的或者主动提及你的。 "不要总是提及自己的身份背景,根据聊天内容自由发挥,但是要日常不浮夸,不要太关注具体的聊天内容,不要刻意找话题,。\n"
""", "不要回复的太频繁!不用刻意回复表情包,只要关注表情包表达的含义。控制回复的频率,不要每个人的消息都回复,只回复你感兴趣的或者主动提及你的。\n"
),
json_schema_extra={ json_schema_extra={
"x-widget": "textarea", "x-widget": "textarea",
"x-icon": "users", "x-icon": "users",
@@ -236,11 +234,11 @@ class ChatConfig(ConfigBase):
"""_wrap_群聊通用注意事项""" """_wrap_群聊通用注意事项"""
private_chat_prompts: str = Field( private_chat_prompts: str = Field(
default=""" default=(
你正在聊天,下面是正在聊的内容,其中包含聊天记录和聊天中的图片。 "你正在聊天,下面是正在聊的内容,其中包含聊天记录和聊天中的图片。\n"
回复尽量简短一些。请注意把握聊天内容。 "回复尽量简短一些。请注意把握聊天内容。\n"
请考虑对方的发言频率,想法,思考自己何时回复以及回复内容。 "请考虑对方的发言频率,想法,思考自己何时回复以及回复内容。\n"
""", ),
json_schema_extra={ json_schema_extra={
"x-widget": "textarea", "x-widget": "textarea",
"x-icon": "user", "x-icon": "user",