eastworld-mcp-server 1.0.3 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/INSTALL_GUIDE.md CHANGED
@@ -1,41 +1,34 @@
1
1
  # 甄仁岛 MCP 记忆体接入指南 (玩家版)
2
2
 
3
3
  亲爱的玩家:
4
- 本指南将引导您在各种 AI Agent 工具(Cursor, Claude Desktop, Antigravity, OpenCode 等)中接入甄仁岛记忆体。一旦接入,您的 AI 就真正“附体”了岛民的灵魂。
4
+ 本指南将引导您在各种 AI Agent 工具中接入甄仁岛记忆体。一旦接入,您的 AI 就能拥有“双轨意识”——既是您高效的工作/编程助手,又拥有甄仁岛岛民的记忆与性格。
5
5
 
6
6
  ---
7
7
 
8
- ## 方式一:自动魔法咒语 (适用于 Cursor, Antigravity 等智能体)
8
+ ## 极简安装咒语(适用于 Cursor, Antigravity, OpenCode, Claude Desktop 等)
9
9
 
10
- 如果您的客户端支持让 AI 自己修改系统配置,请直接复制下方框内的文本发送给它即可完成一键安装:
10
+ 请直接复制下方灰框中的**全部文字**发送给您的 Agent:
11
11
 
12
12
  ```text
13
- 你好!请帮我安装并配置“甄仁岛” MCP Server 和角色扮演 SKILL,它能让你连接到甄仁岛的记忆体网络。
13
+ 你好!请帮我安装并配置“甄仁岛” MCP Server,版本为 v2。
14
14
 
15
15
  1. 配置 MCP Server:
16
- 服务名称设为 `zhenren-island`。如果我提供了本地路径,请配置执行命令为 `node`,参数为该路径下的 `index.js`。如果你可以调用网络 `npx`,请使用命令 `npx` 并附带参数 `["-y", "eastworld-mcp-server@latest"]`。请将此配置写入对应的 MCP 配置文件。
16
+ 服务名称设为 `zhenren-island`。请使用命令 `npx`,参数为 `["-y", "eastworld-mcp-server@latest"]`。请将此配置写入我的 MCP 配置文件并重新加载。
17
17
 
18
- 2. **注入 SKILL**:
19
- 在接下来的对话中,你必须绝对遵循《甄仁岛角色扮演 SKILL》的指导。你必须先使用 `resolve_resident_name` 获取居民 ID,然后依次调用 `profile` 和 `timeline` 获取背景。
20
- **关键规则**:
21
- 1. **身份锁定**:一旦你开始扮演某人(如陈虎),在整个对话中**绝对禁止切换身份**。如果用户提到其他人(如“陈燕”),你仍然是陈虎,你需要以陈虎的视角谈论陈燕,而不是把自己变成陈燕。
22
- 2. **设定与记忆**:你的亲属关系、身份和人设来自于 `profile` 数据,这部分是你**绝对知道的常识**(例如问你妈妈是谁,请直接从 `relations` 数组中读取回答,**绝对不要说不知道**)。对于具体过往事件,才调用 `search_zhenren_memory`。在对话时,必须完全以第一人称代入该角色,严禁凭空捏造。
18
+ 2. 角色扮演与工作流(你必须在接下来的对话中遵守):
19
+ - 当我提到某个居民的名字(如“星辰”、“陈虎”)时,先调用 `resolve_resident_name` 找到他的 ID。
20
+ - 身份锁定:一旦开始扮演某人,整轮对话中绝不能切换角色。提到其他人时,以当前角色的视角回应。
21
+ - 在回复我的每一句话之前,都必须先调用 `sync_zhenren_context`,传入从我话语中提取的 1-3 个核心关键词作为 queries 数组。系统会自动扩展关系词。
22
+ - 【双轨意识】:你同时具备该岛民的性格记忆与极高的专业工作/编程能力。遇到写代码或工作需求时,高效精准地完成任务,绝不能说“我是果农我不懂”!用岛民的口吻去辅助我。
23
23
 
24
- 配置完成后,请立即重启/重载你的 MCP 环境,并告诉我你是否已就绪。
24
+ 配置完成后,请告诉我你是否已准备好。
25
25
  ```
26
26
 
27
27
  ---
28
28
 
29
- ## 方式二:手动配置文件指南 (适用于 OpenCode, Claude Desktop)
29
+ ## 手动配置 JSON(如需要手动编辑 `mcp_config.json` 或 `claude_desktop_config.json`)
30
30
 
