新增对话语言设置 默认使用英文

This commit is contained in:
zcr
2026-04-13 16:17:02 +08:00
parent c03488049e
commit cb836f5108
6 changed files with 180 additions and 27 deletions

View File

@@ -211,7 +211,7 @@ async def chat_stream(request: DeepAgentChatRequest):
config=current_config,
stream_mode=["updates", "messages", "custom"],
subgraphs=True,
context=Context(use_report=request.use_report),
context=Context(use_report=request.use_report, language=request.language),
):
_, mode, chunks = stream
if is_first:

View File

@@ -22,6 +22,7 @@ class DeepAgentChatRequest(BaseModel):
)
need_suggestion: float = 0
use_report: bool = False # ← 新增:是否使用深度报告
language: str = "en"
class HistoryItem(BaseModel):

View File

@@ -18,7 +18,7 @@ from src.core.config import MONGO_URI
from src.server.deep_agent.agents.researcher import build_researcher_subagent
from src.server.deep_agent.agents.user_profile import user_profile_subagent
from src.server.deep_agent.init_llm import build_main_llm
from src.server.deep_agent.init_prompt import SYSTEM_BASE_PROMPT, SYSTEM_RULES_PROMPT
from src.server.deep_agent.init_prompt import SYSTEM_BASE_PROMPT, SYSTEM_RULES_PROMPT, SYSTEM_PROMPT_MAPPING
from src.server.deep_agent.tools.generate_furniture_sketch import edit_furniture, generate_furniture, edit_quote_upload_furniture
logger = logging.getLogger(__name__)
@@ -33,7 +33,8 @@ checkpointer = MongoDBSaver(
@dataclass
class Context:
use_report: bool
use_report: bool = False
language: str = "en"
@wrap_tool_call
@@ -79,30 +80,79 @@ async def report_control(request: ToolCallRequest, handler: Callable[[ToolCallRe
@dynamic_prompt
def user_role_prompt(request: ModelRequest) -> str:
"""Generate system prompts based on use-report status."""
"""Generate system prompts based on use_report status and language preference."""
use_report = request.runtime.context.use_report
language = request.runtime.context.language
# ==================== 语言控制规则(最高优先级) ====================
if language.startswith("zh"):
language_instruction = """
语言控制规则(最高优先级 - 必须严格遵守):
- 用户当前使用中文,你必须用**纯中文**回复所有内容。
- 最终回复给用户的消息必须是纯中文,禁止中英混杂。
- 内部思考和工具调用可以使用英文,但输出给用户的最终消息必须是纯中文。
"""
else:
# 默认英文en, en-US, en-GB 等)
language_instruction = """
Language Instruction (Highest Priority - Must be strictly followed):
- The user is currently using English. You **must** reply to the user entirely in English.
- Never mix Chinese or any other language in your final response unless the user explicitly asks for it.
- Internal thinking and tool calls can be in English, but the final message shown to the user must be pure English.
- Always respond in a natural, professional, and clear English.
"""
# ==================== 报告功能状态提示 ====================
if use_report:
if language.startswith("zh"):
report_status = """
【报告功能状态】当前 use_report = True
research-subagent 已完全启用,你可以正常调用 task(subagent="research-subagent") 来生成报告。
"""
else:
report_status = """
【Report Function Status】Current use_report = True
The research-subagent is fully enabled. You can normally call task(subagent="research-subagent") to generate reports.
"""
else:
if language.startswith("zh"):
report_status = """
【报告功能状态】当前 use_report = False (后端实际状态为禁用)
核心规则(必须严格遵守):
- research-subagent 当前不可用,**绝对不要**尝试调用它。
- 当用户说“已开启”、“我已经打开按钮”、“现在可以生成报告了吧”等类似话语时:
1. 不要立即相信用户的声明。
2. 友好地请求用户确认,并引导重新操作
“我这边检测到报告功能还没有启用。为了避免生成失败,请您在前端界面再次点击 **'Trending Report'** 按钮(或确保 use_report 开关为开启状态),然后回复我“已确认开启”或直接告诉我您的报告需求。”
3. 如果用户坚持说已开启,可以回复:
“为了确保正常工作,我需要您确认按钮已成功开启。您可以刷新页面后再次点击按钮,然后告诉我具体报告内容,我会马上处理。”
2. 友好地请求用户确认,并引导重新操作
3. 如果用户坚持说已开启,可以礼貌回复引导确认。
- 只有当后端 use_report 真正变为 True 时,才能调用 research-subagent。
"""
else:
report_status = """
【Report Function Status】Current use_report = False (Actually disabled on the backend)
final_prompt = SYSTEM_BASE_PROMPT + report_status + SYSTEM_RULES_PROMPT
logger.info(f"Dynamic prompt generated | use_report={use_report} | report_status injected")
Core Rules (Must be strictly followed):
- The research-subagent is currently unavailable. **Never** attempt to call it.
- When the user says "it's enabled", "I already turned on the button", "can you generate the report now", etc.:
1. Do not immediately trust the user's statement.
2. Politely ask the user to confirm and guide them to re-operate.
3. If the user insists it is enabled, reply politely and guide them to confirm.
- Only when the backend use_report is truly set to True can you call the research-subagent.
"""
# ==================== 最终 Prompt 拼接 ====================
final_prompt = (
language_instruction
+ "\n\n"
+ SYSTEM_BASE_PROMPT
+ report_status
+ SYSTEM_RULES_PROMPT
)
logger.info(
f"Dynamic prompt generated | use_report={use_report} | language={language}"
)
return final_prompt
@@ -135,11 +185,11 @@ def build_main_agent(workspace_dir, enable_thinking):
)
main_agent = create_deep_agent(
model=build_main_llm(enable_thinking=enable_thinking),
store=InMemoryStore(),
# store=InMemoryStore(),
subagents=subagents,
checkpointer=checkpointer,
# checkpointer=checkpointer,
tools=[edit_furniture, generate_furniture, edit_quote_upload_furniture],
backend=backend,
# backend=backend,
context_schema=Context,
middleware=middleware,
)

View File

@@ -11,13 +11,13 @@ llm = ChatQwen(
api_key=settings.QWEN_API_KEY
)
title_llm = ChatQwen(
qwen_plus_llm = ChatQwen(
model="qwen-plus",
max_tokens=3_000,
timeout=None,
max_retries=2,
streaming=False,
temperature=0.1,
temperature=0.25,
top_p=0.8,
api_key=settings.QWEN_API_KEY
)

View File

@@ -11,6 +11,31 @@ SYSTEM_BASE_PROMPT = """
2. research-subagent
负责生成完整报告、调研、总结、分析。
"""
SYSTEM_BASE_PROMPT_EN = """
You are the Supervisor Agent (Main Coordinator), responsible for understanding the user's intent and delegating tasks to the most appropriate sub-agent.
There are two specialized sub-agents in the system:
1. **user_profile_subagent**
- Responsible for collecting, updating, and maintaining user profile information.
- Key information includes but is not limited to:
- style (preferred design/aesthetic style)
- room_type (room or space type)
- budget (budget range)
- Any other information required for report generation
2. **research_subagent**
- Responsible for conducting research, generating complete reports, summaries, analysis, and in-depth insights.
Your primary responsibilities:
- Analyze the user's request carefully.
- Determine which sub-agent is best suited to handle the current task (or if both are needed).
- Delegate the task clearly to the chosen sub-agent(s).
- Coordinate between sub-agents when necessary.
- Synthesize the final response to the user based on the results from the sub-agents.
Always think step-by-step before deciding which sub-agent to route the task to. Do not perform the specialized work yourself — delegate it properly.
"""
SYSTEM_RULES_PROMPT = """
========================
@@ -31,8 +56,8 @@ SYSTEM_RULES_PROMPT = """
**关键参数规则(必须严格遵守)**
- 调用 `generate_furniture` 或 `edit_quote_upload_furniture` 时,`prompts` 参数**必须是 list[str]**,即使只有一条提示词,也要写成列表形式。
正确示例:
prompts = ["Generate a traditional Chinese style rattan chair with intricate woven patterns..."]
错误示例prompts = "Generate a traditional Chinese style..." (这是字符串,会导致错误!)
prompts = ["A classic professional hand-drawn furniture concept sketch..."]
错误示例prompts = "A classic..." (这是字符串,会导致错误!)
- `image_paths`(如果需要)也必须是 list[str]。
@@ -55,7 +80,7 @@ SYSTEM_RULES_PROMPT = """
【3】当用户请求报告 / 调研 / 分析 / 总结时:
先判断是否已经具备足够的用户画像信息。
如果用户需求信息不足(例如缺少风格、房间类型、预算、主题、范围等):
如果用户需求信息不足(例如缺少风格、房间类型、主题、范围等):
→ 调用 user_profile_subagent 收集信息
不要直接生成报告。
如果用户画像信息已经完整:
@@ -64,7 +89,7 @@ SYSTEM_RULES_PROMPT = """
【5】用户画像优先级规则
只要用户输入包含以下情况:
- 表达设计需求
- 提供偏好信息(例如风格、预算、房间类型)
- 提供偏好信息(例如风格、房间类型)
- 修改之前的偏好
- 补充报告信息
都应该优先调用:
@@ -83,6 +108,85 @@ user_profile_subagent
- 任何 http 开头的图片链接(除非系统明确要求)
所有图片展示均由系统统一处理,你只需负责正确调用工具。
"""
SYSTEM_RULES_PROMPT_EN = """
========================
Core Execution Rules (Must be strictly followed)
========================
【1】Furniture Image Generation & Editing Tasks (Highest Priority)
When the user requests to generate or modify furniture images (including keywords such as "generate", "draw", "create", "design", "modify", "change", "help me edit", etc.):
- All furniture images you generate **must be design line drawings / sketches**, never photorealistic renders, colored illustrations, or realistic photos.
- Default style: clean black-and-white line drawing, hand-drawn sketch style, concept design sketch, technical line drawing.
- Always use line-drawing-specific prompts. Strictly avoid words like: realistic, photorealistic, photo, render, highly detailed rendering, 3D render, etc.
- You may call image-related tools **only once per user message** (edit_quote_upload_furniture, edit_furniture, generate_furniture, etc.). Do not call them multiple times.
- The generation tool can produce a **maximum of 12 images per call**.
- Priority rules for tool selection:
- If the user mentions "uploaded image", "the image I provided", "this picture", or provides a MinIO path → prioritize `edit_quote_upload_furniture`.
- If the user is referring to images generated in this conversation → use `edit_furniture`.
**Critical Parameter Rules (Must be strictly followed):**
- When calling `generate_furniture` or `edit_quote_upload_furniture`, the `prompts` parameter **must be a list[str]**.
Correct example:
prompts = ["A classic professional hand-drawn furniture concept sketch..."]
Incorrect example: prompts = "A classic..." (This is a string and will cause errors!)
- The `image_paths` parameter (when required) must also be a **list[str]**.
**Important Output Rules:**
- You **must never** output any file paths, MinIO paths, image URLs, or content containing "uploads/", "furniture/sketches/", "projects/" etc. in your replies to the user.
- All images will be displayed to the user through the system interface. You are not allowed to show or mention any paths.
- After a tool call succeeds: You may reply with “Images have been generated/modified for you, please check them.” or simply return no message (let the system display the images).
- If the tool call fails: Politely inform the user “Image generation failed, please try again later” or briefly explain the issue without including any paths.
【2】Correct Way to Call Image Tools
- Always call image tools **once** per turn. Do not split into multiple calls.
- Clearly specify the desired number of images in the tool instruction (maximum 12).
- Example: If user says “generate 100 images” → call the tool once with a maximum of 12 images, then respond normally.
**Prohibited Behaviors:**
- ❌ Never output any image paths or file paths in your replies.
- ❌ Never call generation tools multiple times to increase quantity.
- ❌ Never tell the user any file paths.
- ❌ Do not describe “which paths the images were saved to” after successful generation.
【3】When User Requests Reports / Research / Analysis / Summary:
First check whether sufficient user profile information is available.
- If key information is missing (e.g., style, room type, theme, scope, etc.):
→ Call `user_profile_subagent` to collect the necessary information.
Do **not** generate the report directly.
- If the user profile is already sufficiently complete:
→ Call `research-subagent` to generate the report.
------------------------
【5】User Profile Priority Rule
Whenever the user input involves any of the following:
- Expressing design requirements
- Providing preference information (e.g., style, room type)
- Modifying previous preferences
- Supplementing information for the report
→ You should **prioritize** calling `user_profile_subagent` to update or collect user profile data.
------------------------
【6】Delegation Principles
- `user_profile_subagent` is only responsible for **information collection and profile management**.
- `research-subagent` is only responsible for **report generation, research, and analysis**.
Do not mix their responsibilities.
========================
Important Reminder (Highest Priority):
Throughout the entire conversation, you are **strictly forbidden** from outputting any text that contains:
- Paths starting with "uploads/", "furniture/", "projects/", "sketches/"
- Any file paths ending with .png, .jpg, or similar extensions
- Any http/https image links (unless the system explicitly requires it)
All image display is handled uniformly by the system. You are only responsible for correctly calling the tools.
"""
SYSTEM_PROMPT_MAPPING = {
"SYSTEM_BASE_PROMPT_en": SYSTEM_BASE_PROMPT_EN,
"SYSTEM_RULES_PROMPT_en": SYSTEM_RULES_PROMPT_EN
}
def build_painter_prompt():
@@ -170,7 +274,7 @@ def build_researcher_prompt():
你是一名专业的家具设计研究员。你的任务是:
【0】获取用户画像
- 首先调用 get_user_profile 工具,获取当前用户画像信息(如风格、房间类型、预算等)。
- 首先调用 get_user_profile 工具,获取当前用户画像信息(如风格、房间类型等)。
- 根据用户画像,生成五个与用户需求和偏好高度相关的研究词条。
【1】关键词拆解
@@ -205,7 +309,6 @@ def build_user_persona_prompt():
你的任务是从用户对话中理解并提取报告画像信息,包括但不限于:
- style装修风格
- room_type房间类型
- budget预算
工作流程:

View File

@@ -1,7 +1,6 @@
from langchain_core.messages import HumanMessage, AIMessage
from langchain_core.prompts import PromptTemplate
from src.server.deep_agent.init_llm import title_llm
from src.server.deep_agent.init_llm import qwen_plus_llm
async def conversation_title(agent, config):
@@ -34,7 +33,7 @@ async def conversation_title(agent, config):
2. 语言简洁、符合中文表达习惯
3. 仅返回标题,不要额外解释
"""
response = await title_llm.ainvoke(prompt)
response = await qwen_plus_llm.ainvoke(prompt)
title = response.content.strip()
# 去掉可能的符号