diff --git a/agent/guideline_middleware.py b/agent/guideline_middleware.py index 9ddfb17..a9b2911 100644 --- a/agent/guideline_middleware.py +++ b/agent/guideline_middleware.py @@ -6,7 +6,7 @@ from utils.fastapi_utils import (extract_block_from_system_prompt, format_messag from langchain.chat_models import BaseChatModel from langgraph.runtime import Runtime -from langchain_core.messages import SystemMessage +from langchain_core.messages import SystemMessage, HumanMessage from typing import Any, Callable from langchain_core.callbacks import BaseCallbackHandler from langchain_core.outputs import LLMResult @@ -124,10 +124,11 @@ Action: Provide concise, friendly, and personified natural responses. response.additional_kwargs["message_tag"] = "THINK" response.content = f"{response.content}" - # 将响应添加到原始消息列表 - state['messages'] = state['messages'] + [response] + # 将响应添加到原始消息列表,并追加 HumanMessage 确保消息以 user 结尾 + # 某些模型不支持 assistant message prefill,要求最后一条消息必须是 user + state['messages'] = state['messages'] + [response, HumanMessage(content=self._get_follow_up_prompt())] return state - + async def abefore_agent(self, state: AgentState, runtime: Runtime) -> dict[str, Any] | None: if not self.guidelines: return None @@ -148,10 +149,23 @@ Action: Provide concise, friendly, and personified natural responses. response.additional_kwargs["message_tag"] = "THINK" response.content = f"{response.content}" - # 将响应添加到原始消息列表 - state['messages'] = state['messages'] + [response] + # 将响应添加到原始消息列表,并追加 HumanMessage 确保消息以 user 结尾 + # 某些模型不支持 assistant message prefill,要求最后一条消息必须是 user + state['messages'] = state['messages'] + [response, HumanMessage(content=self._get_follow_up_prompt())] return state + def _get_follow_up_prompt(self) -> str: + """根据语言返回引导主 agent 回复的提示""" + prompts = { + "ja": "以上の分析に基づいて、ユーザーに返信してください。", + "jp": "以上の分析に基づいて、ユーザーに返信してください。", + "zh": "请根据以上分析,回复用户。", + "zh-TW": "請根據以上分析,回覆用戶。", + "ko": "위 분석을 바탕으로 사용자에게 답변해 주세요.", + "en": "Based on the above analysis, please respond to the user.", + } + return prompts.get(self.language, prompts["en"]) + def wrap_model_call( self, request: ModelRequest, diff --git a/prompt/FACT_RETRIEVAL_PROMPT.md b/prompt/FACT_RETRIEVAL_PROMPT.md index b96f817..be5255e 100644 --- a/prompt/FACT_RETRIEVAL_PROMPT.md +++ b/prompt/FACT_RETRIEVAL_PROMPT.md @@ -167,6 +167,7 @@ Remember the following: - For colloquial or grammatically informal expressions (common in spoken Japanese, Chinese, Korean, etc.), understand the full intended meaning and record it in a clear, semantically complete form. - In Japanese, spoken language often omits particles (e.g., が, を, に). When extracting facts, include the necessary particles to make the meaning unambiguous. For example: "私は林檎好きです" should be understood as "林檎が好き" (likes apples), not literally "私は林檎好き". - When the user expresses a preference or opinion in casual speech, record the core preference/opinion clearly. Remove the subject pronoun (私は/I) since facts are about the user by default, but keep all other semantic components intact. + - **CRITICAL for People/Relationship Tracking**: - Write people-related facts in plain, natural language. Do NOT use structured formats like "Contact:", "referred as", or "DEFAULT when user says". - Good examples: "Michael Johnson is a colleague, also called Mike", "田中さんは友達", "滨田太郎は「滨田」とも呼ばれている"