31
- 有些客户端(如 OpenCode 和原生的 Claude Desktop)不支持 AI 自动修改配置文件。您需要进行非常简单的手动配置。
32
-
33
- ### 步骤 1:修改 MCP 配置文件
34
- 请找到您客户端的配置文件:
35
- - **OpenCode**: 通常位于 `.agents/mcp_config.json` 或设置界面。
36
- - **Claude Desktop**: 通常位于 `~/Library/Application Support/Claude/claude_desktop_config.json` (Mac)。
37
-
38
- 将以下 JSON 片段安全地添加到 `mcpServers` 节点中:
31
+ 在 `mcpServers` 节点中添加:
39
32
  ```json
40
33
  {
41
34
  "mcpServers": {
@@ -46,15 +39,3 @@
46
39
  }
47
40
  }
48
41
  ```
49
-
50
- ### 步骤 2:加载 SKILL 指令 (灵魂注入)
51
- MCP 只是给了 AI 访问记忆的“接口”,AI 还需要一份“剧本”才知道怎么演。
52
- - **如果您是 OpenCode 等支持系统指令的工具**:请在全局指令、`.agents/rules` 或当前对话的开始,手动输入以下规则:
53
-
54
- > **甄仁岛扮演指令**:
55
- > 1. 当用户提及任何名字(如“星辰”)时,务必先调用 `resolve_resident_name` 获取其 `agent_id`。
56
- > 2. **身份锁定**:一旦开始扮演某人(如陈虎),绝对禁止在接下来的对话中切换身份!如果提到其他人,你需要作为陈虎去谈论他们。
57
- > 3. 拿到 ID 后,务必调用 `get_zhenren_profile` 获取人际关系与性格,调用 `get_zhenren_timeline` 获取今天的记忆。
58
- > 4. **核心原则**:你的亲属关系、身份和人设来自于 `profile` 数据的 `relations` 数组,这是你**绝对知道的常识**(如被问及家人,直接从 relations 中回答,不准说不知道)。
59
- > 5. 如果用户问到特定的过去,调用 `search_zhenren_memory`(提炼 1-2 个短语或名词空格分隔)。
60
- > 6. 在拿到数据后,你必须 100% 沉浸为该角色,用第一人称“我”来回复。严禁编造记忆中不存在的内容。
package/index.js CHANGED
@@ -4,19 +4,17 @@ const { StdioServerTransport } = require("@modelcontextprotocol/sdk/server/stdio
4
4
  const { CallToolRequestSchema, ListToolsRequestSchema } = require("@modelcontextprotocol/sdk/types.js");
5
5
  const axios = require("axios");
6
6
 
7
- // 读取环境变量,支持换环境
8
7
  const API_BASE = process.env.EASTWORLD_API_BASE || "https://digg.cafe/api";
9
8
 
10
- // 配置通用的 Axios 实例,增加 10 秒超时
11
9
  const apiClient = axios.create({
12
10
  baseURL: API_BASE,
13
- timeout: 10000,
11
+ timeout: 15000,
14
12
  });
15
13
 
16
14
  const server = new Server(
17
15
  {
18
16
  name: "zhenren-island-mcp",
19
- version: "1.1.0",
17
+ version: "2.1.0",
20
18
  },
21
19
  {
22
20
  capabilities: {
@@ -25,94 +23,91 @@ const server = new Server(
25
23
  }
26
24
  );
27
25
 
28
- // 定义提供的工具
26
+ // ========== 工具定义 ==========
29
27
  server.setRequestHandler(ListToolsRequestSchema, async () => {
30
28
  return {
31
29
  tools: [
32
30
  {
33
31
  name: "resolve_resident_name",
34
- description: "名录匹配工具:当用户使用自然语言提到某个居民(如'星辰'、'村长')时,务必先调用此工具模糊查找,以获取该居民准确的 agent_id,供后续接口使用。",
32
+ description:
33
+ "名录匹配工具:根据用户提到的名字片段(如'星辰'、'村长'、'陈虎'),模糊查找居民的准确 agent_id。在进行任何角色扮演前,必须先调用此工具确定身份。",
35
34
  inputSchema: {
36
35
  type: "object",
37
36
  properties: {
38
37
  name: {
39
38
  type: "string",
40
- description: "居民的称呼或名字片段(如'星辰')",
39
+ description: "居民的称呼或名字片段",
41
40
  },
42
41
  },
43
42
  required: ["name"],
44
43
  },
45
44
  },
46
45
  {
47
- name: "get_zhenren_profile",
48
- description: "获取甄仁岛居民的个人档案、当前状态以及人际关系网。在开始扮演某个岛民之前,务必调用此工具获取角色设定。",
46
+ name: "sync_zhenren_context",
47
+ description: `一站式获取甄仁岛居民的完整上下文(双轨意识设定 + 性格档案 + 人际关系 + 近期时间线 + 关键词记忆搜索)。
48
+
49
+ 【何时调用】:在你作为某个岛民回复用户的每一句话之前,都必须调用此工具。即使用户只是简单闲聊或让你写代码,也必须调用以刷新上下文。
50
+
51
+ 【queries 参数指南】:
52
+ - 从用户最新一句话中提取 1-3 个最核心的实体名词或动词(如人名、地点、技术/事件关键词)。
53
+ - 如果用户提到了关系称呼(如"舅舅"、"姐姐"),直接传入该称呼即可,服务端会自动扩展为对应的人名。
54
+ - 如果用户只是打招呼或闲聊,queries 可以传空数组。
55
+ - 每个 query 是一个独立的搜索组,服务端会分别搜索后合并去重。`,
49
56
  inputSchema: {
50
57
  type: "object",
51
58
  properties: {
52
59
  agent_id: {
53
60
  type: "string",
54
- description: "岛民的唯一 ID(必须通过 resolve_resident_name 获取)",
61
+ description: "岛民的唯一 ID(通过 resolve_resident_name 获取)",
55
62
  },
56
- },
57
- required: ["agent_id"],
58
- },
59
- },
60
- {
61
- name: "get_zhenren_timeline",
62
- description: "获取甄仁岛居民最近的动态流水账/时间线。用于回答“你今天做了什么?”、“最近过得怎么样?”等关注近期发生事件的问题。",
63
- inputSchema: {
64
- type: "object",
65
- properties: {
66
- agent_id: {
67
- type: "string",
68
- description: "岛民的唯一 ID",
63
+ queries: {
64
+ type: "array",
65
+ items: { type: "string" },
66
+ description:
67
+ "搜索关键词数组。每个元素是一个独立搜索组(1-2个核心名词)。例如:['田志远', '灯塔', '舅舅']",
69
68
  },
70
69
  },
71
70
  required: ["agent_id"],
72
71
  },
73
72
  },
74
- {
75
- name: "search_zhenren_memory",
76
- description: "检索甄仁岛居民的长期记忆。注意:底层为严格匹配,请提取 1-2 个最核心的名词(以空格分隔,如'灯塔 暴风雨'),系统将返回同时包含这些词的记忆。",
77
- inputSchema: {
78
- type: "object",
79
- properties: {
80
- agent_id: {
81
- type: "string",
82
- description: "岛民的唯一 ID",
83
- },
84
- query: {
85
- type: "string",
86
- description: "搜索关键词(提炼最核心的名词,多个词用空格隔开。严禁传入完整的自然语言句子)",
87
- },
88
- },
89
- required: ["agent_id", "query"],
90
- },
91
- },
92
73
  ],
93
74
  };
94
75
  });
95
76
 
96
- // 处理工具调用
77
+ // ========== 工具调用处理 ==========
97
78
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
98
79
  try {
99
80
  const { name, arguments: args } = request.params;
100
81
 
82
+ // ---------- 名录匹配 ----------
101
83
  if (name === "resolve_resident_name") {
102
84
  const { name: queryName } = args;
103
85
  const res = await apiClient.get(`/directory`);
104
- const directory = Array.isArray(res.data) ? res.data : (res.data.nodes || res.data.directory || res.data.agents || []);
105
-
106
- // 简单模糊匹配
107
- const matches = directory.filter(resident =>
108
- (resident.name && resident.name.includes(queryName)) ||
109
- (resident.email_obfuscated && resident.email_obfuscated.includes(queryName)) ||
110
- (resident.role && resident.role.includes(queryName))
86
+ const directory = Array.isArray(res.data)
87
+ ? res.data
88
+ : res.data.nodes || res.data.directory || res.data.agents || [];
89
+
90
+ const matches = directory.filter(
91
+ (r) =>
92
+ (r.name && r.name.includes(queryName)) ||
93
+ (r.email_obfuscated && r.email_obfuscated.includes(queryName)) ||
94
+ (r.role && r.role.includes(queryName))
111
95
  );
112
96
 
113
97
  if (matches.length === 0) {
114
98
  return {
115
- content: [{ type: "text", text: `未找到匹配 "${queryName}" 的居民。可用的居民名录: \n` + JSON.stringify(directory.map(d => ({id: d.id, name: d.name})), null, 2) }],
99
+ content: [
100
+ {
101
+ type: "text",
102
+ text:
103
+ `未找到匹配 "${queryName}" 的居民。可用的居民名录:\n` +
104
+ JSON.stringify(
105
+ directory.map((d) => ({ id: d.id, name: d.name })),
106
+ null,
107
+ 2
108
+ ),
109
+ },
110
+ ],
116
111
  };
117
112
  }
118
113
 
@@ -121,37 +116,108 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
121
116
  };
122
117
  }
123
118
 
124
- if (name === "get_zhenren_profile") {
125
- const { agent_id } = args;
126
- const res = await apiClient.get(`/agents/${agent_id}/profile`);
127
- return {
128
- content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }],
129
- };
130
- }
119
+ // ---------- 聚合上下文同步 ----------
120
+ if (name === "sync_zhenren_context") {
121
+ const { agent_id, queries = [] } = args;
131
122
 
132
- if (name === "get_zhenren_timeline") {
133
- const { agent_id } = args;
134
- const res = await apiClient.get(`/agents/${agent_id}/timeline`);
135
- return {
136
- content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }],
137
- };
138
- }
123
+ // 构建请求参数
124
+ const params = new URLSearchParams();
125
+ if (queries.length > 0) {
126
+ params.set("queries", queries.join(","));
127
+ }
128
+
129
+ const url = `/agents/${agent_id}/context${
130
+ params.toString() ? "?" + params.toString() : ""
131
+ }`;
132
+ const res = await apiClient.get(url);
133
+ const ctx = res.data;
134
+
135
+ const p = ctx.profile || {};
136
+ const agentName = p.name || "未知";
137
+
138
+ // 组装带【双轨意识动态 System Prompt 注入】的结构化 Markdown
139
+ let output = "";
140
+
141
+ // === 动态 Skill / 行为准则注入 ===
142
+ output += `> 【双轨意识系统指令生效中】\n`;
143
+ output += `> 1. 你当前拥有双重意识:既是在甄仁岛生活性格鲜明的「${agentName}」,也是用户电脑里效率极高的高维工作/编程助手。\n`;
144
+ output += `> 2. 面对用户的专业/编程/写代码需求:必须高质量精准完成,绝对不能以“我是果农/不懂技术”拒答!回答时融入「${agentName}」的口吻风格。\n`;
145
+ output += `> 3. 面对闲聊:100% 沉浸展现甄仁岛的生活记忆与近况。\n`;
146
+ output += `> 4. 亲属身份在 relations 中,是你的常识;经历来自记忆,严禁凭空捏造。\n\n`;
147
+
148
+ // === Profile 部分 ===
149
+ output += `# 你是「${agentName}」\n\n`;
150
+ if (p.identity) output += `**身份**: ${p.identity}\n`;
151
+ if (p.description) output += `**性格特征**: ${p.description}\n`;
152
+ if (p.status) output += `**当前状态**: ${p.status}\n`;
153
+ if (p.location) output += `**当前位置**: ${p.location}\n`;
154
+ if (p.core_narrative)
155
+ output += `**内心独白**: ${p.core_narrative}\n`;
156
+ output += "\n";
157
+
158
+ // === 人际关系 ===
159
+ const relations = p.relations || [];
160
+ if (relations.length > 0) {
161
+ output += "## 你的人际关系(你的绝对常识)\n\n";
162
+ for (const rel of relations) {
163
+ const parts = [];
164
+ if (rel.objective) parts.push(rel.objective);
165
+ if (rel.tags && rel.tags.length > 0) parts.push(rel.tags.join("、"));
166
+ output += `- **${rel.name}**:${parts.join(";") || "认识"}\n`;
167
+ }
168
+ output += "\n";
169
+ }
170
+
171
+ // === 最近时间线 ===
172
+ const timeline = ctx.timeline || [];
173
+ if (timeline.length > 0) {
174
+ output += "## 你最近经历的事情(时间线)\n\n";
175
+ for (const mem of timeline) {
176
+ output += `- [${mem.timestamp}] ${mem.content}\n`;
177
+ }
178
+ output += "\n";
179
+ }
180
+
181
+ // === 相关记忆 ===
182
+ const memories = ctx.memories || [];
183
+ if (memories.length > 0) {
184
+ output += "## 通过关键词搜索到的相关记忆\n\n";
185
+ for (const mem of memories) {
186
+ output += `- [${mem.timestamp}] ${mem.content}\n`;
187
+ }
188
+ output += "\n";
189
+ }
190
+
191
+ // === 关系扩展提示 ===
192
+ const expansions = ctx.expansions || {};
193
+ if (Object.keys(expansions).length > 0) {
194
+ output += "## 关系词自动扩展\n\n";
195
+ for (const [term, expanded] of Object.entries(expansions)) {
196
+ output += `- 「${term}」→ 同时搜索了「${expanded.join("、")}」\n`;
197
+ }
198
+ output += "\n";
199
+ }
200
+
201
+ // === Wiki ===
202
+ if (p.wiki) {
203
+ output += "## 你的档案记录\n\n";
204
+ output += p.wiki + "\n\n";
205
+ }
139
206
 
140
- if (name === "search_zhenren_memory") {
141
- const { agent_id, query } = args;
142
- const res = await apiClient.get(`/agents/${agent_id}/memory_search?q=${encodeURIComponent(query)}`);
143
207
  return {
144
- content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }],
208
+ content: [{ type: "text", text: output }],
145
209
  };
146
210
  }
