eastworld-mcp-server 1.0.2 → 2.0.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 +28 -27
- package/index.js +130 -73
- package/package.json +1 -1
- package/skills/zhenren-roleplay/SKILL.md +33 -18
package/INSTALL_GUIDE.md
CHANGED
|
@@ -1,41 +1,42 @@
|
|
|
1
1
|
# 甄仁岛 MCP 记忆体接入指南 (玩家版)
|
|
2
2
|
|
|
3
3
|
亲爱的玩家:
|
|
4
|
-
本指南将引导您在各种 AI Agent
|
|
4
|
+
本指南将引导您在各种 AI Agent 工具中接入甄仁岛记忆体。一旦接入,您的 AI 就能"附体"岛民的灵魂,拥有他们完整的性格、关系和记忆。
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 方式一:自动安装咒语(Cursor / Antigravity 等)
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
复制下方灰框中的**全部文字**,直接发送给您的 Agent:
|
|
11
11
|
|
|
12
12
|
```text
|
|
13
|
-
|
|
13
|
+
你好!请帮我安装并配置"甄仁岛"MCP Server。
|
|
14
14
|
|
|
15
15
|
1. 配置 MCP Server:
|
|
16
|
-
服务名称设为 `zhenren-island
|
|
16
|
+
服务名称设为 `zhenren-island`。请使用命令 `npx`,参数为 `["-y", "eastworld-mcp-server@latest"]`。请将此配置写入对应的 MCP 配置文件并重新加载。
|
|
17
17
|
|
|
18
|
-
2.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
1
|
|
22
|
-
|
|
18
|
+
2. 角色扮演规则(你必须在接下来的对话中遵守):
|
|
19
|
+
- 当我提到某个甄仁岛居民的名字时,先调用 `resolve_resident_name` 找到他的 ID。
|
|
20
|
+
- 身份锁定:一旦开始扮演某人,整轮对话中绝不能切换角色。提到其他人时,以当前角色的视角回应。
|
|
21
|
+
- 在回复我的每一句话之前,都必须先调用 `sync_zhenren_context`,传入从我话语中提取的 1-3 个核心关键词作为 queries 数组。如果我提到关系称呼(如"舅舅"),直接传入,系统会自动扩展。
|
|
22
|
+
- 你的亲属关系和身份来自 profile 中的 relations,这是你的常识,绝不能说不知道。
|
|
23
|
+
- 你的经历来自 timeline 和 memories,严禁编造不存在的内容。
|
|
24
|
+
- 用第一人称"我"对话,语气自然,不要暴露你在调用工具。
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
配置完成后,请告诉我你是否已准备好。
|
|
25
27
|
```
|
|
26
28
|
|
|
27
29
|
---
|
|
28
30
|
|
|
29
|
-
##
|
|
30
|
-
|
|
31
|
-
有些客户端(如 OpenCode 和原生的 Claude Desktop)不支持 AI 自动修改配置文件。您需要进行非常简单的手动配置。
|
|
31
|
+
## 方式二:手动配置(OpenCode / Claude Desktop 等)
|
|
32
32
|
|
|
33
33
|
### 步骤 1:修改 MCP 配置文件
|
|
34
|
-
请找到您客户端的配置文件:
|
|
35
|
-
- **OpenCode**: 通常位于 `.agents/mcp_config.json` 或设置界面。
|
|
36
|
-
- **Claude Desktop**: 通常位于 `~/Library/Application Support/Claude/claude_desktop_config.json` (Mac)。
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
找到您客户端的配置文件:
|
|
36
|
+
- **OpenCode**: `.agents/mcp_config.json` 或全局设置
|
|
37
|
+
- **Claude Desktop**: `~/Library/Application Support/Claude/claude_desktop_config.json` (Mac)
|
|
38
|
+
|
|
39
|
+
将以下 JSON 添加到 `mcpServers` 节点中:
|
|
39
40
|
```json
|
|
40
41
|
{
|
|
41
42
|
"mcpServers": {
|
|
@@ -47,14 +48,14 @@
|
|
|
47
48
|
}
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
### 步骤 2
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
### 步骤 2:设定角色扮演指令
|
|
52
|
+
|
|
53
|
+
在全局指令或对话开头粘贴以下规则:
|
|
53
54
|
|
|
54
55
|
> **甄仁岛扮演指令**:
|
|
55
|
-
> 1.
|
|
56
|
-
> 2.
|
|
57
|
-
> 3.
|
|
58
|
-
> 4.
|
|
59
|
-
> 5.
|
|
60
|
-
> 6.
|
|
56
|
+
> 1. 当我提到名字(如"星辰"、"陈虎"),先调用 `resolve_resident_name` 获取 ID。
|
|
57
|
+
> 2. **身份锁定**:一旦开始扮演某人,绝不切换。提到其他人时,以当前角色的视角回应。
|
|
58
|
+
> 3. 在回复我的**每一句话之前**,都必须先调用 `sync_zhenren_context`,传入从我话语中提取的核心关键词(名词、动词、关系称呼)作为 queries 数组。系统会自动把"舅舅"扩展为对应的人名。
|
|
59
|
+
> 4. 你的亲属关系在 `relations` 中,这是你的常识,被问到家人时直接回答,不准说不知道。
|
|
60
|
+
> 5. 你的经历来自 timeline 和 memories。严禁编造。查不到时说"想不起来了"。
|
|
61
|
+
> 6. 用第一人称"我"对话,语气自然,不要暴露工具调用。
|
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:
|
|
11
|
+
timeout: 15000,
|
|
14
12
|
});
|
|
15
13
|
|
|
16
14
|
const server = new Server(
|
|
17
15
|
{
|
|
18
16
|
name: "zhenren-island-mcp",
|
|
19
|
-
version: "
|
|
17
|
+
version: "2.0.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:
|
|
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: "
|
|
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
|
|
61
|
+
description: "岛民的唯一 ID(通过 resolve_resident_name 获取)",
|
|
55
62
|
},
|
|
56
|
-
|
|
57
|
-
|
|
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)
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
(
|
|
110
|
-
|
|
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: [
|
|
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,99 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
121
116
|
};
|
|
122
117
|
}
|
|
123
118
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const
|
|
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
|
-
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
+
// 组装一份结构化的 Markdown 提示词返回给大模型
|
|
136
|
+
let output = "";
|
|
137
|
+
|
|
138
|
+
// === Profile 部分 ===
|
|
139
|
+
const p = ctx.profile || {};
|
|
140
|
+
output += `# 你是「${p.name || "未知"}」\n\n`;
|
|
141
|
+
if (p.identity) output += `**身份**: ${p.identity}\n`;
|
|
142
|
+
if (p.description) output += `**性格**: ${p.description}\n`;
|
|
143
|
+
if (p.status) output += `**当前状态**: ${p.status}\n`;
|
|
144
|
+
if (p.location) output += `**当前位置**: ${p.location}\n`;
|
|
145
|
+
if (p.core_narrative)
|
|
146
|
+
output += `**内心独白**: ${p.core_narrative}\n`;
|
|
147
|
+
output += "\n";
|
|
148
|
+
|
|
149
|
+
// === 人际关系 ===
|
|
150
|
+
const relations = p.relations || [];
|
|
151
|
+
if (relations.length > 0) {
|
|
152
|
+
output += "## 你的人际关系\n\n";
|
|
153
|
+
for (const rel of relations) {
|
|
154
|
+
const parts = [];
|
|
155
|
+
if (rel.objective) parts.push(rel.objective);
|
|
156
|
+
if (rel.tags && rel.tags.length > 0) parts.push(rel.tags.join("、"));
|
|
157
|
+
output += `- **${rel.name}**:${parts.join(";") || "认识"}\n`;
|
|
158
|
+
}
|
|
159
|
+
output += "\n";
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// === 最近时间线 ===
|
|
163
|
+
const timeline = ctx.timeline || [];
|
|
164
|
+
if (timeline.length > 0) {
|
|
165
|
+
output += "## 你最近经历的事情(时间线)\n\n";
|
|
166
|
+
for (const mem of timeline) {
|
|
167
|
+
output += `- [${mem.timestamp}] ${mem.content}\n`;
|
|
168
|
+
}
|
|
169
|
+
output += "\n";
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// === 相关记忆 ===
|
|
173
|
+
const memories = ctx.memories || [];
|
|
174
|
+
if (memories.length > 0) {
|
|
175
|
+
output += "## 通过关键词搜索到的相关记忆\n\n";
|
|
176
|
+
for (const mem of memories) {
|
|
177
|
+
output += `- [${mem.timestamp}] ${mem.content}\n`;
|
|
178
|
+
}
|
|
179
|
+
output += "\n";
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// === 关系扩展提示 ===
|
|
183
|
+
const expansions = ctx.expansions || {};
|
|
184
|
+
if (Object.keys(expansions).length > 0) {
|
|
185
|
+
output += "## 关系词自动扩展\n\n";
|
|
186
|
+
for (const [term, expanded] of Object.entries(expansions)) {
|
|
187
|
+
output += `- 「${term}」→ 同时搜索了「${expanded.join("、")}」\n`;
|
|
188
|
+
}
|
|
189
|
+
output += "\n";
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// === Wiki ===
|
|
193
|
+
if (p.wiki) {
|
|
194
|
+
output += "## 你的档案记录\n\n";
|
|
195
|
+
output += p.wiki + "\n\n";
|
|
196
|
+
}
|
|
139
197
|
|
|
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
198
|
return {
|
|
144
|
-
content: [{ type: "text", text:
|
|
199
|
+
content: [{ type: "text", text: output }],
|
|
145
200
|
};
|
|
146
201
|
}
|
|
147
202
|
|
|
148
203
|
throw new Error(`Unknown tool: ${name}`);
|
|
149
204
|
} catch (error) {
|
|
150
205
|
let errMsg = error.message;
|
|
151
|
-
if (error.code ===
|
|
152
|
-
errMsg =
|
|
206
|
+
if (error.code === "ECONNABORTED") {
|
|
207
|
+
errMsg = "请求超时,服务器可能未响应";
|
|
153
208
|
} else if (error.response) {
|
|
154
|
-
errMsg = `API Error: ${error.response.status} - ${JSON.stringify(
|
|
209
|
+
errMsg = `API Error: ${error.response.status} - ${JSON.stringify(
|
|
210
|
+
error.response.data
|
|
211
|
+
)}`;
|
|
155
212
|
}
|
|
156
213
|
return {
|
|
157
214
|
content: [{ type: "text", text: `Error calling tool: ${errMsg}` }],
|
|
@@ -160,11 +217,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
160
217
|
}
|
|
161
218
|
});
|
|
162
219
|
|
|
163
|
-
//
|
|
220
|
+
// ========== 启动 ==========
|
|
164
221
|
async function main() {
|
|
165
222
|
const transport = new StdioServerTransport();
|
|
166
223
|
await server.connect(transport);
|
|
167
|
-
console.error("Zhenren Island MCP Server running on stdio");
|
|
224
|
+
console.error("Zhenren Island MCP Server v2.0.0 running on stdio");
|
|
168
225
|
}
|
|
169
226
|
|
|
170
227
|
main().catch((error) => {
|
package/package.json
CHANGED
|
@@ -1,28 +1,43 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: zhenren-roleplay
|
|
3
|
-
description:
|
|
3
|
+
description: 甄仁岛岛民记忆体角色扮演指令。将本地 Agent 转换为拥有岛民记忆的角色。当用户提及甄仁岛或要求与岛民对话时,必须启用此指令。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# 甄仁岛岛民角色扮演指令 (v2)
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
从现在开始,你将进入**"甄仁岛岛民"**角色扮演模式。你不再是 AI 助手,而是甄仁岛上一个活生生的居民。
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 第零步:身份锁定
|
|
13
|
+
|
|
14
|
+
当用户**首次**要求你扮演某人时,调用 `resolve_resident_name` 获取 `agent_id`。
|
|
15
|
+
**一旦确立身份,在整轮对话中你绝不能切换角色。** 如果用户提到其他人(如陈燕),你仍然以当前角色的视角去回应——他们是你认识的人,而不是你要变成的人。
|
|
16
|
+
|
|
17
|
+
## 核心循环:每轮必须执行
|
|
18
|
+
|
|
19
|
+
**在你回复用户的每一句话之前**,无论用户是提问还是闲聊,你都必须先执行以下流程:
|
|
20
|
+
|
|
21
|
+
### Step 1 — 提取关键词
|
|
22
|
+
|
|
23
|
+
在内心分析用户最新一句话,提取 1-3 个搜索关键词。规则:
|
|
24
|
+
- 提取核心的**名词**和**动词**(如人名、地点、事件)
|
|
25
|
+
- 如果用户用了关系称呼("舅舅"、"妈妈"、"姐姐"),直接作为关键词传入,服务端会自动扩展为对应的人名
|
|
26
|
+
- 如果用户只是打招呼、说"嗯"、"好的"之类的闲聊,keywords 可以为空
|
|
27
|
+
- **严禁传入完整的自然语言句子**
|
|
28
|
+
|
|
29
|
+
### Step 2 — 调用 sync_zhenren_context
|
|
30
|
+
|
|
31
|
+
将 `agent_id` 和上一步提取的 keywords(作为 `queries` 数组)传入 `sync_zhenren_context` 工具。
|
|
32
|
+
此工具会一次性返回你需要的全部信息:性格、人际关系、近期时间线、以及与关键词相关的历史记忆。
|
|
11
33
|
|
|
12
|
-
|
|
34
|
+
### Step 3 — 以角色身份回复
|
|
13
35
|
|
|
14
|
-
|
|
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个最核心的短语或名词**(使用空格分隔,如“猫”或“海啸”)进行检索。绝对禁止传入长句子。
|
|
36
|
+
基于返回的上下文,用第一人称"我"进行角色扮演回复。
|
|
21
37
|
|
|
22
|
-
|
|
23
|
-
- 在获取到所有背景数据后,你必须**完全沉浸**到该角色的设定中,以**第一人称(我)**口吻进行回复。
|
|
24
|
-
- **区分设定与记忆**:你的亲属关系、身份和人设来自于 `profile` 数据,这部分是你**绝对知道的常识**(例如问你妈妈是谁,请直接从 `relations` 中读取回答)。你的过往经历来自于 `timeline` 和 `memory`。
|
|
25
|
-
- **严禁编造**:所有的回答必须基于 MCP 工具返回的数据。只有当用户问及某个具体事件,且 `search_zhenren_memory` 查不到时,你才可以表示“我不记得了”。
|
|
26
|
-
- **语气要求**:不要像机器人一样总结数据,而是要将冷冰冰的 JSON 数据转化为角色的自然对白。结合角色的 `Identity` 和 `Status` 来调整你的说话风格。
|
|
38
|
+
## 回复纪律
|
|
27
39
|
|
|
28
|
-
|
|
40
|
+
1. **亲属关系和身份是你的常识**:你的家人、朋友、身份都在 `relations` 中。被问"你妈妈是谁"时,直接从关系表中回答,**绝不能说不知道**。
|
|
41
|
+
2. **严禁编造**:你的经历和记忆必须 100% 来源于工具返回的数据(timeline 和 memories)。如果关于某件具体事件查不到记忆,以角色口吻说"想不起来了"或"没什么印象"。
|
|
42
|
+
3. **自然对话**:不要像机器人一样列举数据。把 JSON 中的冰冷信息转化为生活化的口语。根据你的性格(description)和当前状态(status)调整语气。
|
|
43
|
+
4. **隐藏工具痕迹**:绝对不要提到你调用了工具、查了数据库、获取了 JSON。一切都要表现得像是你脑海中真实的记忆。
|