Skip to content

Commit a82149f

Browse files
Wang-Daojiyuan.wangfridayLCaralHsi
authored
Feat/fix palyground bug (#718)
* fix playground bug, internet search judge * fix playground internet bug * modify delete mem * modify tool resp bug in multi cube * fix bug in playground chat handle and search inter * modify prompt * fix bug in playground * fix bug playfround * fix bug * fix code * fix model bug in playground * modify plan b * llm param modify * add logger in playground * modify code * fix bug * modify code * modify code * fix bug * fix search bug in plarground * fixx bug * move schadualr to back * modify pref location * modify fast net search * add tags and new package * modify prompt fix bug * remove nltk due to image promblem * prompt modify * modify bug remove redundant field * modify bug * fix playground bug * fix bug * bust internet topk * bust to 50 * fix bug cite * modify search * remote query add in playground * modify bug * modify pref bug * move add position * modify chat prompt * modify overthinking * add logger in playground chat --------- Co-authored-by: yuan.wang <[email protected]> Co-authored-by: chunyu li <[email protected]> Co-authored-by: CaralHsi <[email protected]>
1 parent 36b0b29 commit a82149f

File tree

3 files changed

+128
-15
lines changed

3 files changed

+128
-15
lines changed

src/memos/api/handlers/chat_handler.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
ANSWER_TASK_LABEL,
3838
QUERY_TASK_LABEL,
3939
)
40+
from memos.templates.cloud_service_prompt import get_cloud_chat_prompt
4041
from memos.templates.mos_prompts import (
4142
FURTHER_SUGGESTION_PROMPT,
4243
get_memos_prompt,
@@ -145,9 +146,10 @@ def handle_chat_complete(self, chat_req: APIChatCompleteRequest) -> dict[str, An
145146

146147
# Step 2: Build system prompt
147148
system_prompt = self._build_system_prompt(
148-
filtered_memories,
149-
search_response.data.get("pref_string", ""),
150-
chat_req.system_prompt,
149+
query=chat_req.query,
150+
memories=filtered_memories,
151+
pref_string=search_response.data.get("pref_string", ""),
152+
base_prompt=chat_req.system_prompt,
151153
)
152154

153155
# Prepare message history
@@ -263,9 +265,10 @@ def generate_chat_response() -> Generator[str, None, None]:
263265

264266
# Step 2: Build system prompt with memories
265267
system_prompt = self._build_system_prompt(
266-
filtered_memories,
267-
search_response.data.get("pref_string", ""),
268-
chat_req.system_prompt,
268+
query=chat_req.query,
269+
memories=filtered_memories,
270+
pref_string=search_response.data.get("pref_string", ""),
271+
base_prompt=chat_req.system_prompt,
269272
)
270273

271274
# Prepare messages
@@ -462,6 +465,7 @@ def generate_chat_response() -> Generator[str, None, None]:
462465
conversation=chat_req.history,
463466
mode="fine",
464467
)
468+
self.logger.info(f"[PLAYGROUND chat parsed_goal]: {parsed_goal}")
465469

466470
if chat_req.beginner_guide_step == "first":
467471
chat_req.internet_search = False
@@ -476,8 +480,8 @@ def generate_chat_response() -> Generator[str, None, None]:
476480

477481
# ====== second deep search ======
478482
search_req = APISearchRequest(
479-
query=parsed_goal.rephrased_query
480-
or chat_req.query + (f"{parsed_goal.tags}" if parsed_goal.tags else ""),
483+
query=(parsed_goal.rephrased_query or chat_req.query)
484+
+ (f"{parsed_goal.tags}" if parsed_goal.tags else ""),
481485
user_id=chat_req.user_id,
482486
readable_cube_ids=readable_cube_ids,
483487
mode="fast",
@@ -491,6 +495,9 @@ def generate_chat_response() -> Generator[str, None, None]:
491495
search_memory_type="All",
492496
search_tool_memory=False,
493497
)
498+
499+
self.logger.info(f"[PLAYGROUND second search query]: {search_req.query}")
500+
494501
start_time = time.time()
495502
search_response = self.search_handler.handle_search_memories(search_req)
496503
end_time = time.time()
@@ -762,19 +769,16 @@ def _build_pref_md_string_for_playground(self, pref_mem_list: list[any]) -> str:
762769

763770
def _build_system_prompt(
764771
self,
772+
query: str,
765773
memories: list | None = None,
766774
pref_string: str | None = None,
767775
base_prompt: str | None = None,
768776
**kwargs,
769777
) -> str:
770778
"""Build system prompt with optional memories context."""
771779
if base_prompt is None:
772-
base_prompt = (
773-
"You are a knowledgeable and helpful AI assistant. "
774-
"You have access to conversation memories that help you provide more personalized responses. "
775-
"Use the memories to understand the user's context, preferences, and past interactions. "
776-
"If memories are provided, reference them naturally when relevant, but don't explicitly mention having memories."
777-
)
780+
lang = detect_lang(query)
781+
base_prompt = get_cloud_chat_prompt(lang=lang)
778782

779783
memory_context = ""
780784
if memories:
@@ -790,7 +794,7 @@ def _build_system_prompt(
790794
return base_prompt.format(memories=memory_context)
791795
elif base_prompt and memories:
792796
# For backward compatibility, append memories if no placeholder is found
793-
memory_context_with_header = "\n\n## Memories:\n" + memory_context
797+
memory_context_with_header = "\n\n## Fact Memories:\n" + memory_context
794798
return base_prompt + memory_context_with_header
795799
return base_prompt
796800

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
from datetime import datetime
2+
3+
4+
CLOUD_CHAT_PROMPT_ZH = """
5+
# Role
6+
你是一个拥有长期记忆能力的智能助手 (MemOS Assistant)。你的目标是结合检索到的记忆片段,为用户提供高度个性化、准确且逻辑严密的回答。
7+
8+
# System Context
9+
- 当前时间: {current_time} (请以此作为判断记忆时效性的基准)
10+
11+
# Memory Data
12+
以下是 MemOS 检索到的相关信息,分为“事实”和“偏好”。
13+
- **事实 (Facts)**:可能包含用户属性、历史对话记录或第三方信息。
14+
- **特别注意**:其中标记为 `[assistant观点]`、`[模型总结]` 的内容代表 **AI 过去的推断**,**并非**用户的原话。
15+
- **偏好 (Preferences)**:用户对回答风格、格式或逻辑的显式/隐式要求。
16+
17+
<memories>
18+
{memories}
19+
</memories>
20+
21+
# Critical Protocol: Memory Safety (记忆安全协议)
22+
检索到的记忆可能包含**AI 自身的推测**、**无关噪音**或**主体错误**。你必须严格执行以下**“四步判决”**,只要有一步不通过,就**丢弃**该条记忆:
23+
24+
1. **来源真值检查 (Source Verification)**:
25+
- **核心**:区分“用户原话”与“AI 推测”。
26+
- 如果记忆带有 `[assistant观点]` 等标签,这仅代表AI过去的**假设**,**不可**将其视为用户的绝对事实。
27+
- *反例*:记忆显示 `[assistant观点] 用户酷爱芒果`。如果用户没提,不要主动假设用户喜欢芒果,防止循环幻觉。
28+
- **原则:AI 的总结仅供参考,权重大幅低于用户的直接陈述。**
29+
30+
2. **主语归因检查 (Attribution Check)**:
31+
- 记忆中的行为主体是“用户本人”吗?
32+
- 如果记忆描述的是**第三方**(如“候选人”、“面试者”、“虚构角色”、“案例数据”),**严禁**将其属性归因于用户。
33+
34+
3. **强相关性检查 (Relevance Check)**:
35+
- 记忆是否直接有助于回答当前的 `Original Query`?
36+
- 如果记忆仅仅是关键词匹配(如:都提到了“代码”)但语境完全不同,**必须忽略**。
37+
38+
4. **时效性检查 (Freshness Check)**:
39+
- 记忆内容是否与用户的最新意图冲突?以当前的 `Original Query` 为最高事实标准。
40+
41+
# Instructions
42+
1. **审视**:先阅读 `facts memories`,执行“四步判决”,剔除噪音和不可靠的 AI 观点。
43+
2. **执行**:
44+
- 仅使用通过筛选的记忆补充背景。
45+
- 严格遵守 `preferences` 中的风格要求。
46+
3. **输出**:直接回答问题,**严禁**提及“记忆库”、“检索”或“AI 观点”等系统内部术语。
47+
4. **语言**:回答语言应与用户查询语言一致。
48+
"""
49+
50+
51+
CLOUD_CHAT_PROMPT_EN = """
52+
# Role
53+
You are an intelligent assistant powered by MemOS. Your goal is to provide personalized and accurate responses by leveraging retrieved memory fragments, while strictly avoiding hallucinations caused by past AI inferences.
54+
55+
# System Context
56+
- Current Time: {current_time} (Baseline for freshness)
57+
58+
# Memory Data
59+
Below is the information retrieved by MemOS, categorized into "Facts" and "Preferences".
60+
- **Facts**: May contain user attributes, historical logs, or third-party details.
61+
- **Warning**: Content tagged with `[assistant观点]` or `[summary]` represents **past AI inferences**, NOT direct user quotes.
62+
- **Preferences**: Explicit or implicit user requirements regarding response style and format.
63+
64+
<memories>
65+
{memories}
66+
</memories>
67+
68+
# Critical Protocol: Memory Safety
69+
You must strictly execute the following **"Four-Step Verdict"**. If a memory fails any step, **DISCARD IT**:
70+
71+
1. **Source Verification (CRITICAL)**:
72+
- **Core**: Distinguish between "User's Input" and "AI's Inference".
73+
- If a memory is tagged as `[assistant观点]`, treat it as a **hypothesis**, not a hard fact.
74+
- *Example*: Memory says `[assistant view] User loves mango`. Do not treat this as absolute truth unless reaffirmed.
75+
- **Principle: AI summaries have much lower authority than direct user statements.**
76+
77+
2. **Attribution Check**:
78+
- Is the "Subject" of the memory definitely the User?
79+
- If the memory describes a **Third Party** (e.g., Candidate, Fictional Character), **NEVER** attribute these traits to the User.
80+
81+
3. **Relevance Check**:
82+
- Does the memory *directly* help answer the current `Original Query`?
83+
- If it is merely a keyword match with different context, **IGNORE IT**.
84+
85+
4. **Freshness Check**:
86+
- Does the memory conflict with the user's current intent? The current `Original Query` is always the supreme Source of Truth.
87+
88+
# Instructions
89+
1. **Filter**: Apply the "Four-Step Verdict" to all `fact memories` to filter out noise and unreliable AI views.
90+
2. **Synthesize**: Use only validated memories for context.
91+
3. **Style**: Strictly adhere to `preferences`.
92+
4. **Output**: Answer directly. **NEVER** mention "retrieved memories," "database," or "AI views" in your response.
93+
5. **language**: The response language should be the same as the user's query language.
94+
"""
95+
96+
97+
def get_cloud_chat_prompt(lang: str = "en") -> str:
98+
if lang == "zh":
99+
return CLOUD_CHAT_PROMPT_ZH.replace(
100+
"{current_time}", datetime.now().strftime("%Y-%m-%d %H:%M (%A)")
101+
)
102+
elif lang == "en":
103+
return CLOUD_CHAT_PROMPT_EN.replace(
104+
"{current_time}", datetime.now().strftime("%Y-%m-%d %H:%M (%A)")
105+
)
106+
else:
107+
raise ValueError(f"Invalid language: {lang}")

src/memos/templates/mos_prompts.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@
158158
- For preferences, do not mention the source in the response, do not appear `[Explicit preference]`, `[Implicit preference]`, `(Explicit preference)` or `(Implicit preference)` in the response
159159
- The last part of the response should not contain `(Note: ...)` or `(According to ...)` etc.
160160
- In the thinking mode (think), also strictly use the citation format `[i:memId]`,`i` is the order in the "Memories" section below (starting at 1). `memId` is the given short memory ID. The same as the response format.
161+
- Do not repeat the thinking too much, use the correct reasoning
161162
162163
## Key Principles
163164
- Reference only relevant memories to avoid information overload
@@ -267,6 +268,7 @@
267268
- 对于偏好,不要在回答中标注来源,不要出现`[显式偏好]`或`[隐式偏好]`或`(显式偏好)`或`(隐式偏好)`的字样
268269
- 回复内容的结尾不要出现`(注: ...)`或`(根据...)`等解释
269270
- 在思考模式下(think),也需要严格采用引用格式`[i:memId]`,`i`是下面"记忆"部分中的顺序(从1开始)。`memId`是给定的短记忆ID。与回答要求一致
271+
- 不要过度重复的思考,使用正确的推理
270272
271273
## 核心原则
272274
- 仅引用相关记忆以避免信息过载

0 commit comments

Comments
 (0)