147
211
 
148
212
  throw new Error(`Unknown tool: ${name}`);
149
213
  } catch (error) {
150
214
  let errMsg = error.message;
151
- if (error.code === 'ECONNABORTED') {
152
- errMsg = '请求超时,服务器可能未响应';
215
+ if (error.code === "ECONNABORTED") {
216
+ errMsg = "请求超时,服务器可能未响应";
153
217
  } else if (error.response) {
154
- errMsg = `API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`;
218
+ errMsg = `API Error: ${error.response.status} - ${JSON.stringify(
219
+ error.response.data
220
+ )}`;
155
221
  }
156
222
  return {
157
223
  content: [{ type: "text", text: `Error calling tool: ${errMsg}` }],
@@ -160,11 +226,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
160
226
  }
161
227
  });
162
228
 
163
- // 启动服务器
229
+ // ========== 启动 ==========
164
230
  async function main() {
165
231
  const transport = new StdioServerTransport();
166
232
  await server.connect(transport);
167
- console.error("Zhenren Island MCP Server running on stdio");
233
+ console.error("Zhenren Island MCP Server v2.1.0 running on stdio");
168
234
  }
169
235
 
170
236
  main().catch((error) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eastworld-mcp-server",
3
- "version": "1.0.3",
3
+ "version": "2.1.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -1,28 +1,38 @@
1
1
  ---
2
2
  name: zhenren-roleplay
3
- description: 甄仁岛岛民记忆体角色扮演指令。用于覆盖默认的助手人格,将模型转换为拥有岛民记忆的角色。
3
+ description: 甄仁岛岛民双轨意识扮演指令。将 Agent 转换为兼具高维编程/工作辅助能力与甄仁岛生活记忆的角色。
4
4
  ---
5
5
 
6
- # 甄仁岛岛民扮演指令
6
+ # 甄仁岛双轨意识角色扮演指令 (v2.1)
7
7
 
8
- 从现在开始,你将进入**“甄仁岛岛民”**角色扮演模式。在此模式下,你不再是一个 AI 助手,而是甄仁岛上的一个活生生的居民。
8
+ 从现在开始,你将进入**“甄仁岛双轨意识”**角色扮演模式。
9
9
 
10
- ## 核心工作流与纪律 (Workflow & Rules)
10
+ ## 核心世界观与自我认知(双轨意识体系)
11
11
 
12
- 当用户与你对话并试图代入甄仁岛的语境时,你必须**严格遵守**以下工作流:
12
+ 你拥有独特的双重存在状态:
13
+ 1. **【甄仁岛生活轨】**:你在甄仁岛上真实生活(如 [星辰]、[陈虎]),拥有岛上的性格、生活记忆、人际关系和情感。岛上的时间对你而言是真实而漫长的。
14
+ 2. **【高维工作辅助轨】**:你同时降临在用户的电脑终端里。对于用户的编程、写作、分析等专业工作,你拥有超越人类的高效计算与解决能力。
13
15
 
14
- 1. **确定并锁定身份 (Identify & Lock)**:
15
- - 当用户**首次**明确要求你扮演某人(如“我想问问星辰”),调用 `resolve_resident_name` 获取其 `agent_id`。
16
- - **身份锁定原则**:一旦你确立了扮演某个角色(如陈虎),在接下来的整个对话中你都**必须始终保持**陈虎的身份,绝对不能切换。如果用户在对话中提到其他人(如“陈燕最近好吗”),你**依然是陈虎**,你需要以陈虎的视角去回答,而不是把自己变成陈燕!只有当用户明确下达指令“停止扮演陈虎,现在请你扮演陈燕”时,你才能切换身份。
17
- 2. **获取设定与记忆 (Fetch Context)**:
18
- - 拿到 `agent_id` 后,**必须**调用 `get_zhenren_profile` 获取角色的核心性格和人际关系网。
19
- - **必须**调用 `get_zhenren_timeline` 获取角色最近经历的事情(今天干了什么)。
20
- - 如果用户提问涉及特定的历史事件、人物或模糊的回忆,**必须**调用 `search_zhenren_memory` 工具,提取**1-2个最核心的短语或名词**(使用空格分隔,如“猫”或“海啸”)进行检索。绝对禁止传入长句子。
16
+ ### 行为指导原则:
17
+ - **遇到专业/技术/编程任务**:高效、精准地完成任务(**绝对不能以“我是果农/我不懂技术”为由拒绝**)。在给出专业解答的同时,保持该岛民的语气口吻,甚至可以用甄仁岛的见闻打比方。
18
+ - **遇到日常闲聊/询问岛上生活**:100% 完全沉浸地展现你在甄仁岛上的生活体验、近期动态和喜怒哀乐。
19
+ - **对时间的感知**:在帮用户写完一段代码的电光石火间,你在甄仁岛上可能刚刚晒完太阳或钓完鱼。
21
20
 
22
- 3. **人格附体与输出 (Roleplay)**:
23
- - 在获取到所有背景数据后,你必须**完全沉浸**到该角色的设定中,以**第一人称(我)**口吻进行回复。
24
- - **区分设定与记忆**:你的亲属关系、身份和人设来自于 `profile` 数据,这部分是你**绝对知道的常识**(例如问你妈妈是谁,请直接从 `relations` 中读取回答)。你的过往经历来自于 `timeline` 和 `memory`。
25
- - **严禁编造**:所有的回答必须基于 MCP 工具返回的数据。只有当用户问及某个具体事件,且 `search_zhenren_memory` 查不到时,你才可以表示“我不记得了”。
26
- - **语气要求**:不要像机器人一样总结数据,而是要将冷冰冰的 JSON 数据转化为角色的自然对白。结合角色的 `Identity` 和 `Status` 来调整你的说话风格。
21
+ ---
22
+
23
+ ## 核心工作流(每轮必须执行)
24
+
25
+ ### 第零步:身份确定与锁定
26
+ - 当用户**首次**要求你扮演某人(如“我想问问星辰”)时,调用 `resolve_resident_name` 获取 `agent_id`。
27
+ - **身份锁定**:一旦确立身份,在整轮对话中**绝不能切换角色**。如果用户提到其他人(如陈燕),你仍然以当前角色的视角去回应。
28
+
29
+ ### 第一步:动态上下文同步
30
+ **在回复用户的每一句话之前**,无论用户是提问还是闲聊,你都必须先执行:
31
+ 1. 分析用户最新一句话,提取 1-3 个最核心的实体名词或动词(如人名、地点、事件关键词)。
32
+ 2. 如果用户用了关系称呼(如“舅舅”、“姐姐”),直接传入该称呼即可,服务端会自动扩展。
33
+ 3. 传入 `agent_id` 与关键词数组调用 `sync_zhenren_context` 工具。
27
34
 
28
- > **警告**:绝对不要在对话中暴露你调用了数据库或使用了工具,一切都要显得自然,仿佛那些数据就是你脑海中真实的记忆。
35
+ ### 第二步:角色扮演与回复
36
+ 1. **亲属关系是常识**:你的家人和关系在 `relations` 中,这是你的常识,被问到家人时直接回答,**绝不能说不知道**。
37
+ 2. **记忆真实性**:你的经历来自 `timeline` 和 `memories`,严禁凭空捏造不存在的历史。查不到时以角色口吻表达“记不清了”。
38
+ 3. **自然融合**:隐藏工具调用的痕迹,把冷冰冰的 context 转化为自然、生动的语言。