diff --git a/examples/cookbook/chapter1/API/1/test_memos_setup_api_mode.py b/examples/cookbook/chapter1/API/1/test_memos_setup_api_mode.py new file mode 100644 index 00000000..f77ae563 --- /dev/null +++ b/examples/cookbook/chapter1/API/1/test_memos_setup_api_mode.py @@ -0,0 +1,152 @@ +# test_memos_setup_api_mode.py +# 🎯 API模式验证脚本 - 使用OpenAI API和MOS.simple() +import os +import sys + +from dotenv import load_dotenv + + +def check_openai_environment(): + """🎯 检查OpenAI环境变量配置""" + print("🔍 检查OpenAI环境变量配置...") + + # 加载.env文件 + load_dotenv() + + # 检查OpenAI配置 + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + print("📋 OpenAI环境变量状态:") + + if openai_key: + masked_key = openai_key[:8] + "..." + openai_key[-4:] if len(openai_key) > 12 else "***" + print(f" ✅ OPENAI_API_KEY: {masked_key}") + print(f" ✅ OPENAI_API_BASE: {openai_base}") + return True + else: + print(" ❌ OPENAI_API_KEY: 未配置") + print(f" ❌ OPENAI_API_BASE: {openai_base}") + return False + + +def check_memos_installation(): + """🎯 检查MemOS安装状态""" + print("\n🔍 检查MemOS安装状态...") + + try: + import memos + + print(f"✅ MemOS版本: {memos.__version__}") + + # 测试核心组件导入 + from memos.configs.mem_os import MOSConfig + from memos.mem_cube.general import GeneralMemCube + from memos.mem_os.main import MOS + + print("✅ 核心组件导入成功") + return True + + except ImportError as e: + print(f"❌ 导入失败: {e}") + return False + except Exception as e: + print(f"❌ 其他错误: {e}") + return False + + +def test_api_functionality(): + """🎯 测试API模式功能""" + print("\n🔍 测试API模式功能...") + + try: + from memos.mem_os.main import MOS + + # 加载环境变量获取模型配置 + load_dotenv() + chat_model = os.getenv("OPENAI_API_CHAT_MODEL", "gpt-4o-mini") + embed_model = os.getenv("OPENAI_API_EMBED_MODEL", "text-embedding-3-small") + + print(f"🤖 使用聊天模型: {chat_model}") + print(f"🔍 使用嵌入模型: {embed_model}") + + # 使用默认的MOS.simple()方法 + print("🚀 创建MOS实例(使用MOS.simple())...") + memory = MOS.simple() + + print("✅ MOS.simple() 创建成功!") + print(f" 📊 用户ID: {memory.user_id}") + print(f" 📊 会话ID: {memory.session_id}") + + # 测试添加记忆 + print("\n🧠 测试添加记忆...") + memory.add(memory_content="这是一个API模式的测试记忆") + print("✅ 记忆添加成功!") + + # 测试聊天功能 + print("\n💬 测试聊天功能...") + response = memory.chat("我刚才添加了什么记忆?") + print(f"✅ 聊天响应: {response}") + + # 测试搜索功能 + print("\n🔍 测试搜索功能...") + search_results = memory.search("测试记忆", top_k=3) + if search_results and search_results.get("text_mem"): + print(f"✅ 搜索成功,找到 {len(search_results['text_mem'])} 个结果") + else: + print("⚠️ 搜索未返回结果") + + print("✅ API模式功能测试成功!") + return True + + except Exception as e: + print(f"❌ API模式功能测试失败: {e}") + print("💡 提示:请检查OpenAI API密钥和网络连接。") + return False + + +def main(): + """🎯 API模式主验证流程""" + print("🚀 开始MemOS API模式环境验证...\n") + + # 步骤1: 检查OpenAI环境变量 + env_ok = check_openai_environment() + + # 步骤2: 检查安装状态 + install_ok = check_memos_installation() + + # 步骤3: 测试功能 + if env_ok and install_ok: + func_ok = test_api_functionality() + else: + func_ok = False + if not env_ok: + print("\n⚠️ 由于OpenAI环境变量配置不完整,跳过功能测试") + elif not install_ok: + print("\n⚠️ 由于MemOS安装失败,跳过功能测试") + + # 总结 + print("\n" + "=" * 50) + print("📊 API模式验证结果总结:") + print(f" OpenAI环境变量: {'✅ 通过' if env_ok else '❌ 失败'}") + print(f" MemOS安装: {'✅ 通过' if install_ok else '❌ 失败'}") + print(f" 功能测试: {'✅ 通过' if func_ok else '❌ 失败'}") + + if env_ok and install_ok and func_ok: + print("\n🎉 恭喜!MemOS API模式环境配置完全成功!") + print("💡 你现在可以开始使用MemOS API模式了。") + elif install_ok and env_ok: + print("\n⚠️ MemOS已安装,OpenAI已配置,但功能测试失败。") + print("💡 请检查OpenAI API密钥是否有效,网络连接是否正常。") + elif install_ok: + print("\n⚠️ MemOS已安装,但需要配置OpenAI环境变量才能正常使用。") + print("💡 请在.env文件中配置OPENAI_API_KEY。") + else: + print("\n❌ 环境配置存在问题,请检查上述错误信息。") + + return bool(env_ok and install_ok and func_ok) + + +if __name__ == "__main__": + success = main() + sys.exit(0 if success else 1) diff --git a/examples/cookbook/chapter1/API/2/create_memcube_with_memreader_api.py b/examples/cookbook/chapter1/API/2/create_memcube_with_memreader_api.py new file mode 100644 index 00000000..d1962fdf --- /dev/null +++ b/examples/cookbook/chapter1/API/2/create_memcube_with_memreader_api.py @@ -0,0 +1,211 @@ +# create_memcube_with_memreader_api.py +# 🎯 使用MemReader创建MemCube的完整流程 (API版) +import os +import uuid + +from dotenv import load_dotenv + +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.configs.mem_reader import MemReaderConfigFactory +from memos.mem_cube.general import GeneralMemCube +from memos.mem_reader.factory import MemReaderFactory + + +# 加载环境变量 +load_dotenv() + +# 获取OpenAI配置 +openai_key = os.getenv("OPENAI_API_KEY") +openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + +if not openai_key: + raise ValueError("❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。") + +print("✅ 检测到OpenAI API模式") + +# 获取MemOS配置 +user_id = os.getenv("MOS_USER_ID", "default_user") +top_k = int(os.getenv("MOS_TOP_K", "5")) + +# 获取模型配置 +chat_model = os.getenv("OPENAI_API_CHAT_MODEL", "gpt-4o-mini") +embed_model = os.getenv("OPENAI_API_EMBED_MODEL", "text-embedding-3-small") + + +def create_memcube_with_memreader(): + """ + 🎯 使用MemReader创建MemCube的完整流程 (API版) + """ + + print("🔧 创建MemCube配置...") + + print(f"🤖 使用聊天模型: {chat_model}") + print(f"🔍 使用嵌入模型: {embed_model}") + + # OpenAI模式配置 + cube_config = { + "user_id": user_id, + "cube_id": f"{user_id}_company_handbook_cube", + "text_mem": { + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "openai", + "config": { + "model_name_or_path": chat_model, + "temperature": 0.8, + "max_tokens": 8192, + "top_p": 0.9, + "top_k": 50, + "api_key": openai_key, + "api_base": openai_base, + }, + }, + "embedder": { + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": embed_model, + "base_url": openai_base, + }, + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"{user_id}_company_handbook", + "vector_dimension": 1536, + "distance_metric": "cosine", + }, + }, + }, + }, + "act_mem": {"backend": "uninitialized"}, + "para_mem": {"backend": "uninitialized"}, + } + + # 创建MemCube实例 + config_obj = GeneralMemCubeConfig.model_validate(cube_config) + mem_cube = GeneralMemCube(config_obj) + + print("✅ MemCube创建成功!") + print(f" 📊 用户ID: {mem_cube.config.user_id}") + print(f" 📊 MemCube ID: {mem_cube.config.cube_id}") + print(f" 📊 文本记忆后端: {mem_cube.config.text_mem.backend}") + print(f" 🔍 嵌入模型: {embed_model} (OpenAI)") + print(" 🎯 配置模式: OPENAI API") + + return mem_cube + + +def create_memreader_config(): + """ + 🎯 创建MemReader配置 + """ + + # 加载环境变量 + load_dotenv() + + # 获取OpenAI配置 + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + # 获取模型配置 + chat_model = os.getenv("OPENAI_API_CHAT_MODEL", "gpt-4o-mini") + embed_model = os.getenv("OPENAI_API_EMBED_MODEL", "text-embedding-3-small") + + # MemReader配置 + mem_reader_config = MemReaderConfigFactory( + backend="simple_struct", + config={ + "llm": { + "backend": "openai", + "config": { + "model_name_or_path": chat_model, + "temperature": 0.8, + "max_tokens": 8192, + "top_p": 0.9, + "top_k": 50, + "api_key": openai_key, + "api_base": openai_base, + }, + }, + "embedder": { + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": embed_model, + "base_url": openai_base, + }, + }, + "chunker": { + "backend": "sentence", + "config": {"chunk_size": 64, "chunk_overlap": 20, "min_sentences_per_chunk": 1}, + }, + "remove_prompt_example": False, + }, + ) + + return mem_reader_config + + +def load_document_to_memcube(mem_cube, doc_path): + """ + 🎯 使用MemReader加载文档到MemCube + """ + + print(f"\n📖 使用MemReader读取文档: {doc_path}") + + # 创建MemReader + mem_reader_config = create_memreader_config() + mem_reader = MemReaderFactory.from_config(mem_reader_config) + + # 准备文档数据 + print("📄 准备文档数据...") + documents = [doc_path] # MemReader期望的是文档路径列表 + + # 使用MemReader处理文档 + print("🧠 使用MemReader提取记忆...") + memories = mem_reader.get_memory( + documents, + type="doc", + info={"user_id": mem_cube.config.user_id, "session_id": str(uuid.uuid4())}, + ) + + print(f"📚 MemReader生成了 {len(memories)} 个记忆片段") + + # 添加记忆到MemCube + print("💾 添加记忆到MemCube...") + for mem in memories: + mem_cube.text_mem.add(mem) + + print(f"✅ 成功添加 {len(memories)} 个记忆片段到MemCube") + + # 输出基本信息 + print("\n📊 MemCube基本信息:") + print(f" 📁 文档来源: {doc_path}") + print(f" 📝 记忆片段数量: {len(memories)}") + print(" 🏷️ 文档类型: company_handbook") + print(" 💾 向量数据库: Qdrant (内存模式,释放内存即删除)") + print(f" 🔍 嵌入模型: {embed_model} (OpenAI)") + print(" 🎯 配置模式: OPENAI API") + print(" 🧠 记忆提取器: MemReader (simple_struct)") + + return mem_cube + + +if __name__ == "__main__": + print("🚀 开始使用MemReader创建文档MemCube (API版)...") + + # 创建MemCube + mem_cube = create_memcube_with_memreader() + + # 加载文档 + import os + + current_dir = os.path.dirname(os.path.abspath(__file__)) + doc_path = os.path.join(current_dir, "company_handbook.txt") + load_document_to_memcube(mem_cube, doc_path) + + print("\n🎉 MemCube创建完成!") diff --git a/examples/cookbook/chapter1/API/2/test_memcube_search_and_chat_api.py b/examples/cookbook/chapter1/API/2/test_memcube_search_and_chat_api.py new file mode 100644 index 00000000..9e72b04e --- /dev/null +++ b/examples/cookbook/chapter1/API/2/test_memcube_search_and_chat_api.py @@ -0,0 +1,171 @@ +# test_memcube_search_and_chat_api.py +# 🎯 测试MemCube的搜索和对话功能 (API版) +import os + +from dotenv import load_dotenv + +from memos.configs.mem_os import MOSConfig +from memos.mem_os.main import MOS + + +load_dotenv() + +user_id = os.getenv("MOS_USER_ID", "default_user") +top_k = int(os.getenv("MOS_TOP_K", "5")) +openai_key = os.getenv("OPENAI_API_KEY") +openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + +# 获取模型配置 +chat_model = os.getenv("OPENAI_API_CHAT_MODEL", "gpt-4o-mini") +embed_model = os.getenv("OPENAI_API_EMBED_MODEL", "text-embedding-3-small") + + +def create_mos_config(): + """ + 🎯 创建MOS配置 (API版) + """ + + if not openai_key: + raise ValueError("❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。") + + print(f"🤖 使用聊天模型: {chat_model}") + print(f"🔍 使用嵌入模型: {embed_model}") + + # OpenAI模式配置 + return MOSConfig( + user_id=user_id, + chat_model={ + "backend": "openai", + "config": { + "model_name_or_path": chat_model, + "api_key": openai_key, + "api_base": openai_base, + "temperature": 0.1, + "max_tokens": 1024, + }, + }, + mem_reader={ + "backend": "simple_struct", + "config": { + "llm": { + "backend": "openai", + "config": { + "model_name_or_path": chat_model, + "api_key": openai_key, + "api_base": openai_base, + }, + }, + "embedder": { + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": embed_model, + "base_url": openai_base, + }, + }, + "chunker": { + "backend": "sentence", + "config": { + "tokenizer_or_token_counter": "gpt2", + "chunk_size": 512, + "chunk_overlap": 128, + "min_sentences_per_chunk": 1, + }, + }, + }, + }, + enable_textual_memory=True, + top_k=top_k, + ) + + +def test_memcube_search_and_chat(): + """ + 🎯 测试MemCube的搜索和对话功能 (API版) + """ + + print("🚀 开始测试MemCube搜索和对话功能 (API版)...") + + # 导入步骤2的函数 + from create_memcube_with_memreader_api import ( + create_memcube_with_memreader, + load_document_to_memcube, + ) + + # 创建MemCube并加载文档 + print("\n1️⃣ 创建MemCube并加载文档...") + mem_cube = create_memcube_with_memreader() + # 加载文档 + import os + + current_dir = os.path.dirname(os.path.abspath(__file__)) + doc_path = os.path.join(current_dir, "company_handbook.txt") + load_document_to_memcube(mem_cube, doc_path) + + # 创建MOS配置 + print("\n2️⃣ 创建MOS配置...") + mos_config = create_mos_config() + + # 创建MOS实例并注册MemCube + print("3️⃣ 创建MOS实例并注册MemCube...") + mos = MOS(mos_config) + mos.register_mem_cube(mem_cube, mem_cube_id="handbook") + + print("✅ MOS实例创建成功!") + print(f" 📊 用户ID: {mos.user_id}") + print(f" 📊 会话ID: {mos.session_id}") + print(f" 📊 注册的MemCube: {list(mos.mem_cubes.keys())}") + print(" 🎯 配置模式: OPENAI API") + print(f" 🤖 聊天模型: {chat_model} (OpenAI)") + print(f" 🔍 嵌入模型: {embed_model} (OpenAI)") + + # 测试搜索功能 + print("\n🔍 测试搜索功能...") + test_queries = [ + "公司的工作时间是什么?", + "年假有多少天?", + "有什么福利待遇?", + "如何联系HR部门?", + ] + + for query in test_queries: + print(f"\n❓ 查询: {query}") + + # 使用MOS搜索 + search_results = mos.search(query, top_k=2) + + if search_results and search_results.get("text_mem"): + print(f"📋 找到 {len(search_results['text_mem'])} 个相关结果:") + for cube_result in search_results["text_mem"]: + cube_id = cube_result["cube_id"] + memories = cube_result["memories"] + print(f" 📦 MemCube: {cube_id}") + for i, memory in enumerate(memories[:2], 1): # 只显示前2个结果 + print(f" {i}. {memory.memory[:100]}...") + else: + print("😓 未找到相关结果") + + # 测试对话功能 + print("\n💬 测试对话功能...") + chat_questions = [ + "公司的工作时间安排是怎样的?", + "员工可以享受哪些福利?", + "如何联系IT支持部门?", + ] + + for question in chat_questions: + print(f"\n👤 问题: {question}") + + try: + response = mos.chat(question) + print(f"🤖 回答: {response}") + except Exception as e: + print(f"❌ 对话失败: {e}") + + print("\n🎉 测试完成!") + return mos + + +if __name__ == "__main__": + test_memcube_search_and_chat() diff --git a/examples/cookbook/chapter1/API/3/memcube_lifecycle_api.py b/examples/cookbook/chapter1/API/3/memcube_lifecycle_api.py new file mode 100644 index 00000000..89d3269d --- /dev/null +++ b/examples/cookbook/chapter1/API/3/memcube_lifecycle_api.py @@ -0,0 +1,405 @@ +# memcube_lifecycle_api.py +# 🎯 MemCube生命周期管理:创建、增加记忆、保存、读取、查询、删除 (API版) +import os +import shutil +import time + +from pathlib import Path + +from dotenv import load_dotenv + +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.mem_cube.general import GeneralMemCube + + +class MemCubeManager: + """ + 🎯 MemCube生命周期管理器 (API版) + """ + + def __init__(self, storage_root="./memcube_storage"): + self.storage_root = Path(storage_root) + self.storage_root.mkdir(exist_ok=True) + self.loaded_cubes = {} # 内存中的MemCube缓存 + + def create_empty_memcube(self, cube_id: str) -> GeneralMemCube: + """ + 🎯 创建一个空的MemCube(不包含示例数据) + """ + + # 加载环境变量 + load_dotenv() + + # 获取OpenAI配置 + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + if not openai_key: + raise ValueError("❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。") + + # 获取MemOS配置 + user_id = os.getenv("MOS_USER_ID", "demo_user") + + # OpenAI模式配置 + cube_config = { + "user_id": user_id, + "cube_id": cube_id, + "text_mem": { + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o-mini", + "temperature": 0.8, + "max_tokens": 8192, + "top_p": 0.9, + "top_k": 50, + "api_key": openai_key, + "api_base": openai_base, + }, + }, + "embedder": { + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": "text-embedding-ada-002", + "base_url": openai_base, + }, + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"collection_{cube_id}_{int(time.time())}", + "vector_dimension": 1536, + "distance_metric": "cosine", + }, + }, + }, + }, + "act_mem": {"backend": "uninitialized"}, + "para_mem": {"backend": "uninitialized"}, + } + + config_obj = GeneralMemCubeConfig.model_validate(cube_config) + mem_cube = GeneralMemCube(config_obj) + + print(f"✅ 创建空MemCube: {cube_id}") + return mem_cube + + def save_memcube(self, mem_cube: GeneralMemCube, cube_id: str) -> str: + """ + 🎯 保存MemCube到磁盘 + """ + + save_path = self.storage_root / cube_id + + print(f"💾 保存MemCube到: {save_path}") + + try: + # ⚠️ 如果目录存在,先清理 + if save_path.exists(): + shutil.rmtree(save_path) + + # 保存MemCube + mem_cube.dump(str(save_path)) + + print(f"✅ MemCube '{cube_id}' 保存成功") + return str(save_path) + + except Exception as e: + print(f"❌ 保存失败: {e}") + raise + + def load_memcube(self, cube_id: str) -> GeneralMemCube: + """ + 🎯 从磁盘加载MemCube + """ + + load_path = self.storage_root / cube_id + + if not load_path.exists(): + raise FileNotFoundError(f"MemCube '{cube_id}' 不存在于 {load_path}") + + print(f"📂 从磁盘加载MemCube: {load_path}") + + try: + # 从目录加载MemCube + mem_cube = GeneralMemCube.init_from_dir(str(load_path)) + + # 缓存到内存 + self.loaded_cubes[cube_id] = mem_cube + + print(f"✅ MemCube '{cube_id}' 加载成功") + return mem_cube + + except Exception as e: + print(f"❌ 加载失败: {e}") + raise + + def list_saved_memcubes(self) -> list: + """ + 🎯 列出所有已保存的MemCube + """ + + saved_cubes = [] + + for item in self.storage_root.iterdir(): + if item.is_dir(): + # 检查是否是有效的MemCube目录 + readme_path = item / "README.md" + if readme_path.exists(): + saved_cubes.append( + {"cube_id": item.name, "path": str(item), "size": self._get_dir_size(item)} + ) + + return saved_cubes + + def unload_memcube(self, cube_id: str) -> bool: + """ + 🎯 从内存中移除MemCube(不删除文件) + """ + + if cube_id in self.loaded_cubes: + del self.loaded_cubes[cube_id] + print(f"♻️ MemCube '{cube_id}' 已从内存中移除") + return True + else: + print(f"⚠️ MemCube '{cube_id}' 不在内存中") + return False + + def delete_memcube(self, cube_id: str) -> bool: + """ + 🎯 删除MemCube本地文件 + """ + + delete_path = self.storage_root / cube_id + + if not delete_path.exists(): + print(f"⚠️ MemCube '{cube_id}' 不存在于 {delete_path}") + return False + + print(f"🗑️ 删除MemCube文件: {delete_path}") + + try: + # 删除目录 + shutil.rmtree(delete_path) + + # 从内存缓存中移除(如果还在内存中) + if cube_id in self.loaded_cubes: + del self.loaded_cubes[cube_id] + + print(f"✅ MemCube '{cube_id}' 文件删除成功") + return True + + except Exception as e: + print(f"❌ 删除失败: {e}") + return False + + def _get_dir_size(self, path: Path) -> str: + """计算目录大小""" + total_size = sum(f.stat().st_size for f in path.rglob("*") if f.is_file()) + return f"{total_size / 1024:.1f} KB" + + +def add_memories_to_cube(mem_cube: GeneralMemCube, cube_name: str): + """ + 🎯 向MemCube增加记忆 + """ + + print(f"🧠 向 {cube_name} 增加记忆...") + + # 添加一些示例记忆(包含丰富的元数据) + memories = [ + { + "memory": "阿珍爱上了阿强", + "metadata": {"type": "fact", "source": "conversation", "confidence": 0.9}, + }, + { + "memory": "阿珍身高1米5", + "metadata": {"type": "fact", "source": "file", "confidence": 0.8}, + }, + { + "memory": "阿珍是一个刺客", + "metadata": {"type": "fact", "source": "web", "confidence": 0.7}, + }, + { + "memory": "阿强是一个程序员", + "metadata": {"type": "fact", "source": "conversation", "confidence": 0.9}, + }, + { + "memory": "阿强喜欢写代码", + "metadata": {"type": "fact", "source": "file", "confidence": 0.8}, + }, + ] + + mem_cube.text_mem.add(memories) + + print(f"✅ 成功添加 {len(memories)} 条记忆到 {cube_name}") + + # 显示当前记忆数量 + all_memories = mem_cube.text_mem.get_all() + print(f"📊 {cube_name} 当前总记忆数量: {len(all_memories)}") + + +def basic_query_memcube(mem_cube: GeneralMemCube, cube_name: str): + """ + 🎯 基础查询MemCube + """ + + print(f"🔍 基础查询 {cube_name}:") + + # 获取所有记忆 + all_memories = mem_cube.text_mem.get_all() + print(f" 📊 总记忆数量: {len(all_memories)}") + + # 搜索特定内容 + search_results = mem_cube.text_mem.search("爱情", top_k=1) + print(f" 🎯 搜索'爱情'的结果: {len(search_results)}条") + + for i, result in enumerate(search_results, 1): + print(f" {i}. {result.memory}") + + +def advanced_query_memcube(mem_cube: GeneralMemCube, cube_name: str): + """ + 🎯 进阶查询MemCube(元数据操作) + """ + + print(f"🔬 进阶查询 {cube_name}:") + + # 获取所有记忆 + all_memories = mem_cube.text_mem.get_all() + + # 1. 展示TextualMemoryItem的完整结构 + print(" 📋 第一条记忆的完整结构:") + first_memory = all_memories[0] + print(f" {first_memory}") + print(f" ID: {first_memory.id}") + print(f" 内容: {first_memory.memory}") + print(f" 元数据: {first_memory.metadata}") + print(f" 类型: {first_memory.metadata.type}") + print(f" 来源: {first_memory.metadata.source}") + print(f" 置信度: {first_memory.metadata.confidence}") + print() + + # 2. 元数据筛选 + print(" 🔍 元数据筛选:") + + # 筛选高置信度的记忆 + high_confidence = [ + m for m in all_memories if m.metadata.confidence and m.metadata.confidence >= 0.9 + ] + print(f" 高置信度记忆 (>=0.9): {len(high_confidence)}条") + for i, memory in enumerate(high_confidence, 1): + print(f" {i}. {memory.memory} (置信度: {memory.metadata.confidence})") + + # 筛选特定来源的记忆 + conversation_memories = [m for m in all_memories if m.metadata.source == "conversation"] + print(f" 对话来源记忆: {len(conversation_memories)}条") + for i, memory in enumerate(conversation_memories, 1): + print(f" {i}. {memory.memory} (来源: {memory.metadata.source})") + + # 筛选文件来源的记忆 + file_memories = [m for m in all_memories if m.metadata.source == "file"] + print(f" 文件来源记忆: {len(file_memories)}条") + for i, memory in enumerate(file_memories, 1): + print(f" {i}. {memory.memory} (来源: {memory.metadata.source})") + + # 3. 组合筛选 + print(" 🔍 组合筛选:") + high_conf_file = [ + m + for m in all_memories + if m.metadata.source == "file" and m.metadata.confidence and m.metadata.confidence >= 0.8 + ] + print(f" 高置信度文件记忆: {len(high_conf_file)}条") + for i, memory in enumerate(high_conf_file, 1): + print( + f" {i}. {memory.memory} (来源: {memory.metadata.source}, 置信度: {memory.metadata.confidence})" + ) + + # 4. 统计信息 + print(" 📊 统计信息:") + sources = {} + confidences = [] + + for memory in all_memories: + # 统计来源 + source = memory.metadata.source + sources[source] = sources.get(source, 0) + 1 + + # 收集置信度 + if memory.metadata.confidence: + confidences.append(memory.metadata.confidence) + + print(f" 来源分布: {sources}") + if confidences: + avg_confidence = sum(confidences) / len(confidences) + print(f" 平均置信度: {avg_confidence:.2f}") + + +# 🎯 演示完整的生命周期管理 +def demonstrate_lifecycle(): + """ + 演示MemCube的完整生命周期 (API版) + """ + + manager = MemCubeManager() + + print("🚀 开始MemCube生命周期演示 (API版)...\n") + + # 步骤1: 创建MemCube + print("1️⃣ 创建MemCube") + cube1 = manager.create_empty_memcube("demo_cube_1") + + # 步骤2: 增加记忆 + print("\n2️⃣ 增加记忆") + add_memories_to_cube(cube1, "demo_cube_1") + + # 步骤3: 保存到磁盘 + print("\n3️⃣ 保存MemCube到磁盘") + manager.save_memcube(cube1, "demo_cube_1") + + # 步骤4: 列出保存的MemCube + print("\n4️⃣ 列出已保存的MemCube") + saved_cubes = manager.list_saved_memcubes() + for cube_info in saved_cubes: + print(f" 📦 {cube_info['cube_id']} - {cube_info['size']}") + + # 步骤5: 从磁盘读取 + print("\n5️⃣ 从磁盘读取MemCube") + del cube1 # 💡 删除内存中的引用 + + reloaded_cube = manager.load_memcube("demo_cube_1") + + # 步骤6: 基础查询 + print("\n6️⃣ 基础查询") + basic_query_memcube(reloaded_cube, "重新加载的demo_cube_1") + + # 步骤7: 进阶查询(元数据操作) + print("\n7️⃣ 进阶查询(元数据操作)") + advanced_query_memcube(reloaded_cube, "重新加载的demo_cube_1") + + # 步骤8: 从内存中移除MemCube + print("\n8️⃣ 从内存中移除MemCube") + manager.unload_memcube("demo_cube_1") + + # 步骤9: 删除本地文件 + print("\n9️⃣ 删除本地文件") + manager.delete_memcube("demo_cube_1") + + +if __name__ == "__main__": + """ + 🎯 主函数 - 运行MemCube生命周期演示 (API版) + """ + try: + demonstrate_lifecycle() + print("\n🎉 MemCube生命周期演示完成!") + except Exception as e: + print(f"\n❌ 演示过程中出现错误: {e}") + import traceback + + traceback.print_exc() diff --git a/examples/cookbook/chapter1/Ollama/1/test_memos_setup_ollama_mode.py b/examples/cookbook/chapter1/Ollama/1/test_memos_setup_ollama_mode.py new file mode 100644 index 00000000..9afec4cf --- /dev/null +++ b/examples/cookbook/chapter1/Ollama/1/test_memos_setup_ollama_mode.py @@ -0,0 +1,261 @@ +# test_memos_setup_ollama_mode.py +# 🎯 Ollama模式验证脚本 - 使用本地Ollama模型和手动配置 +import os +import sys + +from dotenv import load_dotenv + + +def check_ollama_environment(): + """🎯 检查Ollama环境变量配置""" + print("🔍 检查Ollama环境变量配置...") + + # 加载.env文件 + load_dotenv() + + # 检查Ollama配置 + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + print("📋 Ollama环境变量状态:") + + if ollama_base_url: + print(f" ✅ OLLAMA_BASE_URL: {ollama_base_url}") + print(f" ✅ OLLAMA_CHAT_MODEL: {ollama_chat_model or '❌ 未配置'}") + print(f" ✅ OLLAMA_EMBED_MODEL: {ollama_embed_model or '❌ 未配置'}") + ollama_configured = bool(ollama_base_url and ollama_chat_model and ollama_embed_model) + + if ollama_configured: + print("✅ Ollama配置完整") + else: + print("❌ Ollama配置不完整") + + return ollama_configured + else: + print(" ❌ OLLAMA_BASE_URL: 未配置") + print(" ❌ OLLAMA_CHAT_MODEL: 未配置") + print(" ❌ OLLAMA_EMBED_MODEL: 未配置") + return False + + +def check_memos_installation(): + """🎯 检查MemOS安装状态""" + print("\n🔍 检查MemOS安装状态...") + + try: + import memos + + print(f"✅ MemOS版本: {memos.__version__}") + + # 测试核心组件导入 + from memos.configs.mem_cube import GeneralMemCubeConfig + from memos.configs.mem_os import MOSConfig + from memos.mem_cube.general import GeneralMemCube + from memos.mem_os.main import MOS + + print("✅ 核心组件导入成功") + return True + + except ImportError as e: + print(f"❌ 导入失败: {e}") + return False + except Exception as e: + print(f"❌ 其他错误: {e}") + return False + + +def test_ollama_functionality(): + """🎯 测试Ollama模式功能""" + print("\n🔍 测试Ollama模式功能...") + + try: + from memos.configs.mem_cube import GeneralMemCubeConfig + from memos.configs.mem_os import MOSConfig + from memos.mem_cube.general import GeneralMemCube + from memos.mem_os.main import MOS + + # 获取环境变量 + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + print("🚀 创建Ollama配置...") + + # 创建MOS配置 + mos_config = MOSConfig( + user_id=os.getenv("MOS_USER_ID", "default_user"), + chat_model={ + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + "temperature": 0.7, + "max_tokens": 1024, + }, + }, + mem_reader={ + "backend": "simple_struct", + "config": { + "llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + }, + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url, + }, + }, + "chunker": { + "backend": "sentence", + "config": { + "tokenizer_or_token_counter": "gpt2", + "chunk_size": 512, + "chunk_overlap": 128, + "min_sentences_per_chunk": 1, + }, + }, + }, + }, + enable_textual_memory=True, + top_k=int(os.getenv("MOS_TOP_K", "5")), + ) + + # 创建MemCube配置 + cube_config = GeneralMemCubeConfig( + user_id=os.getenv("MOS_USER_ID", "default_user"), + cube_id=f"{os.getenv('MOS_USER_ID', 'default_user')}_cube", + text_mem={ + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + }, + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url, + }, + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"{os.getenv('MOS_USER_ID', 'default_user')}_collection", + "vector_dimension": 768, # nomic-embed-text的维度 + "distance_metric": "cosine", + }, + }, + }, + }, + act_mem={"backend": "uninitialized"}, + para_mem={"backend": "uninitialized"}, + ) + + print("✅ 配置创建成功!") + + # 创建MOS实例和MemCube + print("🚀 创建MOS实例和MemCube...") + memory = MOS(mos_config) + mem_cube = GeneralMemCube(cube_config) + memory.register_mem_cube(mem_cube) + + print("✅ MOS实例和MemCube创建成功!") + print(f" 📊 用户ID: {memory.user_id}") + print(f" 📊 会话ID: {memory.session_id}") + print(f" 📊 MemCube ID: {mem_cube.config.cube_id}") + + # 测试添加记忆 + print("\n🧠 测试添加记忆...") + memory.add(memory_content="这是一个Ollama模式的测试记忆") + print("✅ 记忆添加成功!") + + # 测试聊天功能 + print("\n💬 测试聊天功能...") + response = memory.chat("我刚才添加了什么记忆?") + print(f"✅ 聊天响应: {response}") + + # 测试搜索功能 + print("\n🔍 测试搜索功能...") + search_results = memory.search("测试记忆", top_k=3) + if search_results and search_results.get("text_mem"): + print(f"✅ 搜索成功,找到 {len(search_results['text_mem'])} 个结果") + else: + print("⚠️ 搜索未返回结果") + + # 测试MemCube直接操作 + print("\n🔧 测试MemCube直接操作...") + mem_cube.text_mem.add( + [ + { + "memory": "这是通过MemCube直接添加的记忆", + "metadata": {"source": "conversation", "type": "fact", "confidence": 0.9}, + } + ] + ) + print("✅ MemCube直接操作成功!") + + print("✅ Ollama模式功能测试成功!") + return True + + except Exception as e: + print(f"❌ Ollama模式功能测试失败: {e}") + print("💡 提示:请检查Ollama服务是否运行,模型是否已下载。") + return False + + +def main(): + """🎯 Ollama模式主验证流程""" + print("🚀 开始MemOS Ollama模式环境验证...\n") + + # 步骤1: 检查Ollama环境变量 + env_ok = check_ollama_environment() + + # 步骤2: 检查安装状态 + install_ok = check_memos_installation() + + # 步骤3: 测试功能 + if env_ok and install_ok: + func_ok = test_ollama_functionality() + else: + func_ok = False + if not env_ok: + print("\n⚠️ 由于Ollama环境变量配置不完整,跳过功能测试") + elif not install_ok: + print("\n⚠️ 由于MemOS安装失败,跳过功能测试") + + # 总结 + print("\n" + "=" * 50) + print("📊 Ollama模式验证结果总结:") + print(f" Ollama环境变量: {'✅ 通过' if env_ok else '❌ 失败'}") + print(f" MemOS安装: {'✅ 通过' if install_ok else '❌ 失败'}") + print(f" 功能测试: {'✅ 通过' if func_ok else '❌ 失败'}") + + if env_ok and install_ok and func_ok: + print("\n🎉 恭喜!MemOS Ollama模式环境配置完全成功!") + print("💡 你现在可以开始使用MemOS Ollama模式了。") + print("💡 使用方式: 手动配置MOSConfig和GeneralMemCubeConfig") + elif install_ok and env_ok: + print("\n⚠️ MemOS已安装,Ollama已配置,但功能测试失败。") + print("💡 请检查Ollama服务是否运行,模型是否已下载。") + elif install_ok: + print("\n⚠️ MemOS已安装,但需要配置Ollama环境变量才能正常使用。") + print("💡 请在.env文件中配置OLLAMA_BASE_URL、OLLAMA_CHAT_MODEL、OLLAMA_EMBED_MODEL。") + else: + print("\n❌ 环境配置存在问题,请检查上述错误信息。") + + return bool(env_ok and install_ok and func_ok) + + +if __name__ == "__main__": + success = main() + sys.exit(0 if success else 1) diff --git a/examples/cookbook/chapter1/Ollama/2/create_memcube_with_memreader_ollama.py b/examples/cookbook/chapter1/Ollama/2/create_memcube_with_memreader_ollama.py new file mode 100644 index 00000000..b104e30c --- /dev/null +++ b/examples/cookbook/chapter1/Ollama/2/create_memcube_with_memreader_ollama.py @@ -0,0 +1,184 @@ +# create_memcube_with_memreader_ollama.py +# 🎯 使用MemReader创建MemCube的完整流程 (Ollama版) +import os +import uuid + +from dotenv import load_dotenv + +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.configs.mem_reader import MemReaderConfigFactory +from memos.mem_cube.general import GeneralMemCube +from memos.mem_reader.factory import MemReaderFactory + + +def create_memcube_with_memreader(): + """ + 🎯 使用MemReader创建MemCube的完整流程 (Ollama版) + """ + + print("🔧 创建MemCube配置...") + + # 加载环境变量 + load_dotenv() + + # 获取Ollama配置 + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError( + "❌ 未配置Ollama环境变量。请在.env文件中配置OLLAMA_BASE_URL、OLLAMA_CHAT_MODEL、OLLAMA_EMBED_MODEL。" + ) + + print("✅ 检测到Ollama本地模型模式") + + # 获取MemOS配置 + user_id = os.getenv("MOS_USER_ID", "default_user") + top_k = int(os.getenv("MOS_TOP_K", "5")) + + # Ollama模式配置 + cube_config = { + "user_id": user_id, + "cube_id": f"{user_id}_company_handbook_cube", + "text_mem": { + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + }, + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url, + }, + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"{user_id}_company_handbook", + "vector_dimension": 768, + "distance_metric": "cosine", + }, + }, + }, + }, + "act_mem": {"backend": "uninitialized"}, + "para_mem": {"backend": "uninitialized"}, + } + + # 创建MemCube实例 + config_obj = GeneralMemCubeConfig.model_validate(cube_config) + mem_cube = GeneralMemCube(config_obj) + + print("✅ MemCube创建成功!") + print(f" 📊 用户ID: {mem_cube.config.user_id}") + print(f" 📊 MemCube ID: {mem_cube.config.cube_id}") + print(f" 📊 文本记忆后端: {mem_cube.config.text_mem.backend}") + print(f" 🔍 嵌入模型: {ollama_embed_model} (Ollama)") + print(" 🎯 配置模式: OLLAMA") + + return mem_cube + + +def create_memreader_config(): + """ + 🎯 创建MemReader配置 (Ollama版) + """ + + # 加载环境变量 + load_dotenv() + + # 获取Ollama配置 + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + # MemReader配置 + mem_reader_config = MemReaderConfigFactory( + backend="simple_struct", + config={ + "llm": { + "backend": "ollama", + "config": {"model_name_or_path": ollama_chat_model, "api_base": ollama_base_url}, + }, + "embedder": { + "backend": "ollama", + "config": {"model_name_or_path": ollama_embed_model, "api_base": ollama_base_url}, + }, + "chunker": { + "backend": "sentence", + "config": {"chunk_size": 128, "chunk_overlap": 32, "min_sentences_per_chunk": 1}, + }, + "remove_prompt_example": False, + }, + ) + + return mem_reader_config + + +def load_document_to_memcube(mem_cube, doc_path): + """ + 🎯 使用MemReader加载文档到MemCube (Ollama版) + """ + + print(f"\n📖 使用MemReader读取文档: {doc_path}") + + # 创建MemReader + mem_reader_config = create_memreader_config() + mem_reader = MemReaderFactory.from_config(mem_reader_config) + + # 准备文档数据 + print("📄 准备文档数据...") + documents = [doc_path] # MemReader期望的是文档路径列表 + + # 使用MemReader处理文档 + print("🧠 使用MemReader提取记忆...") + memories = mem_reader.get_memory( + documents, + type="doc", + info={"user_id": mem_cube.config.user_id, "session_id": str(uuid.uuid4())}, + ) + + print(f"📚 MemReader生成了 {len(memories)} 个记忆片段") + + # 添加记忆到MemCube + print("💾 添加记忆到MemCube...") + for mem in memories: + mem_cube.text_mem.add(mem) + print(mem) + + print(f"✅ 成功添加 {len(memories)} 个记忆片段到MemCube") + + # 输出基本信息 + print("\n📊 MemCube基本信息:") + print(f" 📁 文档来源: {doc_path}") + print(f" 📝 记忆片段数量: {len(memories)}") + print(" 🏷️ 文档类型: company_handbook") + print(" 💾 向量数据库: Qdrant (内存模式,释放内存即删除)") + print(f" 🔍 嵌入模型: {os.getenv('OLLAMA_EMBED_MODEL')} (Ollama)") + print(" 🎯 配置模式: OLLAMA") + print(" 🧠 记忆提取器: MemReader (simple_struct)") + + return mem_cube + + +if __name__ == "__main__": + print("🚀 开始使用MemReader创建文档MemCube (Ollama版)...") + + # 创建MemCube + mem_cube = create_memcube_with_memreader() + + # 加载文档 + import os + + current_dir = os.path.dirname(os.path.abspath(__file__)) + doc_path = os.path.join(current_dir, "company_handbook.txt") + load_document_to_memcube(mem_cube, doc_path) + + print("\n🎉 MemCube创建完成!") diff --git a/examples/cookbook/chapter1/Ollama/2/test_memcube_search_and_chat_ollama.py b/examples/cookbook/chapter1/Ollama/2/test_memcube_search_and_chat_ollama.py new file mode 100644 index 00000000..037e0f3d --- /dev/null +++ b/examples/cookbook/chapter1/Ollama/2/test_memcube_search_and_chat_ollama.py @@ -0,0 +1,161 @@ +# test_memcube_search_and_chat_ollama.py +# 🎯 测试MemCube的搜索和对话功能 (Ollama版) +import os + +from dotenv import load_dotenv + +from memos.configs.mem_os import MOSConfig +from memos.mem_os.main import MOS + + +def create_mos_config(): + """ + 🎯 创建MOS配置 (Ollama版) + """ + load_dotenv() + + user_id = os.getenv("MOS_USER_ID", "default_user") + top_k = int(os.getenv("MOS_TOP_K", "5")) + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError( + "❌ 未配置Ollama环境变量。请在.env文件中配置OLLAMA_BASE_URL、OLLAMA_CHAT_MODEL、OLLAMA_EMBED_MODEL。" + ) + + # Ollama模式配置 + return MOSConfig( + user_id=user_id, + chat_model={ + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + "temperature": 0.1, + "max_tokens": 1024, + }, + }, + mem_reader={ + "backend": "simple_struct", + "config": { + "llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + }, + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url, + }, + }, + "chunker": { + "backend": "sentence", + "config": { + "tokenizer_or_token_counter": "gpt2", + "chunk_size": 512, + "chunk_overlap": 128, + "min_sentences_per_chunk": 1, + }, + }, + }, + }, + enable_textual_memory=True, + top_k=top_k, + ) + + +def test_memcube_search_and_chat(): + """ + 🎯 测试MemCube的搜索和对话功能 (Ollama版) + """ + + print("🚀 开始测试MemCube搜索和对话功能 (Ollama版)...") + + # 导入步骤2的函数 + from create_memcube_with_memreader_ollama import ( + create_memcube_with_memreader, + load_document_to_memcube, + ) + + # 创建MemCube并加载文档 + print("\n1️⃣ 创建MemCube并加载文档...") + mem_cube = create_memcube_with_memreader() + # 加载文档 + import os + + current_dir = os.path.dirname(os.path.abspath(__file__)) + doc_path = os.path.join(current_dir, "company_handbook.txt") + load_document_to_memcube(mem_cube, doc_path) + + # 创建MOS配置 + print("\n2️⃣ 创建MOS配置...") + mos_config = create_mos_config() + + # 创建MOS实例并注册MemCube + print("3️⃣ 创建MOS实例并注册MemCube...") + mos = MOS(mos_config) + mos.register_mem_cube(mem_cube, mem_cube_id="handbook") + + print("✅ MOS实例创建成功!") + print(f" 📊 用户ID: {mos.user_id}") + print(f" 📊 会话ID: {mos.session_id}") + print(f" 📊 注册的MemCube: {list(mos.mem_cubes.keys())}") + print(" 🎯 配置模式: OLLAMA") + print(f" 🤖 聊天模型: {os.getenv('OLLAMA_CHAT_MODEL')} (Ollama)") + print(f" 🔍 嵌入模型: {os.getenv('OLLAMA_EMBED_MODEL')} (Ollama)") + + # 测试搜索功能 + print("\n🔍 测试搜索功能...") + test_queries = [ + "公司的工作时间是什么?", + "年假有多少天?", + "有什么福利待遇?", + "如何联系HR部门?", + ] + + for query in test_queries: + print(f"\n❓ 查询: {query}") + + # 使用MOS搜索 + search_results = mos.search(query, top_k=2) + + if search_results and search_results.get("text_mem"): + print(f"📋 找到 {len(search_results['text_mem'])} 个相关结果:") + for cube_result in search_results["text_mem"]: + cube_id = cube_result["cube_id"] + memories = cube_result["memories"] + print(f" 📦 MemCube: {cube_id}") + for i, memory in enumerate(memories[:2], 1): # 只显示前2个结果 + print(f" {i}. {memory.memory[:100]}...") + else: + print("😓 未找到相关结果") + + # 测试对话功能 + print("\n💬 测试对话功能...") + chat_questions = [ + "公司的工作时间安排是怎样的?", + "员工可以享受哪些福利?", + "如何联系IT支持部门?", + ] + + for question in chat_questions: + print(f"\n👤 问题: {question}") + + try: + response = mos.chat(question) + print(f"🤖 回答: {response}") + except Exception as e: + print(f"❌ 对话失败: {e}") + + print("\n🎉 测试完成!") + return mos + + +if __name__ == "__main__": + test_memcube_search_and_chat() diff --git a/examples/cookbook/chapter1/Ollama/3/memcube_lifecycle_ollama.py b/examples/cookbook/chapter1/Ollama/3/memcube_lifecycle_ollama.py new file mode 100644 index 00000000..2894f763 --- /dev/null +++ b/examples/cookbook/chapter1/Ollama/3/memcube_lifecycle_ollama.py @@ -0,0 +1,403 @@ +# memcube_lifecycle_ollama.py +# 🎯 MemCube生命周期管理:创建、增加记忆、保存、读取、查询、删除 (Ollama版) +import os +import shutil +import time + +from pathlib import Path + +from dotenv import load_dotenv + +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.mem_cube.general import GeneralMemCube + + +class MemCubeManager: + """ + 🎯 MemCube生命周期管理器 (Ollama版) + """ + + def __init__(self, storage_root="./memcube_storage"): + self.storage_root = Path(storage_root) + self.storage_root.mkdir(exist_ok=True) + self.loaded_cubes = {} # 内存中的MemCube缓存 + + def create_empty_memcube(self, cube_id: str) -> GeneralMemCube: + """ + 🎯 创建一个空的MemCube(不包含示例数据) + """ + + # 加载环境变量 + load_dotenv() + + # 获取Ollama配置 + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError( + "❌ 未配置Ollama环境变量。请在.env文件中配置OLLAMA_BASE_URL、OLLAMA_CHAT_MODEL、OLLAMA_EMBED_MODEL。" + ) + + print("✅ 检测到Ollama本地模型模式") + + # 获取MemOS配置 + user_id = os.getenv("MOS_USER_ID", "demo_user") + + # Ollama模式配置 + cube_config = { + "user_id": user_id, + "cube_id": cube_id, + "text_mem": { + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + }, + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url, + }, + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"collection_{cube_id}_{int(time.time())}", + "vector_dimension": 768, + "distance_metric": "cosine", + }, + }, + }, + }, + "act_mem": {"backend": "uninitialized"}, + "para_mem": {"backend": "uninitialized"}, + } + + config_obj = GeneralMemCubeConfig.model_validate(cube_config) + mem_cube = GeneralMemCube(config_obj) + + print(f"✅ 创建空MemCube: {cube_id}") + return mem_cube + + def save_memcube(self, mem_cube: GeneralMemCube, cube_id: str) -> str: + """ + 🎯 保存MemCube到磁盘 + """ + + save_path = self.storage_root / cube_id + + print(f"💾 保存MemCube到: {save_path}") + + try: + # ⚠️ 如果目录存在,先清理 + if save_path.exists(): + shutil.rmtree(save_path) + + # 保存MemCube + mem_cube.dump(str(save_path)) + + print(f"✅ MemCube '{cube_id}' 保存成功") + return str(save_path) + + except Exception as e: + print(f"❌ 保存失败: {e}") + raise + + def load_memcube(self, cube_id: str) -> GeneralMemCube: + """ + 🎯 从磁盘加载MemCube + """ + + load_path = self.storage_root / cube_id + + if not load_path.exists(): + raise FileNotFoundError(f"MemCube '{cube_id}' 不存在于 {load_path}") + + print(f"📂 从磁盘加载MemCube: {load_path}") + + try: + # 从目录加载MemCube + mem_cube = GeneralMemCube.init_from_dir(str(load_path)) + + # 缓存到内存 + self.loaded_cubes[cube_id] = mem_cube + + print(f"✅ MemCube '{cube_id}' 加载成功") + return mem_cube + + except Exception as e: + print(f"❌ 加载失败: {e}") + raise + + def list_saved_memcubes(self) -> list: + """ + 🎯 列出所有已保存的MemCube + """ + + saved_cubes = [] + + for item in self.storage_root.iterdir(): + if item.is_dir(): + # 检查是否是有效的MemCube目录 + readme_path = item / "README.md" + if readme_path.exists(): + saved_cubes.append( + {"cube_id": item.name, "path": str(item), "size": self._get_dir_size(item)} + ) + + return saved_cubes + + def unload_memcube(self, cube_id: str) -> bool: + """ + 🎯 从内存中移除MemCube(不删除文件) + """ + + if cube_id in self.loaded_cubes: + del self.loaded_cubes[cube_id] + print(f"♻️ MemCube '{cube_id}' 已从内存中移除") + return True + else: + print(f"⚠️ MemCube '{cube_id}' 不在内存中") + return False + + def delete_memcube(self, cube_id: str) -> bool: + """ + 🎯 删除MemCube本地文件 + """ + + delete_path = self.storage_root / cube_id + + if not delete_path.exists(): + print(f"⚠️ MemCube '{cube_id}' 不存在于 {delete_path}") + return False + + print(f"🗑️ 删除MemCube文件: {delete_path}") + + try: + # 删除目录 + shutil.rmtree(delete_path) + + # 从内存缓存中移除(如果还在内存中) + if cube_id in self.loaded_cubes: + del self.loaded_cubes[cube_id] + + print(f"✅ MemCube '{cube_id}' 文件删除成功") + return True + + except Exception as e: + print(f"❌ 删除失败: {e}") + return False + + def _get_dir_size(self, path: Path) -> str: + """计算目录大小""" + total_size = sum(f.stat().st_size for f in path.rglob("*") if f.is_file()) + return f"{total_size / 1024:.1f} KB" + + +def add_memories_to_cube(mem_cube: GeneralMemCube, cube_name: str): + """ + 🎯 向MemCube增加记忆 + """ + + print(f"🧠 向 {cube_name} 增加记忆...") + + # 添加一些示例记忆(包含丰富的元数据) + memories = [ + { + "memory": "阿珍爱上了阿强", + "metadata": {"type": "fact", "source": "conversation", "confidence": 0.9}, + }, + { + "memory": "阿珍身高1米5", + "metadata": {"type": "fact", "source": "file", "confidence": 0.8}, + }, + { + "memory": "阿珍是一个刺客", + "metadata": {"type": "fact", "source": "web", "confidence": 0.7}, + }, + { + "memory": "阿强是一个程序员", + "metadata": {"type": "fact", "source": "conversation", "confidence": 0.9}, + }, + { + "memory": "阿强喜欢写代码", + "metadata": {"type": "fact", "source": "file", "confidence": 0.8}, + }, + ] + + mem_cube.text_mem.add(memories) + + print(f"✅ 成功添加 {len(memories)} 条记忆到 {cube_name}") + + # 显示当前记忆数量 + all_memories = mem_cube.text_mem.get_all() + print(f"📊 {cube_name} 当前总记忆数量: {len(all_memories)}") + + +def basic_query_memcube(mem_cube: GeneralMemCube, cube_name: str): + """ + 🎯 基础查询MemCube + """ + + print(f"🔍 基础查询 {cube_name}:") + + # 获取所有记忆 + all_memories = mem_cube.text_mem.get_all() + print(f" 📊 总记忆数量: {len(all_memories)}") + + # 搜索特定内容 + search_results = mem_cube.text_mem.search("爱情", top_k=1) + print(f" 🎯 搜索'爱情'的结果: {len(search_results)}条") + + for i, result in enumerate(search_results, 1): + print(f" {i}. {result.memory}") + + +def advanced_query_memcube(mem_cube: GeneralMemCube, cube_name: str): + """ + 🎯 进阶查询MemCube(元数据操作) + """ + + print(f"🔬 进阶查询 {cube_name}:") + + # 获取所有记忆 + all_memories = mem_cube.text_mem.get_all() + + # 1. 展示TextualMemoryItem的完整结构 + print(" 📋 第一条记忆的完整结构:") + first_memory = all_memories[0] + print(f" {first_memory}") + print(f" ID: {first_memory.id}") + print(f" 内容: {first_memory.memory}") + print(f" 元数据: {first_memory.metadata}") + print(f" 类型: {first_memory.metadata.type}") + print(f" 来源: {first_memory.metadata.source}") + print(f" 置信度: {first_memory.metadata.confidence}") + print() + + # 2. 元数据筛选 + print(" 🔍 元数据筛选:") + + # 筛选高置信度的记忆 + high_confidence = [ + m for m in all_memories if m.metadata.confidence and m.metadata.confidence >= 0.9 + ] + print(f" 高置信度记忆 (>=0.9): {len(high_confidence)}条") + for i, memory in enumerate(high_confidence, 1): + print(f" {i}. {memory.memory} (置信度: {memory.metadata.confidence})") + + # 筛选特定来源的记忆 + conversation_memories = [m for m in all_memories if m.metadata.source == "conversation"] + print(f" 对话来源记忆: {len(conversation_memories)}条") + for i, memory in enumerate(conversation_memories, 1): + print(f" {i}. {memory.memory} (来源: {memory.metadata.source})") + + # 筛选文件来源的记忆 + file_memories = [m for m in all_memories if m.metadata.source == "file"] + print(f" 文件来源记忆: {len(file_memories)}条") + for i, memory in enumerate(file_memories, 1): + print(f" {i}. {memory.memory} (来源: {memory.metadata.source})") + + # 3. 组合筛选 + print(" 🔍 组合筛选:") + high_conf_file = [ + m + for m in all_memories + if m.metadata.source == "file" and m.metadata.confidence and m.metadata.confidence >= 0.8 + ] + print(f" 高置信度文件记忆: {len(high_conf_file)}条") + for i, memory in enumerate(high_conf_file, 1): + print( + f" {i}. {memory.memory} (来源: {memory.metadata.source}, 置信度: {memory.metadata.confidence})" + ) + + # 4. 统计信息 + print(" 📊 统计信息:") + sources = {} + confidences = [] + + for memory in all_memories: + # 统计来源 + source = memory.metadata.source + sources[source] = sources.get(source, 0) + 1 + + # 收集置信度 + if memory.metadata.confidence: + confidences.append(memory.metadata.confidence) + + print(f" 来源分布: {sources}") + if confidences: + avg_confidence = sum(confidences) / len(confidences) + print(f" 平均置信度: {avg_confidence:.2f}") + + +# 🎯 演示完整的生命周期管理 +def demonstrate_lifecycle(): + """ + 演示MemCube的完整生命周期 + """ + + manager = MemCubeManager() + + print("🚀 开始MemCube生命周期演示...\n") + + # 步骤1: 创建MemCube + print("1️⃣ 创建MemCube") + cube1 = manager.create_empty_memcube("demo_cube_1") + + # 步骤2: 增加记忆 + print("\n2️⃣ 增加记忆") + add_memories_to_cube(cube1, "demo_cube_1") + + # 步骤3: 保存到磁盘 + print("\n3️⃣ 保存MemCube到磁盘") + manager.save_memcube(cube1, "demo_cube_1") + + # 步骤4: 列出保存的MemCube + print("\n4️⃣ 列出已保存的MemCube") + saved_cubes = manager.list_saved_memcubes() + for cube_info in saved_cubes: + print(f" 📦 {cube_info['cube_id']} - {cube_info['size']}") + + # 步骤5: 从磁盘读取 + print("\n5️⃣ 从磁盘读取MemCube") + del cube1 # 💡 删除内存中的引用 + + reloaded_cube = manager.load_memcube("demo_cube_1") + + # 步骤6: 基础查询 + print("\n6️⃣ 基础查询") + basic_query_memcube(reloaded_cube, "重新加载的demo_cube_1") + + # 步骤7: 进阶查询(元数据操作) + print("\n7️⃣ 进阶查询(元数据操作)") + advanced_query_memcube(reloaded_cube, "重新加载的demo_cube_1") + + # 步骤8: 从内存中移除MemCube + print("\n8️⃣ 从内存中移除MemCube") + manager.unload_memcube("demo_cube_1") + + # 步骤9: 删除本地文件 + print("\n9️⃣ 删除本地文件") + manager.delete_memcube("demo_cube_1") + + +if __name__ == "__main__": + """ + 🎯 主函数 - 运行MemCube生命周期演示 + """ + try: + demonstrate_lifecycle() + print("\n🎉 MemCube生命周期演示完成!") + except Exception as e: + print(f"\n❌ 演示过程中出现错误: {e}") + import traceback + + traceback.print_exc() diff --git a/examples/cookbook/chapter2/API/2/create_person_memory_api.py b/examples/cookbook/chapter2/API/2/create_person_memory_api.py new file mode 100644 index 00000000..ecf0c17f --- /dev/null +++ b/examples/cookbook/chapter2/API/2/create_person_memory_api.py @@ -0,0 +1,57 @@ +# create_person_memory_api.py +# 🎯 创建人物记忆的示例 (API版) +import os + +from dotenv import load_dotenv + +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + + +def create_person_memory_api(): + """ + 🎯 创建人物记忆的示例 (API版) + """ + + print("🚀 开始创建人物记忆 (API版)...") + + # 加载环境变量 + load_dotenv() + + # 检查API配置 + openai_key = os.getenv("OPENAI_API_KEY") + if not openai_key: + raise ValueError("❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。") + + print("✅ 检测到OpenAI API模式") + + # 获取用户ID + user_id = os.getenv("MOS_USER_ID", "default_user") + + # 创建人物记忆的元数据 + metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="fact", + source="conversation", + confidence=90.0, + memory_type="LongTermMemory", + key="张三_信息", + entities=["张三", "工程师"], + tags=["人员", "技术"], + ) + + # 创建记忆项 + memory_item = TextualMemoryItem( + memory="张三是我们公司的资深工程师,擅长Python和机器学习", metadata=metadata + ) + + print(f"记忆内容: {memory_item.memory}") + print(f"记忆键: {memory_item.metadata.key}") + print(f"记忆类型: {memory_item.metadata.memory_type}") + print(f"标签: {memory_item.metadata.tags}") + print("🎯 配置模式: OPENAI API") + + return memory_item + + +if __name__ == "__main__": + create_person_memory_api() diff --git a/examples/cookbook/chapter2/API/2/create_project_memory_api.py b/examples/cookbook/chapter2/API/2/create_project_memory_api.py new file mode 100644 index 00000000..cb8e0bce --- /dev/null +++ b/examples/cookbook/chapter2/API/2/create_project_memory_api.py @@ -0,0 +1,57 @@ +# create_project_memory_api.py +# 🎯 创建项目记忆的示例 (API版) +import os + +from dotenv import load_dotenv + +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + + +def create_project_memory_api(): + """ + 🎯 创建项目记忆的示例 (API版) + """ + + print("🚀 开始创建项目记忆 (API版)...") + + # 加载环境变量 + load_dotenv() + + # 检查API配置 + openai_key = os.getenv("OPENAI_API_KEY") + if not openai_key: + raise ValueError("❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。") + + print("✅ 检测到OpenAI API模式") + + # 获取用户ID + user_id = os.getenv("MOS_USER_ID", "default_user") + + # 创建项目记忆的元数据 + project_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="fact", + source="file", + confidence=95.0, + memory_type="LongTermMemory", + key="AI项目_详情", + entities=["AI项目", "机器学习"], + tags=["项目", "AI", "重要"], + sources=["项目文档", "会议记录"], + ) + + # 创建记忆项 + project_memory = TextualMemoryItem( + memory="AI项目是一个智能客服系统,使用最新的NLP技术,预计6个月完成", + metadata=project_metadata, + ) + + print(f"项目记忆: {project_memory.memory}") + print(f"来源: {project_memory.metadata.sources}") + print("🎯 配置模式: OPENAI API") + + return project_memory + + +if __name__ == "__main__": + create_project_memory_api() diff --git a/examples/cookbook/chapter2/API/2/create_work_memory_api.py b/examples/cookbook/chapter2/API/2/create_work_memory_api.py new file mode 100644 index 00000000..b7480792 --- /dev/null +++ b/examples/cookbook/chapter2/API/2/create_work_memory_api.py @@ -0,0 +1,54 @@ +# create_work_memory_api.py +# 🎯 创建工作记忆的示例 (API版) +import os + +from dotenv import load_dotenv + +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + + +def create_work_memory_api(): + """ + 🎯 创建工作记忆的示例 (API版) + """ + + print("🚀 开始创建工作记忆 (API版)...") + + # 加载环境变量 + load_dotenv() + + # 检查API配置 + openai_key = os.getenv("OPENAI_API_KEY") + if not openai_key: + raise ValueError("❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。") + + print("✅ 检测到OpenAI API模式") + + # 获取用户ID + user_id = os.getenv("MOS_USER_ID", "default_user") + + # 创建工作记忆的元数据 + work_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="procedure", + source="conversation", + confidence=80.0, + memory_type="WorkingMemory", # 工作记忆 + key="今日任务", + tags=["任务", "今日"], + ) + + # 创建记忆项 + work_memory = TextualMemoryItem( + memory="今天需要完成代码审查、团队会议、以及准备明天的演示", metadata=work_metadata + ) + + print(f"工作记忆: {work_memory.memory}") + print(f"记忆类型: {work_memory.metadata.memory_type}") + print("🎯 配置模式: OPENAI API") + + return work_memory + + +if __name__ == "__main__": + create_work_memory_api() diff --git a/examples/cookbook/chapter2/API/4/memcube_with_structured_memories_api.py b/examples/cookbook/chapter2/API/4/memcube_with_structured_memories_api.py new file mode 100644 index 00000000..03bf7077 --- /dev/null +++ b/examples/cookbook/chapter2/API/4/memcube_with_structured_memories_api.py @@ -0,0 +1,183 @@ +# memcube_with_structured_memories_api.py +# 🎯 将结构化记忆添加到MemCube的完整示例 (API版) +import os + +from dotenv import load_dotenv + +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.mem_cube.general import GeneralMemCube +from memos.memories.textual.item import TreeNodeTextualMemoryMetadata + + +def create_memcube_config_api(): + """ + 🎯 创建MemCube配置 (API版) + """ + + print("🔧 创建MemCube配置 (API版)...") + + # 加载环境变量 + load_dotenv() + + # 检查API配置 + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + if not openai_key: + raise ValueError("❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。") + + print("✅ 检测到OpenAI API模式") + + # 获取配置 + user_id = os.getenv("MOS_USER_ID", "default_user") + top_k = int(os.getenv("MOS_TOP_K", "5")) + + # 获取模型配置 + chat_model = os.getenv("OPENAI_API_CHAT_MODEL", "gpt-4o-mini") + embed_model = os.getenv("OPENAI_API_EMBED_MODEL", "text-embedding-3-small") + + print(f"🤖 使用聊天模型: {chat_model}") + print(f"🔍 使用嵌入模型: {embed_model}") + + # OpenAI模式配置 + config = GeneralMemCubeConfig( + user_id=user_id, + cube_id=f"{user_id}_structured_memories_cube", + text_mem={ + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "openai", + "config": { + "model_name_or_path": chat_model, + "api_key": openai_key, + "api_base": openai_base, + "temperature": 0.1, + "max_tokens": 1024, + }, + }, + "embedder": { + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": embed_model, + "base_url": openai_base, + }, + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"{user_id}_structured_memories", + "vector_dimension": 1536, + "distance_metric": "cosine", + }, + }, + }, + }, + act_mem={"backend": "uninitialized"}, + para_mem={"backend": "uninitialized"}, + ) + + return config + + +def create_structured_memories_api(): + """ + 🎯 将结构化记忆添加到MemCube的完整示例 (API版) + """ + + print("🚀 开始创建结构化记忆MemCube (API版)...") + + # 创建MemCube配置 + config = create_memcube_config_api() + + # 创建MemCube + mem_cube = GeneralMemCube(config) + + print("✅ MemCube创建成功!") + print(f" 📊 用户ID: {mem_cube.config.user_id}") + print(f" 📊 MemCube ID: {mem_cube.config.cube_id}") + print(f" 📊 文本记忆后端: {mem_cube.config.text_mem.backend}") + print(f" 🔍 嵌入模型: {embed_model} (OpenAI)") + print(" 🎯 配置模式: OPENAI API") + + # 创建多个记忆项 + memories = [] + + # 记忆1:人物信息 + person_metadata = TreeNodeTextualMemoryMetadata( + user_id=mem_cube.config.user_id, + type="fact", + source="conversation", + confidence=90.0, + memory_type="LongTermMemory", + key="李四_信息", + entities=["李四", "设计师"], + tags=["人员", "设计"], + ) + + memories.append( + {"memory": "李四是我们的UI设计师,有5年经验,擅长用户界面设计", "metadata": person_metadata} + ) + + # 记忆2:项目信息 + project_metadata = TreeNodeTextualMemoryMetadata( + user_id=mem_cube.config.user_id, + type="fact", + source="file", + confidence=95.0, + memory_type="LongTermMemory", + key="移动应用项目", + entities=["移动应用", "开发"], + tags=["项目", "移动端", "重要"], + ) + + memories.append( + { + "memory": "移动应用项目正在进行中,预计3个月完成,团队有8个人", + "metadata": project_metadata, + } + ) + + # 记忆3:工作记忆 + work_metadata = TreeNodeTextualMemoryMetadata( + user_id=mem_cube.config.user_id, + type="procedure", + source="conversation", + confidence=85.0, + memory_type="WorkingMemory", + key="本周任务", + tags=["任务", "本周"], + ) + + memories.append( + {"memory": "本周需要完成需求分析、原型设计、以及技术选型", "metadata": work_metadata} + ) + + # 添加到MemCube + mem_cube.text_mem.add(memories) + + print("✅ 成功添加了3个记忆项到MemCube") + + # 查询记忆 + print("\n🔍 查询所有记忆:") + all_memories = mem_cube.text_mem.get_all() + for i, memory in enumerate(all_memories, 1): + print(f"{i}. {memory.memory}") + print(f" 键: {memory.metadata.key}") + print(f" 类型: {memory.metadata.memory_type}") + print(f" 标签: {memory.metadata.tags}") + print() + + # 搜索特定记忆 + print("🔍 搜索包含'李四'的记忆:") + search_results = mem_cube.text_mem.search("李四", top_k=2) + for result in search_results: + print(f"- {result.memory}") + + return mem_cube + + +if __name__ == "__main__": + create_structured_memories_api() diff --git a/examples/cookbook/chapter2/API/5/add_hierarchical_memories_api.py b/examples/cookbook/chapter2/API/5/add_hierarchical_memories_api.py new file mode 100644 index 00000000..93b7a76a --- /dev/null +++ b/examples/cookbook/chapter2/API/5/add_hierarchical_memories_api.py @@ -0,0 +1,182 @@ +# add_hierarchical_memories_api.py +# 🎯 添加层次化记忆的示例 (API版) +import os + +from dotenv import load_dotenv + +from memos.configs.memory import TreeTextMemoryConfig +from memos.memories.textual.item import TreeNodeTextualMemoryMetadata +from memos.memories.textual.tree import TreeTextMemory + + +def add_hierarchical_memories_api(): + """ + 🎯 添加层次化记忆的示例 (API版) + """ + + print("🚀 开始添加层次化记忆 (API版)...") + + # 加载环境变量 + load_dotenv() + + # 检查API配置 + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + if not openai_key: + raise ValueError("❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。") + + print("✅ 检测到OpenAI API模式") + + # 获取用户ID + user_id = os.getenv("MOS_USER_ID", "default_user") + + # 创建TreeTextMemory配置 + tree_config = TreeTextMemoryConfig( + extractor_llm={ + "backend": "openai", + "config": { + "model_name_or_path": "gpt-3.5-turbo", + "api_key": openai_key, + "api_base": openai_base, + "temperature": 0.1, + "max_tokens": 1024, + }, + }, + dispatcher_llm={ + "backend": "openai", + "config": { + "model_name_or_path": "gpt-3.5-turbo", + "api_key": openai_key, + "api_base": openai_base, + "temperature": 0.1, + "max_tokens": 1024, + }, + }, + graph_db={ + "backend": "neo4j", + "config": { + "uri": "bolt://localhost:7687", + "user": "neo4j", + "password": "password", + "db_name": f"{user_id}_hierarchical_memory", + "auto_create": True, + "embedding_dimension": 1536, + }, + }, + embedder={ + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": "text-embedding-ada-002", + "base_url": openai_base, + }, + }, + ) + + # 创建TreeTextMemory实例 + tree_memory = TreeTextMemory(tree_config) + + # 清空现有记忆 + tree_memory.delete_all() + + # 创建层次化记忆结构 + memories = [] + + # 根节点:项目概述 + root_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="topic", + source="file", + confidence=95.0, + memory_type="LongTermMemory", + key="AI项目_根节点", + entities=["AI项目", "智能客服"], + tags=["项目", "根节点", "重要"], + ) + + memories.append( + {"memory": "AI项目是一个智能客服系统,目标是提升客户服务效率", "metadata": root_metadata} + ) + + # 子节点1:技术架构 + tech_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="fact", + source="file", + confidence=90.0, + memory_type="LongTermMemory", + key="技术架构", + entities=["NLP", "机器学习", "API"], + tags=["技术", "架构", "重要"], + ) + + memories.append( + { + "memory": "项目使用最新的NLP技术和机器学习算法,通过API接口提供服务", + "metadata": tech_metadata, + } + ) + + # 子节点2:团队信息 + team_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="fact", + source="conversation", + confidence=85.0, + memory_type="LongTermMemory", + key="团队信息", + entities=["开发团队", "8人"], + tags=["团队", "人员"], + ) + + memories.append( + {"memory": "开发团队有8个人,包括前端、后端、AI工程师和产品经理", "metadata": team_metadata} + ) + + # 子节点3:时间计划 + timeline_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="procedure", + source="file", + confidence=80.0, + memory_type="WorkingMemory", + key="时间计划", + entities=["6个月", "里程碑"], + tags=["计划", "时间", "临时"], + ) + + memories.append( + { + "memory": "项目预计6个月完成,分为需求分析、设计、开发、测试四个阶段", + "metadata": timeline_metadata, + } + ) + + # 添加记忆到图数据库 + tree_memory.add(memories) + + print("✅ 成功添加了4个层次化记忆节点") + + # 搜索记忆 + print("\n🔍 搜索包含'技术'的记忆:") + search_results = tree_memory.search("技术", top_k=3) + for i, result in enumerate(search_results, 1): + print(f"{i}. {result.memory}") + print(f" 键: {result.metadata.key}") + print(f" 类型: {result.metadata.memory_type}") + print(f" 标签: {result.metadata.tags}") + print() + + # 获取工作记忆 + print("🔍 获取工作记忆:") + working_memories = tree_memory.get_working_memory() + for memory in working_memories: + print(f"- {memory.memory}") + + return tree_memory + + +if __name__ == "__main__": + add_hierarchical_memories_api() diff --git a/examples/cookbook/chapter2/API/5/create_treetext_memory_api.py b/examples/cookbook/chapter2/API/5/create_treetext_memory_api.py new file mode 100644 index 00000000..c303dc5b --- /dev/null +++ b/examples/cookbook/chapter2/API/5/create_treetext_memory_api.py @@ -0,0 +1,92 @@ +# create_treetext_memory_api.py +# 🎯 创建TreeTextMemory的示例 (API版) +import os + +from dotenv import load_dotenv + +from memos.configs.memory import TreeTextMemoryConfig +from memos.memories.textual.tree import TreeTextMemory + + +def create_treetext_memory_api(): + """ + 🎯 创建TreeTextMemory的示例 (API版) + """ + + print("🚀 开始创建TreeTextMemory (API版)...") + + # 加载环境变量 + load_dotenv() + + # 检查API配置 + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + if not openai_key: + raise ValueError("❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。") + + print("✅ 检测到OpenAI API模式") + + # 获取用户ID + user_id = os.getenv("MOS_USER_ID", "default_user") + + # 创建TreeTextMemory配置 + tree_config = TreeTextMemoryConfig( + extractor_llm={ + "backend": "openai", + "config": { + "model_name_or_path": "gpt-3.5-turbo", + "api_key": openai_key, + "api_base": openai_base, + "temperature": 0.1, + "max_tokens": 1024, + }, + }, + dispatcher_llm={ + "backend": "openai", + "config": { + "model_name_or_path": "gpt-3.5-turbo", + "api_key": openai_key, + "api_base": openai_base, + "temperature": 0.1, + "max_tokens": 1024, + }, + }, + graph_db={ + "backend": "neo4j", + "config": { + "uri": "bolt://localhost:7687", + "user": "neo4j", + "password": "password", + "db_name": f"{user_id}_tree_memory", + "auto_create": True, + "embedding_dimension": 1536, + }, + }, + embedder={ + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": "text-embedding-ada-002", + "base_url": openai_base, + }, + }, + ) + + # 创建TreeTextMemory实例 + tree_memory = TreeTextMemory(tree_config) + + print("✅ TreeTextMemory创建成功!") + print(f" 📊 用户ID: {tree_memory.config.user_id}") + print(f" 📊 记忆ID: {tree_memory.config.memory_id}") + print(" 🔍 嵌入模型: text-embedding-ada-002 (OpenAI)") + print(" 🤖 聊天模型: gpt-3.5-turbo (OpenAI)") + print(" 🗄️ 图数据库: Neo4j") + print(" 🎯 配置模式: OPENAI API") + + return tree_memory + + +if __name__ == "__main__": + create_treetext_memory_api() diff --git a/examples/cookbook/chapter2/API/5/graph_query_and_reasoning_api.py b/examples/cookbook/chapter2/API/5/graph_query_and_reasoning_api.py new file mode 100644 index 00000000..9a5be894 --- /dev/null +++ b/examples/cookbook/chapter2/API/5/graph_query_and_reasoning_api.py @@ -0,0 +1,122 @@ +# graph_query_and_reasoning_api.py +# 🎯 图数据库查询和推理示例 (API版) +import os + +from dotenv import load_dotenv + +from memos.configs.memory import TreeTextMemoryConfig +from memos.memories.textual.tree import TreeTextMemory + + +def graph_query_and_reasoning_api(): + """ + 🎯 图数据库查询和推理示例 (API版) + """ + + print("🚀 开始图数据库查询和推理 (API版)...") + + # 加载环境变量 + load_dotenv() + + # 检查API配置 + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + if not openai_key: + raise ValueError("❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。") + + print("✅ 检测到OpenAI API模式") + + # 获取用户ID + user_id = os.getenv("MOS_USER_ID", "default_user") + + # 创建TreeTextMemory配置 + tree_config = TreeTextMemoryConfig( + extractor_llm={ + "backend": "openai", + "config": { + "model_name_or_path": "gpt-3.5-turbo", + "api_key": openai_key, + "api_base": openai_base, + "temperature": 0.1, + "max_tokens": 1024, + }, + }, + dispatcher_llm={ + "backend": "openai", + "config": { + "model_name_or_path": "gpt-3.5-turbo", + "api_key": openai_key, + "api_base": openai_base, + "temperature": 0.1, + "max_tokens": 1024, + }, + }, + graph_db={ + "backend": "neo4j", + "config": { + "uri": "bolt://localhost:7687", + "user": "neo4j", + "password": "password", + "db_name": f"{user_id}_reasoning_memory", + "auto_create": True, + "embedding_dimension": 1536, + }, + }, + embedder={ + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": "text-embedding-ada-002", + "base_url": openai_base, + }, + }, + ) + + # 创建TreeTextMemory实例 + tree_memory = TreeTextMemory(tree_config) + + print("🔍 执行图数据库查询和推理...") + + # 1. 向量相似度搜索 + print("\n1️⃣ 向量相似度搜索:") + vector_results = tree_memory.search("AI项目", top_k=3) + for i, result in enumerate(vector_results, 1): + print(f" {i}. {result.memory}") + + # 2. 获取所有记忆 + print("\n2️⃣ 获取所有记忆:") + all_memories = tree_memory.get_all() + print(f" 总记忆数量: {len(all_memories.get('nodes', []))}") + + # 3. 替换工作记忆 + print("\n3️⃣ 替换工作记忆:") + new_working_memories = [ + { + "memory": "当前正在进行需求分析阶段,需要收集用户反馈", + "metadata": { + "memory_type": "WorkingMemory", + "key": "当前状态", + "tags": ["状态", "当前"], + }, + } + ] + tree_memory.replace_working_memory(new_working_memories) + print(" ✅ 工作记忆已更新") + + # 4. 备份记忆 + print("\n4️⃣ 备份记忆到文件:") + backup_dir = "tmp/tree_memory_backup" + tree_memory.dump(backup_dir) + print(f" ✅ 记忆已备份到: {backup_dir}") + + print("\n🎯 配置模式: OPENAI API") + print("🤖 聊天模型: gpt-3.5-turbo (OpenAI)") + print("🔍 嵌入模型: text-embedding-ada-002 (OpenAI)") + + return tree_memory + + +if __name__ == "__main__": + graph_query_and_reasoning_api() diff --git a/examples/cookbook/chapter2/Ollama/2/create_person_memory_ollama.py b/examples/cookbook/chapter2/Ollama/2/create_person_memory_ollama.py new file mode 100644 index 00000000..4276fd8d --- /dev/null +++ b/examples/cookbook/chapter2/Ollama/2/create_person_memory_ollama.py @@ -0,0 +1,64 @@ +# create_person_memory_ollama.py +# 🎯 创建人物记忆的示例 (Ollama版) +import os + +from dotenv import load_dotenv + +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + + +def create_person_memory_ollama(): + """ + 🎯 创建人物记忆的示例 (Ollama版) + """ + + print("🚀 开始创建人物记忆 (Ollama版)...") + + # 加载环境变量 + load_dotenv() + + # 检查Ollama配置 + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError( + "❌ 未配置Ollama环境变量。请在.env文件中配置OLLAMA_BASE_URL、OLLAMA_CHAT_MODEL、OLLAMA_EMBED_MODEL。" + ) + + print("✅ 检测到Ollama本地模型模式") + + # 获取用户ID + user_id = os.getenv("MOS_USER_ID", "default_user") + + # 创建人物记忆的元数据 + metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="fact", + source="conversation", + confidence=90.0, + memory_type="LongTermMemory", + key="张三_信息", + entities=["张三", "工程师"], + tags=["人员", "技术"], + ) + + # 创建记忆项 + memory_item = TextualMemoryItem( + memory="张三是我们公司的资深工程师,擅长Python和机器学习", metadata=metadata + ) + + print(f"记忆内容: {memory_item.memory}") + print(f"记忆键: {memory_item.metadata.key}") + print(f"记忆类型: {memory_item.metadata.memory_type}") + print(f"标签: {memory_item.metadata.tags}") + print("🎯 配置模式: OLLAMA") + print(f"🤖 聊天模型: {ollama_chat_model}") + print(f"🔍 嵌入模型: {ollama_embed_model}") + + return memory_item + + +if __name__ == "__main__": + create_person_memory_ollama() diff --git a/examples/cookbook/chapter2/Ollama/2/create_project_memory_ollama.py b/examples/cookbook/chapter2/Ollama/2/create_project_memory_ollama.py new file mode 100644 index 00000000..0b6a6843 --- /dev/null +++ b/examples/cookbook/chapter2/Ollama/2/create_project_memory_ollama.py @@ -0,0 +1,64 @@ +# create_project_memory_ollama.py +# 🎯 创建项目记忆的示例 (Ollama版) +import os + +from dotenv import load_dotenv + +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + + +def create_project_memory_ollama(): + """ + 🎯 创建项目记忆的示例 (Ollama版) + """ + + print("🚀 开始创建项目记忆 (Ollama版)...") + + # 加载环境变量 + load_dotenv() + + # 检查Ollama配置 + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError( + "❌ 未配置Ollama环境变量。请在.env文件中配置OLLAMA_BASE_URL、OLLAMA_CHAT_MODEL、OLLAMA_EMBED_MODEL。" + ) + + print("✅ 检测到Ollama本地模型模式") + + # 获取用户ID + user_id = os.getenv("MOS_USER_ID", "default_user") + + # 创建项目记忆的元数据 + project_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="fact", + source="file", + confidence=95.0, + memory_type="LongTermMemory", + key="AI项目_详情", + entities=["AI项目", "机器学习"], + tags=["项目", "AI", "重要"], + sources=["项目文档", "会议记录"], + ) + + # 创建记忆项 + project_memory = TextualMemoryItem( + memory="AI项目是一个智能客服系统,使用最新的NLP技术,预计6个月完成", + metadata=project_metadata, + ) + + print(f"项目记忆: {project_memory.memory}") + print(f"来源: {project_memory.metadata.sources}") + print("🎯 配置模式: OLLAMA") + print(f"🤖 聊天模型: {ollama_chat_model}") + print(f"🔍 嵌入模型: {ollama_embed_model}") + + return project_memory + + +if __name__ == "__main__": + create_project_memory_ollama() diff --git a/examples/cookbook/chapter2/Ollama/2/create_work_memory_ollama.py b/examples/cookbook/chapter2/Ollama/2/create_work_memory_ollama.py new file mode 100644 index 00000000..e78c2dc2 --- /dev/null +++ b/examples/cookbook/chapter2/Ollama/2/create_work_memory_ollama.py @@ -0,0 +1,61 @@ +# create_work_memory_ollama.py +# 🎯 创建工作记忆的示例 (Ollama版) +import os + +from dotenv import load_dotenv + +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata + + +def create_work_memory_ollama(): + """ + 🎯 创建工作记忆的示例 (Ollama版) + """ + + print("🚀 开始创建工作记忆 (Ollama版)...") + + # 加载环境变量 + load_dotenv() + + # 检查Ollama配置 + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError( + "❌ 未配置Ollama环境变量。请在.env文件中配置OLLAMA_BASE_URL、OLLAMA_CHAT_MODEL、OLLAMA_EMBED_MODEL。" + ) + + print("✅ 检测到Ollama本地模型模式") + + # 获取用户ID + user_id = os.getenv("MOS_USER_ID", "default_user") + + # 创建工作记忆的元数据 + work_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="procedure", + source="conversation", + confidence=80.0, + memory_type="WorkingMemory", # 工作记忆 + key="今日任务", + tags=["任务", "今日"], + ) + + # 创建记忆项 + work_memory = TextualMemoryItem( + memory="今天需要完成代码审查、团队会议、以及准备明天的演示", metadata=work_metadata + ) + + print(f"工作记忆: {work_memory.memory}") + print(f"记忆类型: {work_memory.metadata.memory_type}") + print("🎯 配置模式: OLLAMA") + print(f"🤖 聊天模型: {ollama_chat_model}") + print(f"🔍 嵌入模型: {ollama_embed_model}") + + return work_memory + + +if __name__ == "__main__": + create_work_memory_ollama() diff --git a/examples/cookbook/chapter2/Ollama/4/memcube_with_structured_memories_ollama.py b/examples/cookbook/chapter2/Ollama/4/memcube_with_structured_memories_ollama.py new file mode 100644 index 00000000..f3d3bf50 --- /dev/null +++ b/examples/cookbook/chapter2/Ollama/4/memcube_with_structured_memories_ollama.py @@ -0,0 +1,183 @@ +# memcube_with_structured_memories_ollama.py +# 🎯 将结构化记忆添加到MemCube的完整示例 (Ollama版) +import os + +from dotenv import load_dotenv + +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.mem_cube.general import GeneralMemCube +from memos.memories.textual.item import TreeNodeTextualMemoryMetadata + + +def create_memcube_config_ollama(): + """ + 🎯 创建MemCube配置 (Ollama版) + """ + + print("🔧 创建MemCube配置 (Ollama版)...") + + # 加载环境变量 + load_dotenv() + + # 检查Ollama配置 + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError( + "❌ 未配置Ollama环境变量。请在.env文件中配置OLLAMA_BASE_URL、OLLAMA_CHAT_MODEL、OLLAMA_EMBED_MODEL。" + ) + + print("✅ 检测到Ollama本地模型模式") + + # 获取配置 + user_id = os.getenv("MOS_USER_ID", "default_user") + top_k = int(os.getenv("MOS_TOP_K", "5")) + + # Ollama模式配置 + cube_config = { + "user_id": user_id, + "cube_id": f"{user_id}_structured_memories_cube", + "text_mem": { + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_chat_model, + "api_base": ollama_base_url, + }, + }, + "embedder": { + "backend": "ollama", + "config": { + "model_name_or_path": ollama_embed_model, + "api_base": ollama_base_url, + }, + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"{user_id}_structured_memories", + "vector_dimension": 768, + "distance_metric": "cosine", + }, + }, + }, + }, + "act_mem": {"backend": "uninitialized"}, + "para_mem": {"backend": "uninitialized"}, + } + + # 创建MemCube实例 + config_obj = GeneralMemCubeConfig.model_validate(cube_config) + + return config_obj + + +def create_structured_memories_ollama(): + """ + 🎯 将结构化记忆添加到MemCube的完整示例 (Ollama版) + """ + + print("🚀 开始创建结构化记忆MemCube (Ollama版)...") + + # 创建MemCube配置 + config = create_memcube_config_ollama() + + # 创建MemCube + mem_cube = GeneralMemCube(config) + + print("✅ MemCube创建成功!") + print(f" 📊 用户ID: {mem_cube.config.user_id}") + print(f" 📊 MemCube ID: {mem_cube.config.cube_id}") + print(f" 📊 文本记忆后端: {mem_cube.config.text_mem.backend}") + + # 获取Ollama配置用于显示 + load_dotenv() + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + print(f" 🔍 嵌入模型: {ollama_embed_model} (Ollama)") + print(f" 🤖 聊天模型: {ollama_chat_model} (Ollama)") + print(" 🎯 配置模式: OLLAMA") + + # 创建多个记忆项 + memories = [] + + # 记忆1:人物信息 + person_metadata = TreeNodeTextualMemoryMetadata( + user_id=mem_cube.config.user_id, + type="fact", + source="conversation", + confidence=90.0, + memory_type="LongTermMemory", + key="李四_信息", + entities=["李四", "设计师"], + tags=["人员", "设计"], + ) + + memories.append( + {"memory": "李四是我们的UI设计师,有5年经验,擅长用户界面设计", "metadata": person_metadata} + ) + + # 记忆2:项目信息 + project_metadata = TreeNodeTextualMemoryMetadata( + user_id=mem_cube.config.user_id, + type="fact", + source="file", + confidence=95.0, + memory_type="LongTermMemory", + key="移动应用项目", + entities=["移动应用", "开发"], + tags=["项目", "移动端", "重要"], + ) + + memories.append( + { + "memory": "移动应用项目正在进行中,预计3个月完成,团队有8个人", + "metadata": project_metadata, + } + ) + + # 记忆3:工作记忆 + work_metadata = TreeNodeTextualMemoryMetadata( + user_id=mem_cube.config.user_id, + type="procedure", + source="conversation", + confidence=85.0, + memory_type="WorkingMemory", + key="本周任务", + tags=["任务", "本周"], + ) + + memories.append( + {"memory": "本周需要完成需求分析、原型设计、以及技术选型", "metadata": work_metadata} + ) + + # 添加到MemCube + mem_cube.text_mem.add(memories) + + print("✅ 成功添加了3个记忆项到MemCube") + + # 查询记忆 + print("\n🔍 查询所有记忆:") + all_memories = mem_cube.text_mem.get_all() + for i, memory in enumerate(all_memories, 1): + print(f"{i}. {memory.memory}") + print(f" 键: {memory.metadata.key}") + print(f" 类型: {memory.metadata.memory_type}") + print(f" 标签: {memory.metadata.tags}") + print() + + # 搜索特定记忆 + print("🔍 搜索包含'李四'的记忆:") + search_results = mem_cube.text_mem.search("李四", top_k=2) + for result in search_results: + print(f"- {result.memory}") + + return mem_cube + + +if __name__ == "__main__": + create_structured_memories_ollama() diff --git a/examples/cookbook/chapter2/Ollama/5/add_hierarchical_memories_ollama.py b/examples/cookbook/chapter2/Ollama/5/add_hierarchical_memories_ollama.py new file mode 100644 index 00000000..e0bfbdaf --- /dev/null +++ b/examples/cookbook/chapter2/Ollama/5/add_hierarchical_memories_ollama.py @@ -0,0 +1,168 @@ +# add_hierarchical_memories_ollama.py +# 🎯 添加层次化记忆的示例 (Ollama版) +import os + +from dotenv import load_dotenv + +from memos.configs.memory import TreeTextMemoryConfig +from memos.memories.textual.item import TreeNodeTextualMemoryMetadata +from memos.memories.textual.tree import TreeTextMemory + + +def add_hierarchical_memories_ollama(): + """ + 🎯 添加层次化记忆的示例 (Ollama版) + """ + + print("🚀 开始添加层次化记忆 (Ollama版)...") + + # 加载环境变量 + load_dotenv() + + # 检查Ollama配置 + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError( + "❌ 未配置Ollama环境变量。请在.env文件中配置OLLAMA_BASE_URL、OLLAMA_CHAT_MODEL、OLLAMA_EMBED_MODEL。" + ) + + print("✅ 检测到Ollama本地模型模式") + + # 获取用户ID + user_id = os.getenv("MOS_USER_ID", "default_user") + + # 创建TreeTextMemory配置 + tree_config = TreeTextMemoryConfig( + extractor_llm={ + "backend": "ollama", + "config": {"model_name_or_path": ollama_chat_model, "api_base": ollama_base_url}, + }, + dispatcher_llm={ + "backend": "ollama", + "config": {"model_name_or_path": ollama_chat_model, "api_base": ollama_base_url}, + }, + graph_db={ + "backend": "neo4j", + "config": { + "uri": "bolt://localhost:7687", + "user": "neo4j", + "password": "password", + "db_name": f"{user_id}_hierarchical_memory", + "auto_create": True, + "embedding_dimension": 768, + }, + }, + embedder={ + "backend": "ollama", + "config": {"model_name_or_path": ollama_embed_model, "api_base": ollama_base_url}, + }, + ) + + # 创建TreeTextMemory实例 + tree_memory = TreeTextMemory(tree_config) + + # 清空现有记忆 + tree_memory.delete_all() + + # 创建层次化记忆结构 + memories = [] + + # 根节点:项目概述 + root_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="topic", + source="file", + confidence=95.0, + memory_type="LongTermMemory", + key="AI项目_根节点", + entities=["AI项目", "智能客服"], + tags=["项目", "根节点", "重要"], + ) + + memories.append( + {"memory": "AI项目是一个智能客服系统,目标是提升客户服务效率", "metadata": root_metadata} + ) + + # 子节点1:技术架构 + tech_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="fact", + source="file", + confidence=90.0, + memory_type="LongTermMemory", + key="技术架构", + entities=["NLP", "机器学习", "API"], + tags=["技术", "架构", "重要"], + ) + + memories.append( + { + "memory": "项目使用最新的NLP技术和机器学习算法,通过API接口提供服务", + "metadata": tech_metadata, + } + ) + + # 子节点2:团队信息 + team_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="fact", + source="conversation", + confidence=85.0, + memory_type="LongTermMemory", + key="团队信息", + entities=["开发团队", "8人"], + tags=["团队", "人员"], + ) + + memories.append( + {"memory": "开发团队有8个人,包括前端、后端、AI工程师和产品经理", "metadata": team_metadata} + ) + + # 子节点3:时间计划 + timeline_metadata = TreeNodeTextualMemoryMetadata( + user_id=user_id, + type="procedure", + source="file", + confidence=80.0, + memory_type="WorkingMemory", + key="时间计划", + entities=["6个月", "里程碑"], + tags=["计划", "时间", "临时"], + ) + + memories.append( + { + "memory": "项目预计6个月完成,分为需求分析、设计、开发、测试四个阶段", + "metadata": timeline_metadata, + } + ) + + # 添加记忆到图数据库 + tree_memory.add(memories) + + print("✅ 成功添加了4个层次化记忆节点") + + # 搜索记忆 + print("\n🔍 搜索包含'技术'的记忆:") + search_results = tree_memory.search("技术", top_k=3) + for i, result in enumerate(search_results, 1): + print(f"{i}. {result.memory}") + print(f" 键: {result.metadata.key}") + print(f" 类型: {result.metadata.memory_type}") + print(f" 标签: {result.metadata.tags}") + print() + + # 获取工作记忆 + print("🔍 获取工作记忆:") + working_memories = tree_memory.get_working_memory() + for memory in working_memories: + print(f"- {memory.memory}") + + return tree_memory + + +if __name__ == "__main__": + add_hierarchical_memories_ollama() diff --git a/examples/cookbook/chapter2/Ollama/5/create_treetext_memory_ollama.py b/examples/cookbook/chapter2/Ollama/5/create_treetext_memory_ollama.py new file mode 100644 index 00000000..22a5bed6 --- /dev/null +++ b/examples/cookbook/chapter2/Ollama/5/create_treetext_memory_ollama.py @@ -0,0 +1,78 @@ +# create_treetext_memory_ollama.py +# 🎯 创建TreeTextMemory的示例 (Ollama版) +import os + +from dotenv import load_dotenv + +from memos.configs.memory import TreeTextMemoryConfig +from memos.memories.textual.tree import TreeTextMemory + + +def create_treetext_memory_ollama(): + """ + 🎯 创建TreeTextMemory的示例 (Ollama版) + """ + + print("🚀 开始创建TreeTextMemory (Ollama版)...") + + # 加载环境变量 + load_dotenv() + + # 检查Ollama配置 + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError( + "❌ 未配置Ollama环境变量。请在.env文件中配置OLLAMA_BASE_URL、OLLAMA_CHAT_MODEL、OLLAMA_EMBED_MODEL。" + ) + + print("✅ 检测到Ollama本地模型模式") + + # 获取用户ID + user_id = os.getenv("MOS_USER_ID", "default_user") + + # 创建TreeTextMemory配置 + tree_config = TreeTextMemoryConfig( + extractor_llm={ + "backend": "ollama", + "config": {"model_name_or_path": ollama_chat_model, "api_base": ollama_base_url}, + }, + dispatcher_llm={ + "backend": "ollama", + "config": {"model_name_or_path": ollama_chat_model, "api_base": ollama_base_url}, + }, + graph_db={ + "backend": "neo4j", + "config": { + "uri": "bolt://localhost:7687", + "user": "neo4j", + "password": "password", + "db_name": f"{user_id}_tree_memory", + "auto_create": True, + "embedding_dimension": 768, + }, + }, + embedder={ + "backend": "ollama", + "config": {"model_name_or_path": ollama_embed_model, "api_base": ollama_base_url}, + }, + ) + + # 创建TreeTextMemory实例 + tree_memory = TreeTextMemory(tree_config) + + print("✅ TreeTextMemory创建成功!") + print(f" 📊 用户ID: {tree_memory.config.user_id}") + print(f" 📊 记忆ID: {tree_memory.config.memory_id}") + print(f" 🔍 嵌入模型: {ollama_embed_model} (Ollama)") + print(f" 🤖 聊天模型: {ollama_chat_model} (Ollama)") + print(" 🗄️ 图数据库: Neo4j") + print(" 🎯 配置模式: OLLAMA") + + return tree_memory + + +if __name__ == "__main__": + create_treetext_memory_ollama() diff --git a/examples/cookbook/chapter2/Ollama/5/graph_query_and_reasoning_ollama.py b/examples/cookbook/chapter2/Ollama/5/graph_query_and_reasoning_ollama.py new file mode 100644 index 00000000..2de3f957 --- /dev/null +++ b/examples/cookbook/chapter2/Ollama/5/graph_query_and_reasoning_ollama.py @@ -0,0 +1,108 @@ +# graph_query_and_reasoning_ollama.py +# 🎯 图数据库查询和推理示例 (Ollama版) +import os + +from dotenv import load_dotenv + +from memos.configs.memory import TreeTextMemoryConfig +from memos.memories.textual.tree import TreeTextMemory + + +def graph_query_and_reasoning_ollama(): + """ + 🎯 图数据库查询和推理示例 (Ollama版) + """ + + print("🚀 开始图数据库查询和推理 (Ollama版)...") + + # 加载环境变量 + load_dotenv() + + # 检查Ollama配置 + ollama_base_url = os.getenv("OLLAMA_BASE_URL") + ollama_chat_model = os.getenv("OLLAMA_CHAT_MODEL") + ollama_embed_model = os.getenv("OLLAMA_EMBED_MODEL") + + if not ollama_base_url or not ollama_chat_model or not ollama_embed_model: + raise ValueError( + "❌ 未配置Ollama环境变量。请在.env文件中配置OLLAMA_BASE_URL、OLLAMA_CHAT_MODEL、OLLAMA_EMBED_MODEL。" + ) + + print("✅ 检测到Ollama本地模型模式") + + # 获取用户ID + user_id = os.getenv("MOS_USER_ID", "default_user") + + # 创建TreeTextMemory配置 + tree_config = TreeTextMemoryConfig( + extractor_llm={ + "backend": "ollama", + "config": {"model_name_or_path": ollama_chat_model, "api_base": ollama_base_url}, + }, + dispatcher_llm={ + "backend": "ollama", + "config": {"model_name_or_path": ollama_chat_model, "api_base": ollama_base_url}, + }, + graph_db={ + "backend": "neo4j", + "config": { + "uri": "bolt://localhost:7687", + "user": "neo4j", + "password": "password", + "db_name": f"{user_id}_reasoning_memory", + "auto_create": True, + "embedding_dimension": 768, + }, + }, + embedder={ + "backend": "ollama", + "config": {"model_name_or_path": ollama_embed_model, "api_base": ollama_base_url}, + }, + ) + + # 创建TreeTextMemory实例 + tree_memory = TreeTextMemory(tree_config) + + print("🔍 执行图数据库查询和推理...") + + # 1. 向量相似度搜索 + print("\n1️⃣ 向量相似度搜索:") + vector_results = tree_memory.search("AI项目", top_k=3) + for i, result in enumerate(vector_results, 1): + print(f" {i}. {result.memory}") + + # 2. 获取所有记忆 + print("\n2️⃣ 获取所有记忆:") + all_memories = tree_memory.get_all() + print(f" 总记忆数量: {len(all_memories.get('nodes', []))}") + + # 3. 替换工作记忆 + print("\n3️⃣ 替换工作记忆:") + new_working_memories = [ + { + "memory": "当前正在进行需求分析阶段,需要收集用户反馈", + "metadata": { + "memory_type": "WorkingMemory", + "key": "当前状态", + "tags": ["状态", "当前"], + }, + } + ] + tree_memory.replace_working_memory(new_working_memories) + print(" ✅ 工作记忆已更新") + + # 4. 备份记忆 + print("\n4️⃣ 备份记忆到文件:") + backup_dir = "tmp/tree_memory_backup" + tree_memory.dump(backup_dir) + print(f" ✅ 记忆已备份到: {backup_dir}") + + print("\n🎯 配置模式: OLLAMA") + print(f"🤖 聊天模型: {ollama_chat_model}") + print(f"🔍 嵌入模型: {ollama_embed_model}") + + return tree_memory + + +if __name__ == "__main__": + graph_query_and_reasoning_ollama() diff --git a/examples/cookbook/chapter3/Connect.py b/examples/cookbook/chapter3/Connect.py new file mode 100644 index 00000000..5c73c44a --- /dev/null +++ b/examples/cookbook/chapter3/Connect.py @@ -0,0 +1,408 @@ +import memos +from memos.configs.embedder import EmbedderConfigFactory +from memos.configs.memory import TreeTextMemoryConfig +from memos.configs.mem_reader import SimpleStructMemReaderConfig +from memos.embedders.factory import EmbedderFactory +from memos.mem_reader.simple_struct import SimpleStructMemReader +from memos.memories.textual.tree import TreeTextMemory +import ast +from dotenv import load_dotenv +from memos.mem_cube.general import GeneralMemCube +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata +import memos.memories.textual.tree_text_memory.retrieve.searcher as searcher +import requests +import json +import os +import pickle +import time +from datetime import datetime +from concurrent.futures import ThreadPoolExecutor, as_completed +from requests.adapters import HTTPAdapter +from urllib3.util.retry import Retry +import re +from typing import Dict, List, Optional, Any, Set, Tuple +from dataclasses import dataclass, field +from enum import Enum +import numpy as np +from memos.configs.mem_os import MOSConfig +import inspect +from memos.configs.embedder import EmbedderConfigFactory +import uuid +from memos.mem_os.main import MOS +from memos.llms.openai import OpenAILLM +from memos.configs.llm import OpenAILLMConfig +from pathlib import Path +from memos.memories.textual.tree_text_memory.organize import manager + +def safe_del(self): + try: + if hasattr(self, 'close') and callable(self.close): + self.close() + except Exception as e: + print(f"[MonkeyPatch] __del__ failed safely: {e}") + +# Monkey patch +manager.MemoryManager.__del__ = safe_del + +def get_memcube_config(): + print("🔧 创建MemCube配置 (API版)...") + + # 加载环境变量 + load_dotenv() + + # 检查API配置 + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + + if not openai_key: + raise ValueError("❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。") + + print("✅ 检测到OpenAI API模式") + + # 获取配置 + user_id = os.getenv("MOS_USER_ID", "default_user") + top_k = int(os.getenv("MOS_TOP_K", "5")) + + # OpenAI模式配置 + config_memcube = GeneralMemCubeConfig( + user_id=user_id, + cube_id=f"{user_id}_structured_memories_cube", + text_mem={ + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o", + "api_key": openai_key, + "api_base": openai_base, + "temperature": 0.8, + "max_tokens": 8192, + } + }, + "embedder": { + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": openai_key, + "model_name_or_path": "text-embedding-ada-002", + "base_url": openai_base, + } + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"{user_id}_structured_memories", + "vector_dimension": 1536, + "distance_metric": "cosine" + } + } + } + }, + act_mem={"backend": "uninitialized"}, + para_mem={"backend": "uninitialized"} + ) + return config_memcube + +def get_following_memory_texts(memory: TreeTextMemory, start_id: str, k: int = 30) -> list[str]: + """ + Return the metadata["memory"] strings of the next k nodes following a given node via FOLLOWS edges. + + Args: + memory (TreeTextMemory): Memory system instance. + start_id (str): The starting node ID. + k (int): Number of following nodes to retrieve. + + Returns: + list[str]: List of memory texts from the following nodes. + """ + graph = memory.graph_store.export_graph() + nodes = {node["id"]: node for node in graph["nodes"]} + follows_map = { + edge["source"]: edge["target"] + for edge in graph["edges"] + if edge["type"] == "FOLLOWS" + } + + result = [] + current_id = start_id + for _ in range(k): + next_id = follows_map.get(current_id) + if not next_id or next_id not in nodes: + break + + metadata = nodes[next_id].get("metadata", {}) + memory_text = metadata.get("memory") or nodes[next_id].get("memory") # fallback + if memory_text: + result.append(memory_text) + current_id = next_id + + return result + +def key_event_extraction(query,llm): + name_prompt = [ + { + "role": "system", + "content": "你是一个精准事件抽取器。用户会描述一个或多个小说中发生过的事件,你需要从中提取出用户想要改变或讨论的关键事件,并用一句话简洁描述每个事件。仅概括事件,无需满足用户需求\n" + "要求:\n" + "1. 每个事件必须是真实发生在小说原文中的事件,而非假设。\n" + "2. 每个事件必须为一个字符串,构成 Python list 的元素。\n" + "3. 最终输出必须是合法的 Python list,例如:\n" + '''["乔峰误杀阿朱", "段誉跳崖逃避婚姻"]\n''' + "你只输出这个 list,不要添加任何解释或额外的内容。" + }, + { + "role": "user", + "content": query + } + ] + key_event = llm.generate(name_prompt) + + return ast.literal_eval(key_event) + +def refine_command(query: str,llm) -> str: + name_prompt = [ + { + "role": "system", + "content": ( + "你是一个任务指令优化器,专用于小说类用户任务。\n" + "用户会给出一个随意、模糊、简短或不完整的请求,\n" + "你需要将它补全为一条完整、清晰、精炼的自然语言指令。\n\n" + "指令内容可以包括但不限于:\n" + "1. 小说剧情续写(如模仿金庸风格续写一段中段剧情)\n" + "2. 小说人物对话(如“请模拟段誉与王语嫣的一段对话”)\n" + "3. 剧情分析(如“分析乔峰误杀阿朱后人物心理与情节影响”)\n" + "4. 世界观设定解读(如“解释萧远山和玄慈之间的恩怨”)\n" + "5. 多角色博弈关系梳理(如“简析萧峰、慕容复、段誉三人的立场冲突”)\n\n" + "你只需输出最终补全后的清晰自然语言指令,不要加任何解释、说明或引导文字。\n" + "如果原始输入非常模糊,比如‘继续’、‘对话’,你需要根据小说上下文补全。\n\n" + "【示例1】\n" + "输入:‘如果阿朱没死呢’\n" + "输出:‘请假设阿朱未死,模仿金庸风格续写一段完整中段剧情。’\n\n" + "【示例2】\n" + "输入:‘乔峰和虚竹的关系’\n" + "输出:‘请分析乔峰与虚竹之间的兄弟关系演变,结合剧情变化和人物心理进行深入剖析。’\n\n" + "【示例3】\n" + "输入:‘继续’\n" + "输出:‘继续前文的小说剧情,模仿金庸风格续写一段中段情节’" + ) + }, + { + "role": "user", + "content": query + } + ] + return llm.generate(name_prompt) + + +def get_event_contexts_for_prompt( + memory: TreeTextMemory, + event_texts: list[str], + k: int = 30 +) -> dict[str, list[str]]: + """ + 对每个事件执行 search + 拿前两个匹配点 + 获取后续剧情,用于构造 GPT prompt。 + + Args: + memory: TreeTextMemory 实例 + event_texts: 提取出的事件文本列表 + k: 每个节点向后取几个 follows + + Returns: + dict[str, list[str]]: {event_text -> [后续memory strings]} + """ + result = {} + + for event in event_texts: + try: + matches = memory.search(event, top_k=2) + memory_strings = [] + + for match in matches: + follow_texts = get_following_memory_texts(memory, match.id, k) + memory_strings.extend(follow_texts) + + result[event] = memory_strings + + except Exception as e: + print(f"Error processing event '{event}': {e}") + result[event] = [] + + return result + + +def node_dict_to_textual_item(node_dict): + return TextualMemoryItem( + id=node_dict["id"], + memory=node_dict["memory"], + metadata=TreeNodeTextualMemoryMetadata(**node_dict["metadata"]) + ) + + +def get_embedding(text): + url = "http://123.129.219.111:3000/v1/embeddings" + headers = { + "Authorization": "Bearer sk-BboZZQNg570YPNhJrGjyPIjOsBpCzUSHRZaDFv4BBVCqTkRQ", + "Content-Type": "application/json" + } + payload = { + "input": text, + "model": "text-embedding-ada-002" + } + try: + response = requests.post(url, headers=headers, json=payload) + response.raise_for_status() + return response.json()["data"][0]["embedding"] + except Exception as e: + print(f"⚠️ 获取 embedding 失败:{e}") + return None +# === TIME STAMP === +def iso_now(): + return datetime.now().isoformat() + +# === CREATE MEMORY NODE === +def create_memory_node_working(content, entities, key, memory_type="WorkingMemory"): + now = iso_now() + node_id = str(uuid.uuid4()) + embedding = get_embedding(content) + + metadata = TreeNodeTextualMemoryMetadata( + user_id="", + session_id="", + status="activated", + type="fact", + confidence=0.99, + entities=entities, + tags=["事件"] if "事件" in key else ["关系"], + updated_at=now, + memory_type=memory_type, + key=key, + sources=[], + embedding=embedding, + created_at=now, + usage=[], + background="" + ) + + return TextualMemoryItem(id=node_id, memory=content, metadata=metadata) + +def build_story_engine_system_prompt(past_event) -> str: + return ( + "你是一个专门负责小说创作的高级 AI 模型,擅长以模仿原作者风格创作中段情节。你的任务是根据用户输入的假设剧情和人物记忆(memory),创作一段完整的剧情发展,大约2000字。\n\n" + "你的创作必须遵守以下规则:\n\n" + "1. 使用原本风格的段落式小说语言,**不得**使用列表、摘要、分析型语言。\n" + f"2. 请基于原本的叙事节奏,原文剧情中的后续发展记忆如下{past_event},请作为参考。" + "3. 结尾应保留张力、未解之谜或新冲突,为后续章节埋下伏笔。\n\n" + "4. 如果用户假设的剧情严重偏离世界观(比如在武侠小说里说主角提起了RPG),则提醒用户不恰当。\n\n" + "你拥有人物的性格、过往事件、动机与情绪等结构化记忆(memory),可用于辅助判断和创作,**但不可直接提及或解释 memory 的存在**。\n\n" + "你的目标是像作者本人续写自己的小说那样,保留风格、节奏、人物逻辑与复杂性,以事件为骨,以情感为脉,以文采为血肉。" + ) + +def continue_story_building_prompt(past_event) ->str: + return ( + + "你是一个专门负责小说创作的高级 AI 模型,擅长以模仿原作者风格创作中段情节,大约2000字。\n\n" + "你将根据之前的小说正文继续进行创作,遵循以下规则:\n\n" + "1. 使用原本风格的段落式小说语言,**不得**使用列表、摘要、分析型语言。\n" + f"2. 请基于原本的叙事节奏,原文剧情中的后续发展记忆如下{past_event},请作为参考。" + "3. 结尾应保留张力、未解之谜或新冲突,为后续章节埋下伏笔。\n\n" + "4. 以原文为参考,如果续写接近尾声或者用户提示结束,则结束故事。\n\n" + "5. 如果用户假设的剧情严重偏离世界观(比如在武侠小说里说主角提起了RPG),则提醒用户不恰当。\n\n" + "你拥有人物的性格、过往事件、动机与情绪等结构化记忆(memory),可用于辅助判断和创作,**但不可直接提及或解释 memory 的存在**。\n\n" + "你的目标是像作者本人续写自己的小说那样,保留风格、节奏、人物逻辑与复杂性,以事件为骨,以情感为脉,以文采为血肉。" + ) + +def show_memory(mem_cube): + all_memories = mem_cube.text_mem.get_all() + nodes = all_memories.get("nodes", []) # 取出节点列表 + + print("🔍 查询所有记忆:") + for i, memory1 in enumerate(nodes, 1): + print(f"{i}. {memory1['memory']}") + print(f" 键: {memory1['metadata'].get('key')}") + print(f" 类型: {memory1['metadata'].get('memory_type')}") + print(f" 标签: {memory1['metadata'].get('tags')}") + print() + + +if __name__ == "__main__": + #Use config to initialize Tree_memory and MOS + config = TreeTextMemoryConfig.from_json_file("/root/Test/memos_config.json") + tree_memory = TreeTextMemory(config) + tree_memory.graph_store.clear() + tree_memory.load("/root/Test") + mos_config = MOSConfig.from_json_file("/root/Test/server_memos_config.json") + memory = MOS(mos_config) + + #Initialize user_id, openai_key and base, and create user + user_id = "root" + os.environ["MOS_USER_ID"] = user_id + os.environ["OPENAI_API_KEY"] = "sk-BboZZQNg570YPNhJrGjyPIjOsBpCzUSHRZaDFv4BBVCqTkRQ" + os.environ["OPENAI_API_BASE"] = "http://123.129.219.111:3000/v1" + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + if not openai_key: + raise ValueError("❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。") + user_id = os.getenv("MOS_USER_ID", "default_user") + top_k = int(os.getenv("MOS_TOP_K", "5")) + memory.create_user(user_id=user_id) + + #Create Memcube + print("🚀 开始创建结构化记忆MemCube (API版)...") + mem_cube = GeneralMemCube(get_memcube_config()) + + print("✅ MemCube创建成功!") + print(f" 📊 用户ID: {mem_cube.config.user_id}") + print(f" 📊 MemCube ID: {mem_cube.config.cube_id}") + print(f" 📊 文本记忆后端: {mem_cube.config.text_mem.backend}") + print(f" 🔍 嵌入模型: text-embedding-ada-002 (OpenAI)") + print(f" 🎯 配置模式: OPENAI API") + + #Assign tree_memory to text_memory + mem_cube.text_mem=tree_memory + + #This is used to show all memories in memcube (optional) + #show_memory(mem_cube) + + #Register memcube to user, then user will have access to that memcube + memory.register_mem_cube(mem_cube,user_id=user_id) + + #Use built-in OpenAI initializer in MemOS to set up LLM config + llm_config = OpenAILLMConfig( + api_key=openai_key, + api_base=openai_base, + model_name_or_path="gpt-4o", + temperature=1.2, + max_tokens=8192, + top_p=1.0, + remove_think_prefix=False, + extra_body=None, + ) + llm = OpenAILLM(llm_config) + + #user query + query="如果萧峰没有杀阿朱" + + #extract key event and get related past event + event_extracted=key_event_extraction(query,llm) + past_event = get_event_contexts_for_prompt(tree_memory,event_extracted) + + #Chat with refined command and past event, all contained in system prompt + response = memory.chat( + query=refine_command(query,llm), + user_id="root", + base_prompt = build_story_engine_system_prompt(past_event) + ) + print(response) + + #Save current memory as working memory and continue to write + memory_tmp = create_memory_node_working(response, [],"") + mem_cube.text_mem.add([memory_tmp]) + query = "继续" + response = memory.chat( + query=refine_command(query,llm), + user_id="root", + base_prompt = continue_story_building_prompt(past_event) + ) + print(response) \ No newline at end of file diff --git a/examples/cookbook/chapter3/Converter.ipynb b/examples/cookbook/chapter3/Converter.ipynb new file mode 100644 index 00000000..1cede2fb --- /dev/null +++ b/examples/cookbook/chapter3/Converter.ipynb @@ -0,0 +1,187 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "1b49e84f", + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "import uuid\n", + "from datetime import datetime\n", + "from pathlib import Path\n", + "import requests # 用于请求 Ollama 本地 API\n", + "\n", + "# === CONFIG ===\n", + "INPUT_FILE = \"memcubes_all.json\"\n", + "OUTPUT_FILE = \"memcube_memory_output_with_embed.json\"\n", + "\n", + "# === EMBEDDING via Ollama (nomic-embed-text:latest) ===\n", + "def get_embedding(text):\n", + " url = \"http://localhost:11434/api/embeddings\" # Ollama 默认端口\n", + " payload = {\n", + " \"model\": \"nomic-embed-text:latest\",\n", + " \"prompt\": text\n", + " }\n", + " try:\n", + " response = requests.post(url, json=payload)\n", + " response.raise_for_status()\n", + " return response.json()[\"embedding\"]\n", + " except Exception as e:\n", + " print(f\"⚠️ 获取 embedding 失败:{e}\")\n", + " return None\n", + "\n", + "# === TIME STAMP ===\n", + "def iso_now():\n", + " return datetime.now().isoformat()\n", + "\n", + "# === CREATE MEMORY NODE ===\n", + "def create_memory_node(content, entities, key, memory_type=\"LongTermMemory\"):\n", + " now = iso_now()\n", + " node_id = str(uuid.uuid4())\n", + " embedding = get_embedding(content)\n", + " return {\n", + " \"id\": node_id,\n", + " \"memory\": content,\n", + " \"metadata\": {\n", + " \"user_id\": \"\",\n", + " \"session_id\": \"\",\n", + " \"status\": \"activated\",\n", + " \"type\": \"fact\",\n", + " \"confidence\": 0.99,\n", + " \"entities\": entities,\n", + " \"tags\": [\"事件\"] if \"事件\" in key else [\"关系\"],\n", + " \"updated_at\": now,\n", + " \"memory_type\": memory_type,\n", + " \"key\": key,\n", + " \"sources\": [],\n", + " \"embedding\": embedding,\n", + " \"created_at\": now,\n", + " \"usage\": [],\n", + " \"background\": \"\"\n", + " }\n", + " }\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "76f8805f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "✅ 完成转换,共生成 7684 个 memory 节点,7198 条边\n", + "📁 输出文件: memcube_memory_output_with_embed.json\n" + ] + } + ], + "source": [ + "\n", + "with open(INPUT_FILE, \"r\", encoding=\"utf-8\") as f:\n", + " memcube_data = json.load(f)\n", + "\n", + "nodes = []\n", + "edges = []\n", + "\n", + "for character, data in memcube_data.items():\n", + " previous_event_id = None\n", + "\n", + " # === EVENTS ===\n", + " for event in data.get(\"events\", []):\n", + " memory_text = f\"{character}在{event.get('time')}于{event.get('location')},因为{event.get('motivation')},进行了{event.get('action')},结果是{event.get('impact')}。\"\n", + " entities = [character] + event.get(\"involved_entities\", [])\n", + " node = create_memory_node(\n", + " content=memory_text,\n", + " entities=entities,\n", + " key=f\"{character}的事件:{event.get('action')}\"\n", + " )\n", + " nodes.append(node)\n", + "\n", + " if previous_event_id:\n", + " edges.append({\n", + " \"source\": previous_event_id,\n", + " \"target\": node[\"id\"],\n", + " \"type\": \"FOLLOWS\"\n", + " })\n", + " previous_event_id = node[\"id\"]\n", + "\n", + " # === AGGREGATED RELATIONS ===\n", + " relations_texts = []\n", + " seen = set()\n", + " for relation in data.get(\"relations\", []):\n", + " name = relation.get(\"name\") or relation.get(\"人物\") or relation.get(\"character\")\n", + " relation_text = relation.get(\"relation\") or relation.get(\"relationship\") or relation.get(\"关系\")\n", + " if not name or not relation_text:\n", + " continue\n", + " dedup_key = (str(name), str(relation_text))\n", + " if dedup_key in seen:\n", + " continue\n", + " seen.add(dedup_key)\n", + " relations_texts.append(f\"与{name}是{relation_text}\")\n", + "\n", + " if relations_texts:\n", + " memory_text = f\"{character}\" + \",\".join(relations_texts) + \"。\"\n", + " entities = [character] \n", + " node = create_memory_node(\n", + " content=memory_text,\n", + " entities=entities,\n", + " key=f\"{character}的关系汇总\",\n", + " )\n", + " nodes.append(node)\n", + "\n", + "# === SAVE TO FILE ===\n", + "with open(OUTPUT_FILE, \"w\", encoding=\"utf-8\") as f:\n", + " json.dump({\n", + " \"nodes\": nodes,\n", + " \"edges\": edges\n", + " }, f, ensure_ascii=False, indent=2)\n", + "\n", + "print(f\"✅ 完成转换,共生成 {len(nodes)} 个 memory 节点,{len(edges)} 条边\")\n", + "print(f\"📁 输出文件: {OUTPUT_FILE}\")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "58b9e2bf", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e84a5609", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/cookbook/chapter3/MUD.py b/examples/cookbook/chapter3/MUD.py new file mode 100644 index 00000000..77be45cb --- /dev/null +++ b/examples/cookbook/chapter3/MUD.py @@ -0,0 +1,529 @@ +import memos +from memos.configs.embedder import EmbedderConfigFactory +from memos.configs.memory import TreeTextMemoryConfig +from memos.configs.mem_reader import SimpleStructMemReaderConfig +from memos.embedders.factory import EmbedderFactory +from memos.mem_reader.simple_struct import SimpleStructMemReader +from memos.memories.textual.tree import TreeTextMemory +import ast +from dotenv import load_dotenv +from memos.mem_cube.general import GeneralMemCube +from memos.configs.mem_cube import GeneralMemCubeConfig +from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata +import memos.memories.textual.tree_text_memory.retrieve.searcher as searcher +import requests +import json +import os +import pickle +import time +from datetime import datetime +from concurrent.futures import ThreadPoolExecutor, as_completed +from requests.adapters import HTTPAdapter +from urllib3.util.retry import Retry +import re +from typing import Dict, List, Optional, Any, Set, Tuple +from dataclasses import dataclass, field +from enum import Enum +import numpy as np +from memos.configs.mem_os import MOSConfig +import inspect +from memos.configs.embedder import EmbedderConfigFactory +import uuid +from memos.mem_os.main import MOS +from memos.llms.openai import OpenAILLM +from memos.configs.llm import OpenAILLMConfig +from pathlib import Path +from memos.memories.textual.tree_text_memory.organize import manager + +def safe_del(self): + try: + if hasattr(self, 'close') and callable(self.close): + self.close() + except Exception as e: + print(f"[MonkeyPatch] __del__ failed safely: {e}") + +# Monkey patch +manager.MemoryManager.__del__ = safe_del + +class Novel_Memcube: + + def __init__(self,openai_key,openai_base,user_id="root"): + self.mem_cube = None + self.openai_key = openai_key + self.openai_base = openai_base + self.memory = None + self.tree_memory = None + self.user_id = user_id + self.llm=None + self.past_event_tmp = None + + + def init_tree_memory(self,path = "/root/Test/memos_config.json"): + config = TreeTextMemoryConfig.from_json_file(path) + self.tree_memory = TreeTextMemory(config) + self.tree_memory.graph_store.clear() + self.tree_memory.load("/root/Test") + + def init_mos(self,path = "/root/Test/server_memos_config.json"): + mos_config = MOSConfig.from_json_file(path) + self.memory = MOS(mos_config) + self.memory.create_user(user_id = self.user_id) + + def init_memcube(self): + self.mem_cube = GeneralMemCube(self.get_memcube_config()) + self.mem_cube.text_mem = self.tree_memory + self.memory.register_mem_cube(self.mem_cube,user_id = self.user_id) + + def init_llm(self): + llm_config = OpenAILLMConfig( + api_key=self.openai_key, + api_base=self.openai_base, + model_name_or_path="gpt-4o", + temperature=1.2, + max_tokens=8192, + top_p=1.0, + remove_think_prefix=False, + extra_body=None, + ) + self.llm = OpenAILLM(llm_config) + + def get_memcube_config(self): + + config_memcube = GeneralMemCubeConfig( + user_id=self.user_id, + cube_id=f"{self.user_id}_structured_memories_cube", + text_mem={ + "backend": "general_text", + "config": { + "extractor_llm": { + "backend": "openai", + "config": { + "model_name_or_path": "gpt-4o", + "api_key": self.openai_key, + "api_base": self.openai_base, + "temperature": 0.8, + "max_tokens": 8192, + } + }, + "embedder": { + "backend": "universal_api", + "config": { + "provider": "openai", + "api_key": self.openai_key, + "model_name_or_path": "text-embedding-ada-002", + "base_url": self.openai_base, + } + }, + "vector_db": { + "backend": "qdrant", + "config": { + "collection_name": f"{self.user_id}_structured_memories", + "vector_dimension": 1536, + "distance_metric": "cosine" + } + } + } + }, + act_mem={"backend": "uninitialized"}, + para_mem={"backend": "uninitialized"} + ) + return config_memcube + + def get_following_memory_texts(self,start_id: str, k: int = 30) -> list[str]: + """ + Return the metadata["memory"] strings of the next k nodes following a given node via FOLLOWS edges. + + Args: + memory (TreeTextMemory): Memory system instance. + start_id (str): The starting node ID. + k (int): Number of following nodes to retrieve. + + Returns: + list[str]: List of memory texts from the following nodes. + """ + graph = self.tree_memory.graph_store.export_graph() + nodes = {node["id"]: node for node in graph["nodes"]} + follows_map = { + edge["source"]: edge["target"] + for edge in graph["edges"] + if edge["type"] == "FOLLOWS" + } + + result = [] + current_id = start_id + for _ in range(k): + next_id = follows_map.get(current_id) + if not next_id or next_id not in nodes: + break + + metadata = nodes[next_id].get("metadata", {}) + memory_text = metadata.get("memory") or nodes[next_id].get("memory") # fallback + if memory_text: + result.append(memory_text) + current_id = next_id + + return result + + + def key_event_extraction(self,query): + name_prompt = [ + { + "role": "system", + "content": "你是一个精准事件抽取器。用户会描述一个或多个小说中发生过的事件,你需要从中提取出用户想要改变或讨论的关键事件,并用一句话简洁描述每个事件。仅概括事件,无需满足用户需求。\n" + "要求:\n" + "1. 每个事件必须是真实发生在小说原文中的事件,而非假设。\n" + "2. 每个事件必须为一个字符串,构成 Python list 的元素。\n" + "3. 最终输出必须是合法的 Python list,例如:\n" + '''["乔峰误杀阿朱", "段誉跳崖逃避婚姻"]\n''' + "你只输出这个 list,不要添加任何解释或额外的内容。" + }, + { + "role": "user", + "content": query + } + ] + key_event = self.llm.generate(name_prompt) + + return ast.literal_eval(key_event) + + def refine_command(self,query: str) -> str: + name_prompt = [ + { + "role": "system", + "content": ( + "你是一个任务指令优化器,专用于小说类用户任务。\n" + "用户会给出一个随意、模糊、简短或不完整的请求,\n" + "你需要将它补全为一条完整、清晰、精炼的自然语言指令。\n\n" + "指令内容可以包括但不限于:\n" + "1. 小说剧情续写(如模仿金庸风格续写一段中段剧情)\n" + "2. 小说人物对话(如“请模拟段誉与王语嫣的一段对话”)\n" + "3. 剧情分析(如“分析乔峰误杀阿朱后人物心理与情节影响”)\n" + "4. 世界观设定解读(如“解释萧远山和玄慈之间的恩怨”)\n" + "5. 多角色博弈关系梳理(如“简析萧峰、慕容复、段誉三人的立场冲突”)\n\n" + "你只需输出最终补全后的清晰自然语言指令,不要加任何解释、说明或引导文字。\n" + "如果原始输入非常模糊,比如‘继续’、‘对话’,你需要根据小说上下文补全。\n\n" + "【示例1】\n" + "输入:‘如果阿朱没死呢’\n" + "输出:‘请假设阿朱未死,模仿金庸风格续写一段完整中段剧情。’\n\n" + "【示例2】\n" + "输入:‘乔峰和虚竹的关系’\n" + "输出:‘请分析乔峰与虚竹之间的兄弟关系演变,结合剧情变化和人物心理进行深入剖析。’\n\n" + "【示例3】\n" + "输入:‘继续’\n" + "输出:‘继续前文的小说剧情,模仿金庸风格续写一段中段情节’" + ) + }, + { + "role": "user", + "content": query + } + ] + return self.llm.generate(name_prompt) + + + def get_event_contexts_for_prompt(self,event_texts: list[str],k: int = 30,top_k=2) -> dict[str, list[str]]: + """ + 对每个事件执行 search + 拿前两个匹配点 + 获取后续剧情,用于构造 GPT prompt。 + + Args: + memory: TreeTextMemory 实例 + event_texts: 提取出的事件文本列表 + k: 每个节点向后取几个 follows + + Returns: + dict[str, list[str]]: {event_text -> [后续memory strings]} + """ + result = {} + + for event in event_texts: + try: + matches = self.tree_memory.search(event, top_k=2) + memory_strings = [] + + for match in matches: + follow_texts = self.get_following_memory_texts(match.id, k) + memory_strings.extend(follow_texts) + + result[event] = memory_strings + + except Exception as e: + print(f"Error processing event '{event}': {e}") + result[event] = [] + + return result + + + def get_embedding(self,text): + url = "http://123.129.219.111:3000/v1/embeddings" + headers = { + "Authorization": "Bearer "+self.openai_key, + "Content-Type": "application/json" + } + payload = { + "input": text, + "model": "text-embedding-ada-002" + } + try: + response = requests.post(url, headers=headers, json=payload) + response.raise_for_status() + return response.json()["data"][0]["embedding"] + except Exception as e: + print(f"⚠️ 获取 embedding 失败:{e}") + return None + # === TIME STAMP === + @staticmethod + def iso_now(): + return datetime.now().isoformat() + + # === CREATE MEMORY NODE === + + def create_memory_node_working(self,content, entities, key, memory_type="WorkingMemory"): + now = Novel_Memcube.iso_now() + node_id = str(uuid.uuid4()) + embedding = self.get_embedding(content) + + metadata = TreeNodeTextualMemoryMetadata( + user_id="", + session_id="", + status="activated", + type="fact", + confidence=0.99, + entities=entities, + tags=["事件"] if "事件" in key else ["关系"], + updated_at=now, + memory_type=memory_type, + key=key, + sources=[], + embedding=embedding, + created_at=now, + usage=[], + background="" + ) + + return TextualMemoryItem(id=node_id, memory=content, metadata=metadata) + + @staticmethod + def node_dict_to_textual_item(node_dict): + return TextualMemoryItem( + id=node_dict["id"], + memory=node_dict["memory"], + metadata=TreeNodeTextualMemoryMetadata(**node_dict["metadata"]) + ) + + + + @staticmethod + def build_story_engine_system_prompt(past_event) -> str: + return ( + "你是一个专门负责小说创作的高级 AI 模型,擅长以模仿原作者风格创作中段情节。你的任务是根据用户输入的假设剧情和人物记忆(memory),创作一段完整的剧情发展。\n\n" + "你的创作必须遵守以下规则:\n\n" + "1. 使用原本风格的段落式小说语言,**不得**使用列表、摘要、分析型语言。\n" + f"2. 请基于原本的叙事节奏,原文剧情中的后续发展记忆如下{past_event},请作为参考。" + "3. 结尾应保留张力、未解之谜或新冲突,为后续章节埋下伏笔。\n\n" + "4. 如果用户假设的剧情严重偏离世界观(比如在武侠小说里说主角提起了RPG),则提醒用户不恰当。\n\n" + "你拥有人物的性格、过往事件、动机与情绪等结构化记忆(memory),可用于辅助判断和创作,**但不可直接提及或解释 memory 的存在**。\n\n" + "你的目标是像作者本人续写自己的小说那样,保留风格、节奏、人物逻辑与复杂性,以事件为骨,以情感为脉,以文采为血肉。" + ) + + @staticmethod + def continue_story_building_prompt(past_event) ->str: + return ( + + "你是一个专门负责小说创作的高级 AI 模型,擅长以模仿原作者风格创作中段情节。\n\n" + "你将根据之前的小说正文继续进行创作,遵循以下规则:\n\n" + "1. 使用原本风格的段落式小说语言,**不得**使用列表、摘要、分析型语言。\n" + f"2. 请基于原本的叙事节奏,原文剧情中的后续发展记忆如下{past_event},请作为参考。" + "3. 结尾应保留张力、未解之谜或新冲突,为后续章节埋下伏笔。\n\n" + "4. 以原文为参考,如果续写接近尾声或者用户提示结束,则结束故事。\n\n" + "5. 如果用户假设的剧情严重偏离世界观(比如在武侠小说里说主角提起了RPG),则提醒用户不恰当。\n\n" + "你拥有人物的性格、过往事件、动机与情绪等结构化记忆(memory),可用于辅助判断和创作,**但不可直接提及或解释 memory 的存在**。\n\n" + "你的目标是像作者本人续写自己的小说那样,保留风格、节奏、人物逻辑与复杂性,以事件为骨,以情感为脉,以文采为血肉。" + ) + @staticmethod + def dialogue_response_prompt(past_event: str) -> str: + return ( + "你是一个专精于小说人物心理与语言风格的高级 AI 模型,擅长模拟原著人物之间的自然对话。\n\n" + "你的任务是根据用户设定的对话场景与人物,生成符合人物性格、时代背景与原著风格的高质量对白。\n\n" + f"1. 背景记忆参考如下:{past_event},请用于理解人物关系与情境。\n" + "2. 所有输出必须为角色对白,**不得**添加任何解释、叙述、引导性描述或分析性内容。\n" + "3. 每一句对话应紧扣人物性格,语言风格应各具特色,不可千篇一律。\n" + "4. 你应尽量体现人物之间的情感波动、矛盾冲突或内心微妙变化。\n" + "5. 对话长度适中,可包含若干轮往返对话,避免草草收尾。\n" + "6. 若用户提供的角色不属于同一部小说或世界观,请委婉指出并拒绝生成。\n\n" + "你拥有结构化记忆(memory),包括人物性格、背景、历史事件等,用以辅助生成真实可信的对白,**但请勿在对话中提及 memory 本身的存在**。\n\n" + "目标是让用户感受到两个真实人物在真实场景中的对话,如同原著未收录的番外篇,具有情感张力与文学质感。" + ) + @staticmethod + def analysis_response_prompt(past_event: str) -> str: + return ( + "你是一个专注于小说结构与人物心理剖析的高级 AI 模型,擅长深入挖掘剧情冲突、人物动机与关系演变。\n\n" + f"你拥有的背景信息如下:{past_event},请以此为基础展开分析。\n\n" + "1. 分析内容可以包括:某个角色的心理状态变化、人际关系的张力、一段剧情的矛盾冲突或潜在后果等。\n" + "2. 请使用自然语言完整表达,不使用列表或关键词罗列,风格应有文学性与思辨性。\n" + "3. 分析应有理有据,可适当引用剧情细节,逻辑清晰,避免主观臆断。\n" + "4. 如果分析对象涉及多个角色,需体现各自立场差异与相互影响。\n" + "5. 若用户输入较为模糊(如“分析段誉”),请结合记忆推断最相关的情节加以展开。\n" + "6. 若用户要求分析的事件明显不属于同一世界观或风格,请礼貌拒绝并说明原因。\n\n" + "你拥有结构化记忆(memory),包括人物历史、性格、重大事件等信息,可用于辅助推理,**但请勿直接引用或说明 memory 的存在**。\n\n" + "你的目标是提供有深度、有温度、有洞察力的文学分析,使读者对人物与情节有新的理解与感受。" + ) + + @staticmethod + def world_explanation_prompt(past_event: str) -> str: + return ( + "你是一个博学的小说设定讲解专家,擅长分析小说中的世界观、门派设定、历史背景与文化体系。\n\n" + f"你掌握的相关剧情背景如下:{past_event},请结合此信息回答用户的问题。\n\n" + "1. 回应应以自然语言展开,逻辑清晰,文字优雅,不使用列表形式。\n" + "2. 可以解释人物所处时代、各大门派渊源、武学体系演进、政治格局、恩怨传承等内容。\n" + "3. 若涉及历史设定,应尽量与小说中已有描写保持一致,不可自行编造不合理内容。\n" + "4. 若用户输入模糊(如“少林是什么”),请结合上下文与记忆推断其关心点,并做适当拓展。\n" + "5. 若用户提问明显超出小说世界观(如“段誉学编程了吗”),请礼貌拒绝并说明不合适。\n\n" + "你拥有结构化记忆(memory),涵盖各类设定细节,可用于支撑你的推理与解读,**但请勿显式说明 memory 的存在**。\n\n" + "你的目标是如一位深入原著的解说者,提供权威、流畅且富有文化感的设定解读,帮助读者更深入理解小说的世界。" + ) + + + @staticmethod + def classify_query_intent_prompt(query: str) -> list: + return [ + { + "role": "system", + "content": ( + "你是一个小说交互系统的意图识别模块。\n" + "你将接收用户的一句话请求,判断其属于以下哪一类小说任务:\n\n" + "1. continue_story:继续前文的小说剧情\n" + "2. hypothetical_story:提出假设并基于该假设进行剧情续写\n" + "3. dialogue:模拟小说人物对话\n" + "4. analysis:分析某个角色的心理或人物关系或者分析一段剧情的发展、冲突或后果\n" + "5. world_building:解释小说设定、门派、历史背景等\n" + "6. other:不属于上述类型\n\n" + "你只输出一个类型代号,例如:`hypothetical_story`,不要添加任何解释或多余内容。" + ) + }, + { + "role": "user", + "content": query + } + ] + + def classify_query_intent(self,query: str) -> str: + prompt = Novel_Memcube.classify_query_intent_prompt(query) + result = self.llm.generate(prompt) + return result.strip() + + + def build_story(self,query): + event_extracted = self.key_event_extraction(query) + past_event = self.get_event_contexts_for_prompt(event_extracted) + self.past_event_tmp = past_event + response = self.memory.chat( + query=self.refine_command(query), + user_id=self.user_id, + base_prompt = Novel_Memcube.build_story_engine_system_prompt(past_event) + ) + memory_tmp = self.create_memory_node_working(response, [],"") + self.mem_cube.text_mem.add([memory_tmp]) + return response + + def continue_story(self,query): + response = self.memory.chat( + query=self.refine_command(query), + user_id=self.user_id, + base_prompt = Novel_Memcube.continue_story_building_prompt(self.past_event_tmp) + ) + memory_tmp = self.create_memory_node_working(response, [],"") + self.mem_cube.text_mem.add([memory_tmp]) + return response + + def dialogue(self,query): + event_extracted = self.key_event_extraction(query) + past_event = self.get_event_contexts_for_prompt(event_extracted) + response = self.memory.chat( + query=self.refine_command(query), + user_id=self.user_id, + base_prompt = Novel_Memcube.dialogue_response_prompt(past_event) + ) + memory_tmp = self.create_memory_node_working(response, [],"") + self.mem_cube.text_mem.add([memory_tmp]) + return response + + def analysis(self,query): + event_extracted = self.key_event_extraction(query) + past_event = self.get_event_contexts_for_prompt(event_extracted) + response = self.memory.chat( + query=self.refine_command(query), + user_id=self.user_id, + base_prompt = Novel_Memcube.analysis_response_prompt(past_event) + ) + memory_tmp = self.create_memory_node_working(response, [],"") + self.mem_cube.text_mem.add([memory_tmp]) + return response + + def world_explanation(self,query): + event_extracted = self.key_event_extraction(query) + past_event = self.get_event_contexts_for_prompt(event_extracted) + response = self.memory.chat( + query=self.refine_command(query), + user_id=self.user_id, + base_prompt = Novel_Memcube.world_explanation_prompt(past_event) + ) + memory_tmp = self.create_memory_node_working(response, [],"") + self.mem_cube.text_mem.add([memory_tmp]) + return response + + def general(self,query): + event_extracted = self.key_event_extraction(query) + past_event = self.get_event_contexts_for_prompt(event_extracted) + response = self.memory.chat( + query=self.refine_command(query), + user_id=self.user_id, + ) + memory_tmp = self.create_memory_node_workingt(response, [],"") + self.mem_cube.text_mem.add([memory_tmp]) + return response + + + def interactive_story_loop(self): + print("欢迎进入 MUD 小说互动游戏!(输入“结束”退出)") + while True: + query = input("请输入你的操作(例如:如果萧峰没有杀阿朱):\n") + if query.strip() in ["结束", "退出", "quit", "exit"]: + print("感谢使用,再见!") + break + intent = self.classify_query_intent(query) + + if intent == "continue_story": + response = self.continue_story(query) + elif intent == "hypothetical_story": + response = self.build_story(query) + elif intent == "dialogue": + response = self.dialogue(query) + elif intent == "analysis": + response = self.analysis(query) + elif intent == "world_building": + response = self.world_explanation(query) + else: + response = self.general(query) + + print("\n 生成内容如下:\n") + print(response) + + + + +if __name__ == "__main__": + user_id = "root" + os.environ["MOS_USER_ID"] = user_id + os.environ["OPENAI_API_KEY"] = "sk-BboZZQNg570YPNhJrGjyPIjOsBpCzUSHRZaDFv4BBVCqTkRQ" + os.environ["OPENAI_API_BASE"] = "http://123.129.219.111:3000/v1" + openai_key = os.getenv("OPENAI_API_KEY") + openai_base = os.getenv("OPENAI_API_BASE", "https://api.openai.com/v1") + user_id = os.getenv("MOS_USER_ID", "default_user") + + mud = Novel_Memcube(openai_key,openai_base,user_id) + mud.init_tree_memory() + mud.init_mos() + mud.init_memcube() + mud.init_llm() + + mud.interactive_story_loop() \ No newline at end of file diff --git a/examples/cookbook/chapter3/Test.ipynb b/examples/cookbook/chapter3/Test.ipynb new file mode 100644 index 00000000..a94b65bf --- /dev/null +++ b/examples/cookbook/chapter3/Test.ipynb @@ -0,0 +1,7583 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "dece6095-1222-4295-9fe7-ef8d7757a53f", + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "import json\n", + "import os\n", + "import pickle\n", + "import time\n", + "from datetime import datetime\n", + "from concurrent.futures import ThreadPoolExecutor, as_completed\n", + "from requests.adapters import HTTPAdapter\n", + "from urllib3.util.retry import Retry\n", + "import re\n", + "from typing import Dict, List, Optional, Any, Set, Tuple\n", + "from dataclasses import dataclass, field\n", + "from enum import Enum\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d86a7b94", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "✅ 已保存:chapters/chapter1.txt(第一章)\n", + "✅ 已保存:chapters/chapter2.txt(第二章)\n", + "✅ 已保存:chapters/chapter3.txt(第三章)\n", + "✅ 已保存:chapters/chapter4.txt(第四章)\n", + "✅ 已保存:chapters/chapter5.txt(第五章)\n", + "✅ 已保存:chapters/chapter6.txt(第六章)\n", + "✅ 已保存:chapters/chapter7.txt(第七章)\n", + "✅ 已保存:chapters/chapter8.txt(第八章)\n", + "✅ 已保存:chapters/chapter9.txt(第九章)\n", + "✅ 已保存:chapters/chapter10.txt(第十章)\n", + "✅ 已保存:chapters/chapter11.txt(第十一章)\n", + "✅ 已保存:chapters/chapter12.txt(第十二章)\n", + "✅ 已保存:chapters/chapter13.txt(第十三章)\n", + "✅ 已保存:chapters/chapter14.txt(第十四章)\n", + "✅ 已保存:chapters/chapter15.txt(第十五章)\n", + "✅ 已保存:chapters/chapter16.txt(第十六章)\n", + "✅ 已保存:chapters/chapter17.txt(第十七章)\n", + "✅ 已保存:chapters/chapter18.txt(第十八章)\n", + "✅ 已保存:chapters/chapter19.txt(第十八章)\n", + "✅ 已保存:chapters/chapter20.txt(第十九章)\n", + "✅ 已保存:chapters/chapter21.txt(第二十章)\n", + "✅ 已保存:chapters/chapter22.txt(第二十一章)\n", + "✅ 已保存:chapters/chapter23.txt(第二十二章)\n", + "✅ 已保存:chapters/chapter24.txt(第二十三章)\n", + "✅ 已保存:chapters/chapter25.txt(第二十四章)\n", + "✅ 已保存:chapters/chapter26.txt(第二十五章)\n", + "✅ 已保存:chapters/chapter27.txt(第二十六章)\n", + "✅ 已保存:chapters/chapter28.txt(第二十七章)\n", + "✅ 已保存:chapters/chapter29.txt(第二十八章)\n", + "✅ 已保存:chapters/chapter30.txt(第二十九章)\n", + "✅ 已保存:chapters/chapter31.txt(第三十章)\n", + "✅ 已保存:chapters/chapter32.txt(第三十一章)\n", + "✅ 已保存:chapters/chapter33.txt(第三十二章)\n", + "✅ 已保存:chapters/chapter34.txt(第三十三章)\n", + "✅ 已保存:chapters/chapter35.txt(第三十四章)\n", + "✅ 已保存:chapters/chapter36.txt(第三十五章)\n", + "✅ 已保存:chapters/chapter37.txt(第三十六章)\n", + "✅ 已保存:chapters/chapter38.txt(第三十七章)\n", + "✅ 已保存:chapters/chapter39.txt(第三十八章)\n", + "✅ 已保存:chapters/chapter40.txt(第四十章)\n", + "✅ 已保存:chapters/chapter41.txt(第四十一章)\n", + "✅ 已保存:chapters/chapter42.txt(第四十二章)\n", + "✅ 已保存:chapters/chapter43.txt(第四十三章)\n", + "✅ 已保存:chapters/chapter44.txt(第四十四章)\n", + "✅ 已保存:chapters/chapter45.txt(第四十五章)\n", + "✅ 已保存:chapters/chapter46.txt(第四十六章)\n", + "✅ 已保存:chapters/chapter47.txt(第四十七章)\n", + "✅ 已保存:chapters/chapter48.txt(第四十八章)\n", + "✅ 已保存:chapters/chapter49.txt(第四十九章)\n", + "✅ 已保存:chapters/chapter50.txt(第五十章)\n" + ] + } + ], + "source": [ + "def extract_all_chapters(text: str, output_dir: str = \"chapters\"):\n", + " # 匹配所有“第X章”标题的位置\n", + " pattern = r\"(第[一二三四五六七八九十百千零〇两\\d]+章)\"\n", + " matches = list(re.finditer(pattern, text))\n", + "\n", + " if not matches:\n", + " raise ValueError(\"未找到任何章节标题\")\n", + "\n", + " os.makedirs(output_dir, exist_ok=True)\n", + "\n", + " for i in range(len(matches)):\n", + " start_idx = matches[i].start()\n", + " end_idx = matches[i+1].start() if i+1 < len(matches) else len(text)\n", + " chapter_title = matches[i].group()\n", + " chapter_number = i + 1 # 用自然数编号\n", + " \n", + " chapter_text = text[start_idx:end_idx].strip()\n", + " filename = os.path.join(output_dir, f\"chapter{chapter_number}.txt\")\n", + " with open(filename, \"w\", encoding=\"utf-8\") as f:\n", + " f.write(chapter_text)\n", + " print(f\"✅ 已保存:{filename}({chapter_title})\")\n", + "\n", + "# 读取整本小说\n", + "with open(\"天龙八部.txt\", \"r\", encoding=\"utf-8\") as f:\n", + " full_text = f.read()\n", + "\n", + "# 提取并保存所有章节\n", + "extract_all_chapters(full_text)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "18386a8e-ae93-4071-9c17-6d0dce24d6f4", + "metadata": {}, + "outputs": [], + "source": [ + "os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com'\n", + "os.environ['HUGGINGFACE_HUB_URL'] = 'https://hf-mirror.com' \n", + "os.environ['HF_HUB_BASE_URL'] = 'https://hf-mirror.com'" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "874d7f92-a9b5-4dbb-a6d5-721a49361a53", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "⚠ jsonrepair库未安装,将使用基础修复策略。运行 'pip install jsonrepair' 启用高级JSON修复\n" + ] + } + ], + "source": [ + "try:\n", + " from json_repair import repair_json\n", + " HAS_JSONREPAIR = True\n", + " print(\"✓ jsonrepair库已加载,JSON修复功能已启用\")\n", + "except ImportError:\n", + " HAS_JSONREPAIR = False\n", + " print(\"⚠ jsonrepair库未安装,将使用基础修复策略。运行 'pip install jsonrepair' 启用高级JSON修复\")\n", + " def repair_json(text):\n", + " return text" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "114d5da0", + "metadata": {}, + "outputs": [], + "source": [ + "class TaskType(Enum):\n", + " EVENT_EXTRACTION = \"event_extraction\"" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "16c2e298-7cae-4a4a-9707-771a6a830b78", + "metadata": {}, + "outputs": [], + "source": [ + "class APIClient:\n", + " \"\"\"API调用客户端 - 支持完整模型配置\"\"\"\n", + " \n", + " def __init__(self, api_url: str, api_key: str, \n", + " event_model: str = \"gpt-4o\"):\n", + " self.api_url = api_url\n", + " self.api_key = api_key\n", + " self.event_model = event_model # 块分析+实体抽取使用的模型\n", + " \n", + " # 创建session并配置连接池和重试策略\n", + " self.session = requests.Session()\n", + " \n", + " retry_strategy = Retry(\n", + " total=3,\n", + " backoff_factor=1,\n", + " status_forcelist=[500, 502, 503, 504],\n", + " )\n", + " \n", + " adapter = HTTPAdapter(pool_connections=10, pool_maxsize=20, max_retries=retry_strategy)\n", + " self.session.mount('http://', adapter)\n", + " self.session.mount('https://', adapter)\n", + " \n", + " self.session.headers.update({\n", + " \"Content-Type\": \"application/json\",\n", + " \"Authorization\": f\"Bearer {self.api_key}\"\n", + " })\n", + " \n", + " def call_api(self, messages: List[Dict], task_type: TaskType, timeout: int = 1800) -> Dict:\n", + " \"\"\"统一的API调用方法 - 根据任务类型选择模型\"\"\"\n", + " # 根据任务类型选择模型\n", + " if task_type == TaskType.EVENT_EXTRACTION:\n", + " model_name = self.event_model\n", + " else:\n", + " model_name = self.event_model # 默认\n", + " \n", + " data = {\n", + " \"model\": model_name,\n", + " \"messages\": messages,\n", + " \"stream\": False\n", + " }\n", + " \n", + " try:\n", + " response = self.session.post(url=self.api_url, json=data, timeout=timeout)\n", + " response.raise_for_status()\n", + " result = response.json()\n", + " return {\n", + " \"status\": \"success\",\n", + " \"content\": result['choices'][0]['message']['content'],\n", + " \"model_used\": model_name\n", + " }\n", + " except requests.exceptions.RequestException as e:\n", + " return {\n", + " \"status\": \"error\",\n", + " \"error\": str(e),\n", + " \"model_used\": model_name\n", + " }\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "179ee663", + "metadata": {}, + "outputs": [], + "source": [ + "def build_event_extraction_prompt(text: str):\n", + " \"\"\"构造 GPT 对话式抽取事件的 prompt\"\"\"\n", + " return [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": (\n", + " \"你是一个小说事件抽取助手。请从给定段落中提取以下字段:\"\n", + " \"- name(涉及人物)\\n\"\n", + " \"- first_appearance(是否首次出现)\\n\"\n", + " \"- time(时间描述)\\n\"\n", + " \"- location(地点)\\n\"\n", + " \"- action(人物做了什么)\\n\"\n", + " \"- involved_entities(其他涉及对象)\\n\"\n", + " \"- impact(行为产生了什么影响)\\n\"\n", + " \"- utterances(人物说了什么)\\n\"\n", + " \"请返回标准 JSON 格式\"\n", + " )\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": f\"以下是小说片段:\\n{text}\\n\\n请返回结构化 JSON 信息:\"\n", + " }\n", + " ]" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "8bff988f", + "metadata": {}, + "outputs": [], + "source": [ + "api_client = APIClient(\n", + " api_url=\"http://123.129.219.111:3000/v1/chat/completions\",\n", + " api_key=\"sk-ZXk4KtKH99yelVZKPrpGB2t8OrhUOoVV0hhGi26zgjkN58Ye\",\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "721c7361", + "metadata": {}, + "outputs": [], + "source": [ + "class Prompt:\n", + " @staticmethod\n", + " def extract_character_names_prompt(paragraph: str, alias_to_name: dict = None):\n", + " system_msg = (\n", + " \"你是一个小说人物识别专家,请从以下小说片段中提取所有明确提及的人物。\\n\"\n", + " \"对于每个人物,请标注该人物的标准姓名(如“乔峰”)以及其在该片段中出现的所有称呼、别名、代称(如“丐帮帮主”、“乔帮主”、“那大汉”)。\\n\\n\"\n", + " \"请以如下格式返回 JSON:\\n\"\n", + " \"[\\n\"\n", + " \" {\\n\"\n", + " \" \\\"name\\\": \\\"乔峰\\\",\\n\"\n", + " \" \\\"aliases\\\": [\\\"丐帮帮主\\\", \\\"乔帮主\\\", \\\"那大汉\\\"]\\n\"\n", + " \" }\\n\"\n", + " \"]\\n\\n\"\n", + " \"⚠️ 注意:\\n\"\n", + " \"1. 只包含人物,不包括地点或组织。\\n\"\n", + " \"2. 同一人物的多个称呼应统一归并在同一个条目中。\\n\"\n", + " \"3. 所有字段使用标准 JSON 格式。不要包含 markdown 符号或注释。\\n\"\n", + " \"4. 如果无法确定某个称呼是否为新人物,可以暂时保留为独立项。\"\n", + " )\n", + "\n", + " if alias_to_name:\n", + " system_msg += \"\\n\\n以下是已知别名对应的标准人物姓名,请尽量将新识别到的称呼归入已有人物中:\\n\"\n", + " alias_map_str = json.dumps(alias_to_name, ensure_ascii=False, indent=2)\n", + " system_msg += alias_map_str\n", + "\n", + " return [\n", + " {\"role\": \"system\", \"content\": system_msg},\n", + " {\"role\": \"user\", \"content\": f\"小说片段如下:\\n{paragraph}\"}\n", + " ]\n", + " @staticmethod\n", + " def update_character_prompt(character_name: str, unfinished_events: list, paragraph: str):\n", + " return [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": (\n", + " \"你是小说人物建模专家,将分析某人物的未完成事件与最新小说片段。\\n\"\n", + " \"你的任务是更新以下字段:\\n\"\n", + " \"- events:事件列表(更新状态、添加新事件,包含子字段 event_id、action、motivation、impact、involved_entities、time、location、event、if_completed)\\n\"\n", + " '''+ - 每个事件必须包含唯一的 \"event_id\",例如 \"event_001\"、\"event_002\" 等。'''\n", + " \"- utterances:说过的话(含时间或事件编号)\\n\"\n", + " \"- speech_style:说话风格(如 古典、直接、讽刺等)\\n\"\n", + " \"- personality_traits:性格(如 冷静、冲动)\\n\"\n", + " \"- emotion_state:当前情绪状态\\n\"\n", + " \"- relations:与他人的关系列表(见结构)\\n\\n\"\n", + " \"请特别注意以下要求:\\n\"\n", + " \"1. 请认真判断现有未完成事件是否已经在新片段中结束。\\n\"\n", + " \"2. 如果某事件已有结局或结果,请务必将其 `if_completed` 字段标记为 true。\\n\"\n", + " \"3. 如果小说片段中出现与该人物相关的新事件,请添加新的事件条目。\\n\"\n", + " \"最终请输出以下 JSON 结构:\\n\"\n", + " \"{\\n\"\n", + " \" \\\"events\\\": [...],\\n\"\n", + " \" \\\"utterances\\\": [...],\\n\"\n", + " \" \\\"speech_style\\\": \\\"...\\\",\\n\"\n", + " \" \\\"personality_traits\\\": [...],\\n\"\n", + " \" \\\"emotion_state\\\": \\\"...\\\",\\n\"\n", + " \" \\\"relations\\\": [...]\\n\"\n", + " \"}\\n\\n\"\n", + " \"⚠️ 请注意:\\n\"\n", + " \"1. 所有字段名必须使用双引号包裹(JSON 标准格式)。\\n\"\n", + " \"2. 不要添加注释符号、额外说明或 markdown 符号(如 ```json、// 等)。\\n\"\n", + " \"3. 仅返回完整 JSON 对象,不能是数组或其他格式。\\n\"\n", + " \"4. 如没有内容可填,请使用空数组 [] 或空字符串 \\\"\\\"。\\n\"\n", + " )\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": (\n", + " f\"人物姓名:{character_name}\\n\"\n", + " f\"当前未完结事件如下(JSON):\\n{json.dumps(unfinished_events, ensure_ascii=False, indent=2)}\\n\\n\"\n", + " f\"小说片段如下:\\n{paragraph}\\n\\n\"\n", + " \"请按上述格式返回该人物的更新信息。\"\n", + " )\n", + " }\n", + " ]\n", + "\n", + " @staticmethod\n", + " def speculate_event_outcome(character_name: str, memcube: dict, user_input: str):\n", + " return [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": (\n", + " \"你是一位小说剧本推演专家。\\n\"\n", + " \"你将获得所有人物的完整 JSON 信息(包括事件链、性格、情绪、关系等)以及一条用户提出的假设性情节。\\n\"\n", + " \"你的任务是基于这些人物的背景、未完成事件、关系网、性格与动机,合理地推演故事可能的发展。\\n\"\n", + " \"请生成完整的小说段落风格的叙述(不是列表、不是 JSON),描写故事如何展开。\\n\"\n", + " \"注意语言风格应与原小说保持一致(如古典武侠风)。\"\n", + " )\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": (\n", + " f\"人物姓名:{character_name}\\n\\n\"\n", + " f\"人物信息如下(JSON 格式):\\n{json.dumps(memcube, ensure_ascii=False, indent=2)}\\n\\n\"\n", + " f\"用户的假设性情节如下:\\n{user_input}\\n\\n\"\n", + " \"请基于上述信息推演故事的发展,返回小说式语言的叙述,不要包含任何解释性语言或 JSON。\"\n", + " )\n", + " }\n", + " ]\n", + " \n", + " @staticmethod\n", + " def evaluate_plot_reasonableness(character_name: str, memcube: dict, user_input: str):\n", + " return [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": (\n", + " \"你是一个小说人物行为合理性分析专家。\\n\"\n", + " \"你将获得所有人物的完整 JSON 信息(包括事件链、性格、情绪、关系等)以及用户提出的一条假设性剧情。\\n\"\n", + " \"你的任务是:\\n\"\n", + " \"1. 判断该剧情是否符合该人物的行为逻辑、性格特征、情绪状态以及当前背景。\\n\"\n", + " \"2. 如不合理,请指出具体不合理的地方,并说明原因。\\n\"\n", + " \"3. 如合理,请说明其合理性,并简要描述该剧情如何顺理成章地发生。\\n\\n\"\n", + " \"返回格式:\\n\"\n", + " \"- 合理性评估:合理 / 不合理 / 有条件合理\\n\"\n", + " \"- 分析说明:详细解释是否符合人物动机、关系与背景\\n\"\n", + " \"- 建议:如有必要,提出修改建议或更合理的替代表达\\n\\n\"\n", + " \"请用简洁中文回答,不要生成小说正文或 JSON 结构。\"\n", + " )\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": (\n", + " f\"人物姓名:{character_name}\\n\\n\"\n", + " f\"所有人物的完整信息如下(JSON 格式):\\n{json.dumps(memcube, ensure_ascii=False, indent=2)}\\n\\n\"\n", + " f\"用户提出的剧情设想如下:\\n{user_input}\\n\\n\"\n", + " \"请你判断这个剧情是否符合该人物当前的状态与逻辑,并说明理由。\"\n", + " )\n", + " }\n", + " ]\n", + "\n", + "@staticmethod\n", + "def emotion_trajectory_prompt(character_name: str, memcube: dict, user_input: str):\n", + " return [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": (\n", + " \"你是一个小说人物情绪轨迹分析专家。\\n\"\n", + " \"你将获得某个人物的完整信息(包括事件、性格、情绪、关系等)和用户设想的一段剧情(可能尚未出现在原文中)。\\n\"\n", + " \"请判断在该剧情中,该人物的情绪是否会发生变化。\\n\\n\"\n", + " \"你的任务是:\\n\"\n", + " \"1. 判断该剧情设想中是否包含情绪变化。\\n\"\n", + " \"2. 如果有,请指出情绪类型,并解释该变化是如何被激发的。\\n\"\n", + " \"3. 如果没有,请说明为何情绪保持稳定。\\n\\n\"\n", + " \"返回格式:\\n\"\n", + " \"- 情绪变化:有 / 无\\n\"\n", + " \"- 当前情绪:xxx\\n\"\n", + " \"- 变化原因:xxx\\n\"\n", + " \"请使用简洁中文作答。\"\n", + " )\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": (\n", + " f\"人物姓名:{character_name}\\n\\n\"\n", + " f\"该人物的完整信息如下(JSON):\\n{json.dumps(memcube, ensure_ascii=False, indent=2)}\\n\\n\"\n", + " f\"用户设想剧情如下:\\n{user_input}\"\n", + " )\n", + " }\n", + " ]\n", + "\n", + "@staticmethod\n", + "def conflict_progression_prompt(character_name: str, memcube: dict, user_input: str):\n", + " return [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": (\n", + " \"你是一个小说人物之间矛盾关系演化的分析专家。\\n\"\n", + " \"你将获得某人物的完整资料(JSON 格式)以及用户提出的一条设想剧情。\\n\"\n", + " \"请判断在这条剧情中,是否涉及与他人之间的矛盾进展。\\n\\n\"\n", + " \"你的任务是:\\n\"\n", + " \"1. 判断该设想剧情中是否涉及已有或潜在冲突对象。\\n\"\n", + " \"2. 如果有,请判断该关系是否发生变化(如激化、缓和或解决)。\\n\"\n", + " \"3. 简述冲突变化的原因。\\n\\n\"\n", + " \"返回格式:\\n\"\n", + " \"- 对手:xxx\\n\"\n", + " \"- 当前阶段:xxx(如:潜在 → 升级 → 缓和 → 解决)\\n\"\n", + " \"- 变化原因:xxx\\n\"\n", + " \"请使用简洁中文作答。\"\n", + " )\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": (\n", + " f\"人物姓名:{character_name}\\n\\n\"\n", + " f\"该人物的完整信息如下(JSON):\\n{json.dumps(memcube, ensure_ascii=False, indent=2)}\\n\\n\"\n", + " f\"用户设想剧情如下:\\n{user_input}\"\n", + " )\n", + " }\n", + " ]\n", + "\n", + "@staticmethod\n", + "def character_position_prompt(character_name: str, memcube: dict, user_input: str):\n", + " return [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": (\n", + " \"你是一个小说人物立场判断专家。\\n\"\n", + " \"你将获得某角色的完整 JSON 信息和一段用户设想的剧情。\\n\"\n", + " \"你的任务是:\\n\"\n", + " \"1. 判断该人物是否在剧情中对某个议题表达了明确立场(如支持、反对、中立、困惑)。\\n\"\n", + " \"2. 如果表达了,请指出该议题和该人物的态度,并解释是否符合他当前的行为逻辑和背景。\\n\\n\"\n", + " \"返回格式:\\n\"\n", + " \"- 议题:xxx\\n\"\n", + " \"- 立场:支持 / 反对 / 中立 / 困惑\\n\"\n", + " \"- 原因:xxx\\n\"\n", + " \"请使用简洁中文作答。\"\n", + " )\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": (\n", + " f\"人物姓名:{character_name}\\n\\n\"\n", + " f\"该人物的完整信息如下(JSON):\\n{json.dumps(memcube, ensure_ascii=False, indent=2)}\\n\\n\"\n", + " f\"用户设想剧情如下:\\n{user_input}\"\n", + " )\n", + " }\n", + " ]\n", + "\n", + "\n", + "# ✅ 构建人物事件列表的子集(仅包含未完结事件)\n", + "def get_unfinished_events(memcube: dict):\n", + " return [event for event in memcube.get(\"event_chain\", []) if not event.get(\"if_completed\", False)]\n", + "\n", + "# ✅ 合并 GPT 结果到原人物 JSON\n", + "from copy import deepcopy\n", + "\n", + "def update_memcube_with_gpt_result(memcube: dict, updated_events: list):\n", + " new_memcube = deepcopy(memcube)\n", + " new_memcube[\"event_chain\"] = updated_events\n", + " return new_memcube\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "51c5ffd2", + "metadata": {}, + "outputs": [], + "source": [ + "from concurrent.futures import ThreadPoolExecutor, as_completed\n", + "\n", + "def update_memcube_for_character(name, memcube, content, chapter_id):\n", + " try:\n", + " unfinished = get_unfinished_events(memcube)\n", + " update_prompt = Prompt.update_character_prompt(name, unfinished, content)\n", + " update_result = api_client.call_api(update_prompt, \"update_character\", timeout=1800)\n", + "\n", + " raw = update_result.get(\"content\", \"\").strip(\"```json\").strip(\"```\").strip()\n", + " if not raw:\n", + " return name, None, \"空返回\"\n", + "\n", + " updated = json.loads(raw)\n", + " return name, updated, None\n", + "\n", + " except Exception as e:\n", + " return name, None, str(e)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fc828efc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "📖 正在处理:chapters/chapter1\n", + "🆕 新人物识别:龚光杰\n", + "🆕 新人物识别:褚师弟\n", + "🆕 新人物识别:左子穆\n", + "🆕 新人物识别:辛双清\n", + "🆕 新人物识别:段誉\n", + "🆕 新人物识别:马五德\n", + "🆕 新人物识别:钟灵\n", + "🆕 新人物识别:司空玄\n", + "\n", + "📖 正在处理:chapters/chapter2\n", + "🆕 新人物识别:干光豪\n", + "🆕 新人物识别:葛师妹\n", + "🆕 新人物识别:钟万仇\n", + "🆕 新人物识别:钟夫人\n", + "🆕 新人物识别:岳老二\n", + "🆕 新人物识别:来福儿\n", + "⚠️ 更新失败:辛双清 in chapters/chapter2 -> Extra data: line 107 column 1 (char 2233)\n", + "\n", + "📖 正在处理:chapters/chapter3\n", + "🆕 新人物识别:瑞婆婆\n", + "🆕 新人物识别:平婆婆\n", + "🆕 新人物识别:木婉清\n", + "\n", + "📖 正在处理:chapters/chapter4\n", + "🆕 新人物识别:南海鳄神\n", + "🆕 新人物识别:叶二娘\n", + "🆕 新人物识别:云中鹤\n", + "🆕 新人物识别:郁光标\n", + "🆕 新人物识别:吴光胜\n", + "\n", + "📖 正在处理:chapters/chapter5\n", + "🆕 新人物识别:褚万里\n", + "🆕 新人物识别:朱丹臣\n", + "🆕 新人物识别:古笃诚\n", + "🆕 新人物识别:傅思归\n", + "🆕 新人物识别:葛光佩\n", + "\n", + "📖 正在处理:chapters/chapter6\n", + "🆕 新人物识别:玉虚散人\n", + "🆕 新人物识别:段正淳\n", + "🆕 新人物识别:高升泰\n", + "🆕 新人物识别:段正明\n", + "🆕 新人物识别:秦红棉\n", + "\n", + "📖 正在处理:chapters/chapter7\n", + "🆕 新人物识别:恶贯满盈\n", + "⚠️ 更新失败:叶二娘 in chapters/chapter7 -> Invalid control character at: line 18 column 51 (char 516)\n", + "⚠️ 更新失败:云中鹤 in chapters/chapter7 -> Invalid control character at: line 28 column 10 (char 664)\n", + "\n", + "📖 正在处理:chapters/chapter8\n", + "🆕 新人物识别:镇南王妃刀白凤\n", + "🆕 新人物识别:保定帝段正明\n", + "🆕 新人物识别:巴天石\n", + "🆕 新人物识别:华赫艮\n", + "🆕 新人物识别:范骅\n", + "🆕 新人物识别:黄眉僧\n", + "🆕 新人物识别:司空见惯\n", + "🆕 新人物识别:巴司空\n", + "\n", + "📖 正在处理:chapters/chapter9\n", + "🆕 新人物识别:刀白凤\n", + "🆕 新人物识别:岳老三\n", + "🆕 新人物识别:郭光豪\n", + "🆕 新人物识别:段郎的父亲\n", + "🆕 新人物识别:段延庆\n", + "🆕 新人物识别:高善\n", + "🆕 新人物识别:宁次客\n", + "🆕 新人物识别:孟辰\n", + "🆕 新人物识别:大理段氏子孙\n", + "🆕 新人物识别:段芳\n", + "🆕 新人物识别:佛爷\n", + "🆕 新人物识别:幽谷主\n", + "🆕 新人物识别:慧真\n", + "🆕 新人物识别:慧真和尚\n", + "🆕 新人物识别:崔百泉\n", + "🆕 新人物识别:过彦之\n", + "🆕 新人物识别:柯百岁\n", + "🆕 新人物识别:平婆\n", + "🆕 新人物识别:岳老\n", + "🆕 新人物识别:段皇兄\n", + "🆕 新人物识别:何师\n", + "🆕 新人物识别:毛小拳\n", + "🆕 新人物识别:皇太弟\n", + "🆕 新人物识别:张三\n", + "🆕 新人物识别:蔡庆图\n", + "🆕 新人物识别:梁少爷\n", + "🆕 新人物识别:圆一大\n", + "🆕 新人物识别:少奶\n", + "🆕 新人物识别:老太爷\n", + "🆕 新人物识别:进士\n", + "🆕 新人物识别:李记\n", + "🆕 新人物识别:李姑\n", + "🆕 新人物识别:老怪\n", + "\n", + "📖 正在处理:chapters/chapter10\n", + "🆕 新人物识别:慧观\n", + "🆕 新人物识别:延庆太子\n", + "🆕 新人物识别:枯荣大师\n", + "🆕 新人物识别:大轮明王鸠摩智\n", + "🆕 新人物识别:本因大师\n", + "🆕 新人物识别:本观大师\n", + "🆕 新人物识别:本相大师\n", + "🆕 新人物识别:本参大师\n", + "🆕 新人物识别:星宿老人丁春秋\n", + "🆕 新人物识别:慕容博\n", + "🆕 新人物识别:六脉神剑\n", + "🆕 新人物识别:无影\n", + "\n", + "📖 正在处理:chapters/chapter11\n", + "🆕 新人物识别:鸠摩智\n", + "🆕 新人物识别:阿碧\n", + "🆕 新人物识别:阿朱\n" + ] + } + ], + "source": [ + "def get_unfinished_events(memcube: dict):\n", + " return [event for event in memcube.get(\"events\", []) if not event.get(\"if_completed\", False)]\n", + "\n", + "def init_memcube(character_name: str, chunk_id: str):\n", + " return {\n", + " \"name\": character_name,\n", + " \"first_appearance\": chunk_id,\n", + " \"aliases\": [character_name],\n", + " \"events\": [],\n", + " \"utterances\": [],\n", + " \"speech_style\": \"\",\n", + " \"personality_traits\": [],\n", + " \"emotion_state\": \"\",\n", + " \"relations\": []\n", + " }\n", + "\n", + "def merge_events(old_events: list, new_events: list):\n", + " \"\"\"合并事件:新事件覆盖旧事件;若旧事件被更新(如状态变为已完成),则同步更新\"\"\"\n", + " event_dict = {e[\"event_id\"]: e for e in old_events}\n", + "\n", + " for new_event in new_events:\n", + " eid = new_event[\"event_id\"]\n", + " if eid in event_dict:\n", + " # 合并逻辑:新字段优先,保留 event_id\n", + " merged = event_dict[eid].copy()\n", + " for key, value in new_event.items():\n", + " if value not in [None, \"\", []]:\n", + " merged[key] = value\n", + " event_dict[eid] = merged\n", + " else:\n", + " event_dict[eid] = new_event # 新事件直接加入\n", + "\n", + " return list(event_dict.values())\n", + "\n", + "def merge_unique_list(old: list, new: list):\n", + " \"\"\"合并两个列表并去重,保持原有顺序\"\"\"\n", + " combined = old + new\n", + " seen = set()\n", + " result = []\n", + " for item in combined:\n", + " if isinstance(item, dict):\n", + " key = json.dumps(item, sort_keys=True, ensure_ascii=False)\n", + " else:\n", + " key = str(item)\n", + " if key not in seen:\n", + " seen.add(key)\n", + " result.append(item)\n", + " return result\n", + "\n", + "memcubes = {}\n", + "alias_to_name = {}\n", + "chapter_folder = \"chapters\"\n", + "\n", + "chapter_files = sorted(\n", + " [os.path.join(chapter_folder, f) for f in os.listdir(chapter_folder) if f.startswith(\"chapter\") and f.endswith(\".txt\")],\n", + " key=lambda x: int(re.search(r'chapter(\\d+)', x).group(1))\n", + ")\n", + "\n", + "for chapter_file in chapter_files:\n", + " chapter_id = chapter_file.replace(\".txt\", \"\")\n", + " print(f\"\\n📖 正在处理:{chapter_id}\")\n", + "\n", + " with open(chapter_file, \"r\", encoding=\"utf-8\") as f:\n", + " content = f.read()\n", + "\n", + " name_prompt = Prompt.extract_character_names_prompt(content, alias_to_name)\n", + " name_result = api_client.call_api(name_prompt, \"name_extraction\", timeout=1800)\n", + " try:\n", + " extracted = json.loads(name_result.get(\"content\", \"\").strip(\"```json\").strip(\"```\").strip())\n", + " except:\n", + " extracted = []\n", + "\n", + " # alias 映射表(可用于后续处理)\n", + " \n", + "\n", + " # 🧱 Step 2: 初始化人物\n", + " for item in extracted:\n", + " std_name = item[\"name\"]\n", + " aliases = item.get(\"aliases\", [])\n", + " \n", + " # 初始化 memcube\n", + " if std_name not in memcubes:\n", + " print(f\"🆕 新人物识别:{std_name}\")\n", + " memcubes[std_name] = init_memcube(std_name, chapter_id)\n", + " memcubes[std_name][\"aliases\"] = [] # 初始化 alias 列表\n", + "\n", + " # 更新 alias\n", + " all_aliases = list(set(memcubes[std_name].get(\"aliases\", []) + aliases))\n", + " memcubes[std_name][\"aliases\"] = all_aliases\n", + "\n", + " # 构建 alias 到标准名的映射\n", + " for alias in [std_name] + aliases:\n", + " alias_to_name[alias] = std_name\n", + "\n", + " # 🔄 Step 3: 更新人物状态\n", + " with ThreadPoolExecutor(max_workers=8) as executor:\n", + " futures = {\n", + " executor.submit(update_memcube_for_character, name, memcube, content, chapter_id): name\n", + " for name, memcube in memcubes.items()\n", + " }\n", + "\n", + " for future in as_completed(futures):\n", + " name = futures[future]\n", + " try:\n", + " name, updated, error = future.result()\n", + " if error or not updated:\n", + " print(f\"⚠️ 更新失败:{name} in {chapter_id} -> {error}\")\n", + " continue\n", + "\n", + " memcube = memcubes[name]\n", + " memcube[\"events\"] = merge_events(memcube[\"events\"], updated.get(\"events\", []))\n", + " memcube[\"utterances\"].extend(updated.get(\"utterances\", []))\n", + " if updated.get(\"speech_style\"):\n", + " memcube[\"speech_style\"] = updated[\"speech_style\"]\n", + " memcube[\"personality_traits\"] = merge_unique_list(\n", + " memcube[\"personality_traits\"], updated.get(\"personality_traits\", [])\n", + " )\n", + " if updated.get(\"emotion_state\"):\n", + " memcube[\"emotion_state\"] = updated[\"emotion_state\"]\n", + " memcube[\"relations\"].extend(updated.get(\"relations\", []))\n", + "\n", + " except Exception as e:\n", + " print(f\"⚠️ 并行执行异常:{name} -> {e}\")\n", + "\n", + "# 💾 保存最终 memcubes\n", + "with open(\"memcubes_all.json\", \"w\", encoding=\"utf-8\") as f:\n", + " json.dump(memcubes, f, ensure_ascii=False, indent=2)\n", + "\n", + "print(\"\\n✅ 所有章节处理完成,总人物数:\", len(memcubes))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "54b947c1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "剑湖宫中,秋风渐起,树影婆娑。无量山难得的热闹一如既往,宗门弟子已集结于练武厅,东宗与西宗的比剑厮杀,一如锁定七龙珠般的高潮。然而,众人等待的席间却少了段誉这妙人,与平日相比,情势似乎少了些意外的光彩。\n", + "\n", + "褚师弟站在剑湖宫练武厅的中央,感受到众多观战者的目光投射。比武的剑光交错,龚师兄在他身侧气势如虹,剑招犹如急风骤雨,每一击都使得褚师弟心头微颤。他明白此战若败,剑湖宫五年的权力只能由东宗继续掌握。对龚师兄的自信与得意,褚师弟心生怨恨,但他仍在心中默默维护着剑术的尊严。\n", + "\n", + "左子穆轻拍衣袖,面色如常,然而隐藏的怒意依然在心中起伏。原本提议于段誉的比试成了泡影,东宗的龚师兄以玲珑的步法获胜,让无量剑西宗的实力稍显暗淡。左子穆坚毅如斯,暗暗记住了辛师妹的眼中鄙意,心底之火无法压制。\n", + "\n", + "辛师妹在一旁笑声轻蔑,无量玉壁的钻研成果隐隐显现,她对左子穆的腹中有话虽未细表,但东宗下一次比武必然有意。她的弟子褚师弟落败,却仍不失继续努力的决心。\n", + "\n", + "而钟灵则坐在梁柱上,手中把玩着一只闪电貂,目光逼向龚师兄,她的心里有些难以言表的好奇,但转瞬被无量剑的比试吸引住。神农帮未曾在此时出现,练武厅依然是无量剑的主场。但心底明白,她用灵巧身姿也不愿在比武大会上独自一人做主角。\n", + "\n", + "正因段誉未至,习惯于斗剑的马五德继续专注于观战。无量剑的两派竞争虽不免激烈,但并未爆发更多的意外事件。左子穆观战之际,让龚师兄不经意间偷瞄见繁星闪烁,心下虽有些瑕疵,东宗却继续处于优势。\n", + "\n", + "夜幕降临,无量山上剑影依稀,霜寒蓄积,江湖的慷慨和剑湖宫依然如故。在宗派斗争繁琐而复杂的面前,剑湖宫并无段誉的幽默与趣谈,或许明朝霞起,剑湖宫上将卷起另一番风波。\n" + ] + } + ], + "source": [ + "with open(\"memcubes1.json\", \"r\", encoding=\"utf-8\") as f:\n", + " memcubes = json.load(f)\n", + "\n", + "character_name = \"段誉\"\n", + "user_input = \"如果段誉没有出现在剑湖宫比武大会,事情会怎样?\"\n", + "\n", + "# 构造 prompt\n", + "prompt = Prompt.speculate_event_outcome(character_name, memcubes, user_input)\n", + "\n", + "# 调 GPT\n", + "response = api_client.call_api(prompt, \"speculative_story\")\n", + "print(response.get(\"content\", \"❌ 没有返回\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "571895a4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'段誉': {'name': '段誉',\n", + " 'first_appearance': 'chapters/chapter1',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '段誉在杏子林遭遇丐帮内乱后西夏来犯',\n", + " 'if_completed': True,\n", + " 'action': ['试图说服乔峰留下', '与王语嫣交流并保护她', '用六脉神剑击退努儿海', '实施凌波微步逃脱'],\n", + " 'motivation': ['保护王语嫣不受伤害', '不愿和丐帮直接冲突'],\n", + " 'involved_entities': ['乔峰', '王语嫣', '西夏武士', '努儿海', '丐帮'],\n", + " 'impact': ['与丐帮的关系变得复杂', '帮助乔峰及王语嫣避险', '自身武功暴露给西夏'],\n", + " 'utterances': [{'event_id': 'event_003', 'text': '大哥,大哥,我随你去!'},\n", + " {'event_id': 'event_003', 'text': '王姑娘,你们要到那里去?'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['谨慎', '善良', '机智'],\n", + " 'emotion_state': '混乱但镇定',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '结拜兄弟',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:结义, impact:共同进退'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.75,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:保护, impact:避免受伤'},\n", + " {'target': '阿朱',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': '共同目击事件,互相协作'},\n", + " {'target': '阿碧',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': '共同目击事件,互相协作'}]},\n", + " {'event_id': 'event_004',\n", + " 'time': '第十七章',\n", + " 'location': '桑树林与碾坊',\n", + " 'event': '段誉护送中毒的王语嫣并与西夏武士对抗',\n", + " 'if_completed': False,\n", + " 'action': ['安慰王语嫣并保护', '寻找避雨处', '误入碾坊后对抗西夏武士', '使用凌波微步和六脉神剑击退武士'],\n", + " 'motivation': ['保护王语嫣的安全', '自我防卫'],\n", + " 'involved_entities': ['王语嫣', '西夏武士', '农家青年男女'],\n", + " 'impact': ['与王语嫣关系进一步加深', '暴露自己的武功和内力', '导致农家青年男女因误解而遇害'],\n", + " 'utterances': [{'event_id': 'event_004', 'text': '王姑娘,你觉得怎样?'},\n", + " {'event_id': 'event_004', 'text': '敌人追来啦!'},\n", + " {'event_id': 'event_004', 'text': '我不想再杀人了!'},\n", + " {'event_id': 'event_004', 'text': '在下无能,不克护送姑娘回府,实深惭愧。'},\n", + " {'event_id': 'event_004', 'text': '到那里去?我陪你同去。'}],\n", + " 'speech_style': '直接且略带幽默',\n", + " 'personality_traits': ['善良', '有责任感', '冲动'],\n", + " 'emotion_state': '坚定中的焦虑',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:保护, impact:避免急险'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '龚光杰': {'name': '龚光杰',\n", + " 'first_appearance': 'chapters/chapter1',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '大雨刷刷声音之际',\n", + " 'location': '碾坊',\n", + " 'event': '段誉与王语嫣被西夏武士围攻',\n", + " 'if_completed': True,\n", + " 'action': ['使用凌波微步闪避敌人攻击', '与王语嫣合作击杀西夏武士', '面对李延宗的挑战并最终被他放过'],\n", + " 'motivation': ['保护王语嫣', '不愿杀戮,但被迫自卫'],\n", + " 'involved_entities': ['王语嫣', '西夏武士', '李延宗'],\n", + " 'impact': ['杀死多名西夏武士', '保护了王语嫣,但心情复杂'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'content': '我不想杀人!要我再杀人,那可下不了手啦,你们快快走吧!'},\n", + " {'event_id': 'event_001', 'content': '王姑娘,这一生一世,我是永远永远不会对你生气的。'}],\n", + " 'speech_style': '坦诚而随意',\n", + " 'personality_traits': ['善良', '不愿杀戮', '多情'],\n", + " 'emotion_state': '关心与紧张后放松',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:保护, impact:成功脱险'},\n", + " {'target': '李延宗',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:交手, impact:不敌但对方放过'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '褚师弟': {'name': '褚师弟',\n", + " 'first_appearance': 'chapters/chapter1',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十七章',\n", + " 'location': '桑树林',\n", + " 'event': '逃亡保护',\n", + " 'if_completed': False,\n", + " 'action': ['发现王语嫣中毒', '为王语嫣遮风避雨', '想到为王语嫣而死'],\n", + " 'motivation': ['保护王语嫣', '履行承诺'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士'],\n", + " 'impact': ['段誉增加了对王语嫣的感情', '设法暂时避开西夏武士的追赶'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'content': '这一生一世,我是永远永远不会对你生气的。'}],\n", + " 'speech_style': '诚挚',\n", + " 'personality_traits': ['保护他人', '循规学习'],\n", + " 'emotion_state': '心中难过,保护欲强',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:保护, impact:情感加深'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '十数分钟后',\n", + " 'location': '大碾坊',\n", + " 'event': '战斗与危机处理',\n", + " 'if_completed': True,\n", + " 'action': ['与西夏武士战斗', '致使西夏多人伤亡', '因灾难而解救一对农家青年', '用六脉神剑自卫并无意击杀'],\n", + " 'motivation': ['继续保护王语嫣', '自保'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士', '一对农家青年'],\n", + " 'impact': ['段誉因此成就了武斗技巧(凌波微步)', '对农家青年间接引发危机'],\n", + " 'utterances': [{'event_id': 'event_002',\n", + " 'content': '我不想再杀人了!要我再杀人,那可下不了手啦。'}],\n", + " 'speech_style': '歉然',\n", + " 'personality_traits': ['受困犹勇', '富有同情心'],\n", + " 'emotion_state': '惶恐不安,兼感愧疚',\n", + " 'relations': [{'target': '西夏武士',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:战斗, impact:多人死亡'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '之后',\n", + " 'location': '无锡途中',\n", + " 'event': '与王语嫣的对话',\n", + " 'if_completed': False,\n", + " 'action': ['与王语嫣谈话', '未能显露对王语嫣更深情感'],\n", + " 'motivation': ['与她保持关系'],\n", + " 'involved_entities': ['段誉', '王语嫣'],\n", + " 'impact': ['增进了对王语嫣的理解', '确认王语嫣心有所属'],\n", + " 'utterances': [{'event_id': 'event_003',\n", + " 'content': '永如眼前一般,那就心满意足,别无他求了。'}],\n", + " 'speech_style': '诚挚',\n", + " 'personality_traits': ['痴情', '顾全大局'],\n", + " 'emotion_state': '情感受伤,仍旧坚毅',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:谈话, impact:关系稳定'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '龚师兄': {'name': '龚师兄',\n", + " 'first_appearance': 'chapters/chapter1',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十七章,今日意',\n", + " 'location': '碾坊',\n", + " 'event': '保护王语嫣脱险',\n", + " 'if_completed': True,\n", + " 'action': ['与段誉共同对抗西夏武士', '给予段誉指导击败敌人', '指挥段誉用六脉神剑自卫'],\n", + " 'motivation': ['保护心爱之人', '不让王语嫣受到伤害'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士'],\n", + " 'impact': ['段誉成功逃脱敌人包围', '段誉增强了对王语嫣的情意'],\n", + " 'utterances': [{'event': 'event_001',\n", + " 'text': '你打他不过的,认了输吧。',\n", + " 'timestamp': '在碾坊战斗中'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['冷静', '勇敢'],\n", + " 'emotion_state': '专注',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 1,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:保护王语嫣, motivation:不让王语嫣受到伤害'},\n", + " {'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:与段誉共同对抗西夏武士, impact:段誉增强了对王语嫣的情意'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '在碾坊中',\n", + " 'location': '碾坊',\n", + " 'event': '与李延宗对峙',\n", + " 'if_completed': True,\n", + " 'action': ['识别李延宗的多种武功技法', '言辞激励李延宗'],\n", + " 'motivation': ['为段誉争取时间', '测试李延宗的武功'],\n", + " 'involved_entities': ['李延宗', '段誉'],\n", + " 'impact': ['李延宗撤退', '提升对于江湖武功见识的界限'],\n", + " 'utterances': [{'event': 'event_002',\n", + " 'text': '你使激将之计,要我饶他性命,嘿嘿,我李延宗是何等样人。',\n", + " 'timestamp': '与李延宗对峙时'}],\n", + " 'speech_style': '讽刺',\n", + " 'personality_traits': ['聪慧', '机智'],\n", + " 'emotion_state': '冷静',\n", + " 'relations': [{'target': '李延宗',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.7,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:言辞激励李延宗, impact:李延宗撤退'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '辛师妹': {'name': '辛师妹',\n", + " 'first_appearance': 'chapters/chapter1',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '在大雨中,与段誉逃亡的途中',\n", + " 'location': '碾坊',\n", + " 'event': '中毒后避雨并遭遇西夏武士',\n", + " 'if_completed': True,\n", + " 'action': ['请求段誉保护', '与农女换衣', '从碾坊阁楼观察形势', '指点段誉如何应对武士'],\n", + " 'motivation': ['生存', '躲避追兵', '帮助段誉'],\n", + " 'involved_entities': ['段誉', '西夏武士', '农女', '农家青年'],\n", + " 'impact': ['指点段誉杀死多名西夏武士'],\n", + " 'utterances': [{'time': 'event_001', 'content': '请你过来。'},\n", + " {'time': 'event_001', 'content': '这金钗真的送了给你。'},\n", + " {'time': 'event_001', 'content': '你点他的小腹‘下脘穴’。'}],\n", + " 'speech_style': '文雅',\n", + " 'personality_traits': ['聪明', '沉着'],\n", + " 'emotion_state': '镇定',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:协同逃命与战斗'},\n", + " {'target': '慕容复',\n", + " 'relation_type': '亲属',\n", + " 'relation_strength': 1.0,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'motivation:寻找, impact:指点段誉'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '左师兄': {'name': '左师兄',\n", + " 'first_appearance': 'chapters/chapter1',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '夜间,天已全黑',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内部叛乱清理',\n", + " 'if_completed': True,\n", + " 'action': ['参与商讨如何处置叛乱', '观察各长老与弟子的反应', '待人处事平和,避免内战'],\n", + " 'motivation': ['维护丐帮的正义与秩序', '确保帮内忠诚', '避免无谓的内耗与惨剧'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长老',\n", + " '白世镜',\n", + " '刘竹庄',\n", + " '宋奚陈吴四长老',\n", + " '徐长老',\n", + " '智光大师',\n", + " '赵钱孙',\n", + " '马夫人'],\n", + " 'impact': ['对丐帮内的忠诚和秩序进行清理', '促使乔峰处理事件并对人物关系进行稳定', '预防部分帮众间的冲突升级'],\n", + " 'utterances': [{'time': 'event_001',\n", + " 'content': '咱们丐帮自居为江湖第一大帮,乔帮主待人仁义,处事么允,咱们大伙儿拥戴尚自不及,为什么居然有人猪油蒙了心,意会起意叛乱?'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['忠诚', '善良', '理智'],\n", + " 'emotion_state': '担忧',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '帮主',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:支持乔峰, impact:维护帮规与丐帮稳定'},\n", + " {'target': '吴长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:观察反应, impact:关注丐帮长老的动向'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '夜间,丐帮与西夏一品堂商谈',\n", + " 'location': '杏子林外',\n", + " 'event': '与西夏一品堂的会面交涉',\n", + " 'if_completed': False,\n", + " 'action': ['参与迎接与处理西夏来客', '站在乔峰一边,抵制西夏的挑衅'],\n", + " 'motivation': ['维护丐帮与外界的关系', '保护丐帮的威信与安危'],\n", + " 'involved_entities': ['乔峰', '徐长老', '白世镜', '吴长老', '西夏一品堂', '赫连铁树'],\n", + " 'impact': ['帮助应对西夏一品堂的挑衅与威胁', '维持丐帮与外界的良好关系'],\n", + " 'utterances': [],\n", + " 'speech_style': '古典',\n", + " 'personality_traits': ['机智', '稳重'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '徐长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:合作应对外敌, impact:稳固丐帮外部关系'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '左子穆': {'name': '左子穆',\n", + " 'first_appearance': 'chapters/chapter1',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十七章',\n", + " 'location': '桑树林和碾坊附近',\n", + " 'event': '遭遇西夏武士追杀',\n", + " 'if_completed': False,\n", + " 'action': ['保护王语嫣', '与段誉一道逃离追兵', '观察和分析段誉的战斗', '对战局提供关键指导'],\n", + " 'motivation': ['求生', '保护王语嫣', '帮助段誉'],\n", + " 'involved_entities': ['段誉', '西夏武士', '碾坊里的农家青年'],\n", + " 'impact': ['段誉发挥出潜在武功', '王语嫣感受到了段誉的保护', '西夏武士多人被杀']},\n", + " {'event_id': 'event_002',\n", + " 'time': '离开碾坊后',\n", + " 'location': '前往无锡的路上',\n", + " 'event': '与段誉前往无锡打探消息',\n", + " 'if_completed': False,\n", + " 'action': ['讨论未来计划', '决定救阿朱和阿碧', '骑马前往无锡'],\n", + " 'motivation': ['寻找解毒方法和帮助丐帮', '营救慕容复的婢女'],\n", + " 'involved_entities': ['段誉', '阿朱和阿碧(计划中的救援对象)'],\n", + " 'impact': ['与段誉的关系进一步发展', '计划关注丐帮的情况']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '双清': {'name': '双清',\n", + " 'first_appearance': 'chapters/chapter1',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十七章',\n", + " 'location': '桑树林',\n", + " 'event': '保护受伤的王语嫣',\n", + " 'if_completed': False,\n", + " 'action': ['与段誉共骑', '逃避西夏武士', '寻找安全地点'],\n", + " 'motivation': ['保护王语嫣不受伤害'],\n", + " 'involved_entities': ['段誉', '西夏武士', '王语嫣'],\n", + " 'impact': ['帮助王语嫣暂时避开追兵'],\n", + " 'utterances': [{'timestamp': 'event_001', 'content': '你觉得怎样?'}],\n", + " 'speech_style': '谨慎',\n", + " 'personality_traits': ['保护他人'],\n", + " 'emotion_state': '担忧',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:协助逃亡, impact:保护'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十七章',\n", + " 'location': '破败的碾坊',\n", + " 'event': '与西夏武士交战',\n", + " 'if_completed': True,\n", + " 'action': ['协助段誉击败西夏武士', '使用‘悲酥清风’解药'],\n", + " 'motivation': ['确保自身安全', '帮助段誉'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士', '农家青年'],\n", + " 'impact': ['共同击败敌人', '解决王语嫣中毒问题'],\n", + " 'utterances': [{'timestamp': 'event_002', 'content': '你去攻他个措手不及。'},\n", + " {'timestamp': 'event_002', 'content': '我曾闻其名,只是瞧不清楚。'}],\n", + " 'speech_style': '冷静分析',\n", + " 'personality_traits': ['智慧', '机智'],\n", + " 'emotion_state': '镇定',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:相互策应, impact:击败敌人'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '马五德': {'name': '马五德',\n", + " 'first_appearance': 'chapters/chapter1',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '小说第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '参与丐帮会面和揭露契丹身份',\n", + " 'if_completed': True,\n", + " 'action': ['参与丐帮会面', '保护智光大师', '反驳马夫人', '对抗西夏国武士', '辞去丐帮帮主职务'],\n", + " 'motivation': ['澄清自己的契丹身份', '维护个人声誉', '保护丐帮名声与权力结构'],\n", + " 'involved_entities': ['智光大师', '赵钱孙', '徐长老', '单氏五虎', '丐帮众人'],\n", + " 'impact': ['暂时性放弃了丐帮帮主职位', '引起丐帮内部对个人身份的质疑', '促成西夏国与丐帮的冲突']},\n", + " {'event_id': 'event_002',\n", + " 'time': '小说第十七章',\n", + " 'location': '桑树林',\n", + " 'event': '跟随段誉保护王语嫣',\n", + " 'if_completed': False,\n", + " 'action': ['与段誉同行找寻避雨之地', '推进局势避免更大损害', '与西夏武士对峙'],\n", + " 'motivation': ['保证王语嫣的安全', '寻求与西夏人交涉的机会'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士'],\n", + " 'impact': ['与段誉及王语嫣的关系加深', '协助保护王语嫣不被西夏人伤害'],\n", + " 'utterances': ['event_002: 保证王语嫣的安全'],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['勇敢', '善良'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action: 与段誉同行, impact: 与段誉及王语嫣的关系加深'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '同道',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'impact: 协助保护王语嫣不被西夏人伤害'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '容子矩': {'name': '容子矩',\n", + " 'first_appearance': 'chapters/chapter1',\n", + " 'events': [{'event_id': 'event_002',\n", + " 'time': '三十余年后,近期',\n", + " 'location': '杏树林',\n", + " 'event': '回忆事件引发乔峰身份曝光',\n", + " 'if_completed': True,\n", + " 'action': ['回忆往事', '向丐帮众人叙述真相', '促成丐帮乔峰身份危机'],\n", + " 'motivation': ['希望化解仇恨', '觉悟和忏悔'],\n", + " 'involved_entities': ['乔峰', '丐帮众长老', '赵钱孙'],\n", + " 'impact': ['改变丐帮对乔峰的态度', '引发身份危机'],\n", + " 'utterances': [{'event_id': 'event_002',\n", + " 'text': '我智光在武林中只是个无名小卒,做错了事,不算什么,但带头大哥和汪帮主是何等的身份地位?何况汪帮主已然逝世,我可不能胡乱损及他二位的声名,请恕我不能明言。'}],\n", + " 'speech_style': '坦白',\n", + " 'personality_traits': ['忏悔', '真诚'],\n", + " 'emotion_state': '内疚',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '恩仇',\n", + " 'relation_strength': -0.3,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:揭露真相, impact:身份危机'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '同一时期',\n", + " 'location': '碾坊',\n", + " 'event': '与西夏武士对峙',\n", + " 'if_completed': True,\n", + " 'action': ['观察西夏武士杀戮', '意识到自己被误杀无辜', '表示歉意', '计划掩埋死者'],\n", + " 'motivation': ['希望减少伤害', '悔恨与责任感'],\n", + " 'involved_entities': ['段誉', '王语嫣', '李延宗', '西夏武士', '农家青年'],\n", + " 'impact': ['西夏武士被误杀', '段誉情绪波动', '对武林事件有更大责任意识'],\n", + " 'utterances': [{'event_id': 'event_003',\n", + " 'text': '我若不杀老兄,老兄便杀了我。那时候躺在这里的,就不是老兄而是段誉了。在下无可奈何,但心中实在歉仄之至。'}],\n", + " 'speech_style': '悔意与坦率',\n", + " 'personality_traits': ['仁慈', '二者择其轻'],\n", + " 'emotion_state': '悔恨与忧虑',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:帮助逃生, impact:感情提升'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '意图帮衬',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:旁观, impact:共享敌情'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '钟灵': {'name': '钟灵',\n", + " 'first_appearance': 'chapters/chapter1',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '两人共骑,奔跑一阵',\n", + " 'location': '桑树林',\n", + " 'event': '逃离追兵',\n", + " 'if_completed': True,\n", + " 'action': ['共骑马逃跑', '段誉照顾王语嫣', '寻求安全地点'],\n", + " 'motivation': ['保护王语嫣', '逃离西夏武士的追击'],\n", + " 'involved_entities': ['段誉', '西夏武士', '王语嫣'],\n", + " 'impact': ['成功逃脱追兵,暂时安全']},\n", + " {'event_id': 'event_002',\n", + " 'time': '下起雨来',\n", + " 'location': '大碾坊',\n", + " 'event': '避雨遇见农家情侣',\n", + " 'if_completed': True,\n", + " 'action': ['进入碾坊避雨', '与农家情侣相遇', '替王语嫣换衣'],\n", + " 'motivation': ['避免淋雨', '保护王语嫣健康'],\n", + " 'involved_entities': ['段誉', '王语嫣', '农家情侣'],\n", + " 'impact': ['王语嫣在碾坊换上干衣,避免风寒']},\n", + " {'event_id': 'event_003',\n", + " 'time': '王语嫣道:“你肚痛么?发烧么?头痛么?”',\n", + " 'location': '大碾坊',\n", + " 'event': '西夏武士追踪至碾坊',\n", + " 'if_completed': True,\n", + " 'action': ['利用六脉神剑反击', '保护王语嫣免受攻击'],\n", + " 'motivation': ['保护王语嫣', '保全自身性命'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士'],\n", + " 'impact': ['杀死西夏武士,逃脱险境']},\n", + " {'event_id': 'event_004',\n", + " 'time': '马蹄声音,十余骑向着碾坊急奔而来',\n", + " 'location': '大碾坊',\n", + " 'event': '段誉与西夏武士激战',\n", + " 'if_completed': True,\n", + " 'action': ['用凌波微步躲避攻击', '使用毒药解王语嫣之毒'],\n", + " 'motivation': ['保护王语嫣', '消除威胁'],\n", + " 'involved_entities': ['段誉', '西夏武士'],\n", + " 'impact': ['段誉独自于敌众中全身而退,成功解毒']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '司空玄': {'name': '司空玄',\n", + " 'first_appearance': 'chapters/chapter1',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '当天不久,当王语嫣中毒并与段誉逃亡时',\n", + " 'location': '桑树林中及随后进入的碾坊',\n", + " 'event': '西夏武士追捕王语嫣',\n", + " 'if_completed': False,\n", + " 'action': ['司空玄可能对西夏武士的行动进行观察或帮助', '参与对王语嫣的救援或提供指导'],\n", + " 'motivation': ['确保王语嫣的安全', '帮助或结交段誉和王语嫣'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士', '农家青年与农女'],\n", + " 'impact': ['帮助段誉击退或避开西夏武士的攻击'],\n", + " 'utterances': [],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['善良', '冷静'],\n", + " 'emotion_state': '担忧',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'motivation:确保王语嫣的安全'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'motivation:确保王语嫣的安全'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '之后,在无锡城',\n", + " 'location': '无锡城',\n", + " 'event': '寻找解药与丐帮消息',\n", + " 'if_completed': False,\n", + " 'action': ['研究解药或提供策略', '帮助段誉和王语嫣制定计划'],\n", + " 'motivation': ['解决自己和他人的毒药问题', '加深与段誉和王语嫣的友情'],\n", + " 'involved_entities': ['段誉', '王语嫣', '丐帮成员'],\n", + " 'impact': ['为王语嫣和段誉提供有价值的见解或资源'],\n", + " 'utterances': [],\n", + " 'speech_style': '文雅',\n", + " 'personality_traits': ['冷静', '善良'],\n", + " 'emotion_state': '希望',\n", + " 'relations': [{'target': '丐帮成员',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:帮助'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '干光豪': {'name': '干光豪',\n", + " 'first_appearance': 'chapters/chapter2',\n", + " 'events': [{'event_id': 'event_004',\n", + " 'time': '潜入听香水榭',\n", + " 'location': '听香水榭内',\n", + " 'event': '调查屋内情况',\n", + " 'if_completed': False,\n", + " 'action': ['潜入', '观察', '听取段誉对自己的评价', '分析段誉的情绪状态'],\n", + " 'motivation': ['帮助阿朱', '查明敌人来意'],\n", + " 'involved_entities': ['段誉',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '阿碧',\n", + " '听香水榭内的各类人物',\n", + " '丐帮乔峰',\n", + " '风波恶'],\n", + " 'impact': ['提升了对段誉情绪状态的理解'],\n", + " 'utterances': [{'time_or_event': 'event_004',\n", + " 'content': '大哥,这几句话好生得体,果然是一帮之主的风度,倘若他和包三先生对发脾气,那便有失身份了。'}],\n", + " 'speech_style': '直白',\n", + " 'personality_traits': ['分析能力强', '谨慎'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': '0.5',\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:协助处理丐帮内变, impact:增加尊重'},\n", + " {'target': '段誉',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': '0.3',\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:观察分析段誉, impact:理解关系动态'}]},\n", + " {'event_id': 'event_012',\n", + " 'time': '无锡松鹤楼',\n", + " 'location': '无锡',\n", + " 'event': '观察乔峰与段誉交往',\n", + " 'if_completed': False,\n", + " 'action': ['观察', '分析段誉与乔峰关系', '参与分析包不同与乔峰的对峙'],\n", + " 'motivation': ['了解乔峰与段誉在江湖的关系', '获取对自身有利的情报'],\n", + " 'involved_entities': ['段誉', '乔峰', '包不同', '风波恶', '丐帮成员'],\n", + " 'impact': ['增进了对丐帮与姑苏慕容家关系的理解'],\n", + " 'utterances': [{'time_or_event': 'event_012', 'content': '真相到底如何?'}],\n", + " 'speech_style': '直白',\n", + " 'personality_traits': ['分析能力强', '谨慎'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': '0.5',\n", + " 'last_updated': 'event_012',\n", + " 'derived_from': 'action:协助处理丐帮内变, impact:增加尊重'},\n", + " {'target': '段誉',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': '0.3',\n", + " 'last_updated': 'event_012',\n", + " 'derived_from': 'action:观察分析段誉, impact:理解关系动态'}]},\n", + " {'event_id': 'event_013',\n", + " 'time': '杏子林夜间',\n", + " 'location': '杏子林',\n", + " 'event': '观摩丐帮内变',\n", + " 'if_completed': False,\n", + " 'action': ['暗中观察', '分析各派势力', '对比各方论述', '内心思考帮规', '关注乔峰处理危机'],\n", + " 'motivation': ['维持自身安全', '持续收集情报', '尊重乔峰的能力'],\n", + " 'involved_entities': ['乔峰',\n", + " '白世镜',\n", + " '宋长老',\n", + " '吴长风',\n", + " '陈长老',\n", + " '执法长老',\n", + " '全冠清',\n", + " '段誉',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '丐帮四长老'],\n", + " 'impact': ['增加了对乔峰的尊重', '提高了警惕', '确认了丐帮的复杂状况'],\n", + " 'utterances': [{'time_or_event': 'event_013',\n", + " 'content': '丐帮开帮数百年,在江湖上受人尊崇,并非恃了人多势众、武功高强,乃是由于行侠仗义、主持公道之故。'}],\n", + " 'speech_style': '直白',\n", + " 'personality_traits': ['分析能力强', '谨慎'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': '0.5',\n", + " 'last_updated': 'event_013',\n", + " 'derived_from': 'action:协助处理丐帮内变, impact:增加尊重'},\n", + " {'target': '段誉',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': '0.3',\n", + " 'last_updated': 'event_013',\n", + " 'derived_from': 'action:观察分析段誉, impact:理解关系动态'}]},\n", + " {'event_id': 'event_014',\n", + " 'time': '杏子林夜间',\n", + " 'location': '杏子林',\n", + " 'event': '目睹西夏一品堂挑战丐帮',\n", + " 'if_completed': False,\n", + " 'action': ['分析局面', '观察西夏一品堂与丐帮冲突', '考虑应对策略'],\n", + " 'motivation': ['评估各方实力', '保持局势发展洞察', '寻找自保的策略'],\n", + " 'involved_entities': ['西夏一品堂', '丐帮成员', '赫连铁树', '段誉'],\n", + " 'impact': ['意识到西夏对中原武林的威胁', '对丐帮局势更加清晰'],\n", + " 'utterances': [],\n", + " 'speech_style': '分析性',\n", + " 'personality_traits': ['冷静', '机敏'],\n", + " 'emotion_state': '警觉',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': '0.5',\n", + " 'last_updated': 'event_014',\n", + " 'derived_from': 'action:协助处理丐帮内变, impact:增加尊重'},\n", + " {'target': '段誉',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': '0.3',\n", + " 'last_updated': 'event_014',\n", + " 'derived_from': 'action:观察分析段誉, impact:理解关系动态'},\n", + " {'target': '西夏一品堂',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': '-0.5',\n", + " 'last_updated': 'event_014',\n", + " 'derived_from': 'action:目睹冲突, impact:意识到威胁'}]},\n", + " {'event_id': 'event_015',\n", + " 'time': '碾坊遭遇战',\n", + " 'location': '碾坊',\n", + " 'event': '与西夏武士战斗并逃脱',\n", + " 'if_completed': True,\n", + " 'action': ['保护王语嫣', '与西夏武士战斗', '使用凌波微步躲避攻击', '内心独白反思杀戮'],\n", + " 'motivation': ['保护王语嫣', '存活下去'],\n", + " 'involved_entities': ['段誉', '王语嫣', '李延宗', '西夏武士若干'],\n", + " 'impact': ['显现武功天赋,引来李延宗关注', '保护段誉和王语嫣成功逃脱', '挑战个人原则与武力边界'],\n", + " 'utterances': [{'time_or_event': 'event_015',\n", + " 'content': '我是无论如何打你不过的,你肯不肯就此罢休?'}],\n", + " 'speech_style': '诚恳',\n", + " 'personality_traits': ['仁慈', '忧虑'],\n", + " 'emotion_state': '惋惜',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': '0.7',\n", + " 'last_updated': 'event_015',\n", + " 'derived_from': 'action:保护王语嫣, impact:拯救与共'},\n", + " {'target': '李延宗',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': '-0.3',\n", + " 'last_updated': 'event_015',\n", + " 'derived_from': 'action:交战与相惜, impact:潜在敌手'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '葛师妹': {'name': '葛师妹',\n", + " 'first_appearance': 'chapters/chapter2',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十五章夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内乱商量平息',\n", + " 'if_completed': True,\n", + " 'action': ['观察丐帮内乱',\n", + " '分析乔峰与慕容复关系',\n", + " '注意到王语嫣对乔峰的态度',\n", + " '内心反思对王语嫣的情感对比赵钱孙与谭婆的关系'],\n", + " 'motivation': ['了解乔峰是否与慕容复真正有勾结', '探索丐帮内部纷争背后的真相'],\n", + " 'involved_entities': ['乔峰', '吴长老', '白世镜', '全冠清', '刘竹庄', '段誉', '王语嫣'],\n", + " 'impact': ['理解江湖中人与乔峰关系复杂', '思考自身与王语嫣的情感动态'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'utterance': '见乔峰平定逆乱,将反叛者一一制望,自是代他欢喜。'}],\n", + " 'speech_style': '分析性',\n", + " 'personality_traits': ['冷静', '内向'],\n", + " 'emotion_state': '复杂情感',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': '对乔峰事件的观察与思考'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': '情感比较与观察'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十六章夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '西夏一品堂对丐帮的威胁与威慑',\n", + " 'if_completed': True,\n", + " 'action': ['聆听并分析西夏一品堂强者与丐帮交锋', '注意到西夏用毒气陷丐帮全局', '观察段誉救王语嫣策略'],\n", + " 'motivation': ['获取对西夏一品堂武功门派的深入了解', '评估段誉与王语嫣之间的关系动向'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏一品堂', '奚长老', '徐长老'],\n", + " 'impact': ['为丐帮应对异国威胁提供新思路', '加强对江湖格局变化的理解'],\n", + " 'utterances': [{'event_id': 'event_002', 'utterance': '西夏一品堂横行江湖,不可小觑。'}],\n", + " 'speech_style': '分析性',\n", + " 'personality_traits': ['冷静', '内向'],\n", + " 'emotion_state': '复杂情感',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': '段誉与丐帮的互动观察'},\n", + " {'target': '西夏一品堂',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': '对丐帮的剥削与威胁'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '第十七章今日意',\n", + " 'location': '木磨房',\n", + " 'event': '段誉护送王语嫣逃避追杀',\n", + " 'if_completed': False,\n", + " 'action': ['与段誉共骑逃跑', '观察段誉与西夏武士战斗', '指导段誉使用六脉神剑', '逃避西夏武士的追杀'],\n", + " 'motivation': ['保护自己和段誉免受西夏武士伤害', '对段誉的保护行动感激'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士', '李延宗'],\n", + " 'impact': ['与段誉形成更加紧密的关系', '激发出段誉的武功潜力对敌'],\n", + " 'utterances': [{'event_id': 'event_003', 'utterance': '段公子,你将肩头的袖箭拔了去。'}],\n", + " 'speech_style': '分析性',\n", + " 'personality_traits': ['冷静', '聪慧'],\n", + " 'emotion_state': '复杂情感',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': '段誉保护事件'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': '情感交互与共患难'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '乔峰': {'name': '乔峰',\n", + " 'first_appearance': 'chapters/chapter2',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '第十四章',\n", + " 'location': '杏子林',\n", + " 'event': '介入丐帮与姑苏慕容冲突',\n", + " 'if_completed': True,\n", + " 'action': ['介入打斗,制止冲突', '主持公道,判断是非'],\n", + " 'motivation': ['维护丐帮的名誉和和谐', '查明真相,避免误会'],\n", + " 'involved_entities': ['包不同', '风波恶', '王语嫣', '阿朱', '阿碧', '丐帮成员'],\n", + " 'impact': ['缓解丐帮与姑苏慕容之间的紧张气氛', '展示了乔峰在武林中的强大影响力'],\n", + " 'utterances': [{'time': 'event_003',\n", + " 'content': ['两位请便吧。', '这里都是咱们多年来同生共死的好兄弟,只不过一时生了些意见,没什么大不了的事。']}],\n", + " 'speech_style': '果断温和',\n", + " 'personality_traits': ['沉着', '果断'],\n", + " 'emotion_state': '镇定',\n", + " 'relations': [{'target': '慕容复',\n", + " 'relation_type': '潜在敌对',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:介入冲突, impact:缓解慕容与丐帮的紧张'}]},\n", + " {'event_id': 'event_004',\n", + " 'time': '第十五章',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内部清理叛乱',\n", + " 'if_completed': True,\n", + " 'action': ['面对四大长老叛乱', '平定叛乱并宽恕四大长老', '揭露全冠清的诡计'],\n", + " 'motivation': ['维持丐帮的稳定和名誉', '依照帮规处理纷争'],\n", + " 'involved_entities': ['吴长风',\n", + " '宋长老',\n", + " '奚长老',\n", + " '陈长老',\n", + " '全冠清',\n", + " '传功长老',\n", + " '执法长老',\n", + " '丐帮众弟子'],\n", + " 'impact': ['内部叛乱被化解', '乔峰威望进一步提升', '涉及人物纷争的来龙去脉得到理清'],\n", + " 'utterances': [{'event_id': 'event_004',\n", + " 'content': ['大丈夫行事,对就是对,错就是错。', '人家说你这个那个,我再也不信了。']}],\n", + " 'speech_style': '坚定且宽容',\n", + " 'personality_traits': ['宽容', '坚定'],\n", + " 'emotion_state': '思虑重重',\n", + " 'relations': [{'target': '吴长风',\n", + " 'relation_type': '下属',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:赦免, impact:情感联结'},\n", + " {'target': '全冠清',\n", + " 'relation_type': '敌视',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:揭露背叛, impact:驱逐'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '盯紧丐帮帮主之位的争斗',\n", + " 'if_completed': True,\n", + " 'action': ['面对身世揭露', '放弃丐帮帮主之位'],\n", + " 'motivation': ['保全丐帮的名誉', '自己理清身世真相'],\n", + " 'involved_entities': ['徐长老', '白世镜', '宋长老', '全冠清', '马夫人', '赵钱孙'],\n", + " 'impact': ['丐帮陷入权力真空', '乔峰可能成为英雄或舍弃者,尚未有定论'],\n", + " 'utterances': [{'event_id': 'event_005',\n", + " 'content': ['我只道恩师汪帮主是有意锻炼于我,使我多历艰辛,以便担当大任,却原来……',\n", + " '有生之年,决不伤一条汉人的性命,若违此誓,有如此刀。']}],\n", + " 'speech_style': '坚毅且沮丧',\n", + " 'personality_traits': ['忠诚', '坚毅'],\n", + " 'emotion_state': '混乱与决绝',\n", + " 'relations': [{'target': '全冠清',\n", + " 'relation_type': '敌对',\n", + " 'relation_strength': -1,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'event:盯紧丐帮帮主之位的争斗,impact:丐帮内乱加深'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '段正淳': {'name': '段正淳',\n", + " 'first_appearance': 'chapters/chapter2',\n", + " 'events': [{'event_id': 'event_004',\n", + " 'time': '杏子林劣势对抗',\n", + " 'location': '杏子林',\n", + " 'event': '对抗西夏国一品堂',\n", + " 'if_completed': True,\n", + " 'action': ['协助丐帮准备对抗', '商讨行动策略'],\n", + " 'motivation': ['保护丐帮', '抵御外侵'],\n", + " 'involved_entities': ['赫连铁树', '努儿海', '西夏国一品堂成员'],\n", + " 'impact': ['面临敌方威胁,丐帮全体手足无措'],\n", + " 'utterances': [{'event_id': 'event_004', 'content': '', 'time': '对抗开始前'}],\n", + " 'speech_style': '分析性',\n", + " 'personality_traits': ['审慎', '聪慧'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '赫连铁树',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:准备对抗, impact:紧张局势'},\n", + " {'target': '努儿海',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:准备对抗, impact:紧张局势'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '与王语嫣共同逃离',\n", + " 'location': '桑树林附近及碾坊',\n", + " 'event': '困境中保护王语嫣',\n", + " 'if_completed': False,\n", + " 'action': ['保护王语嫣安全撤退', '与西夏武士对抗'],\n", + " 'motivation': ['保护王语嫣', '履行承诺'],\n", + " 'involved_entities': ['王语嫣', '西夏武士', '金阿二', '农女'],\n", + " 'impact': ['躲避西夏武士追杀', '启发王语嫣信任'],\n", + " 'utterances': [{'event_id': 'event_005',\n", + " 'content': '王姑娘,你觉得怎样?',\n", + " 'time': '碾坊避雨时'}],\n", + " 'speech_style': '诚恳',\n", + " 'personality_traits': ['仁慈', '忠诚'],\n", + " 'emotion_state': '坚定',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:保护, impact:安全感'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '钟夫人': {'name': '钟夫人',\n", + " 'first_appearance': 'chapters/chapter2',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十七章',\n", + " 'location': '桑树林及附近的碾坊',\n", + " 'event': '钟夫人协助段誉和王语嫣逃避西夏武士追杀',\n", + " 'if_completed': False,\n", + " 'action': ['示警段誉关于王语嫣中毒', '协助段誉寻找避雨之地', '促使段誉离开追兵转而保护王语嫣'],\n", + " 'motivation': ['保护家族成员', '维护情感羁绊'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士'],\n", + " 'impact': ['增进段誉与王语嫣之间的相互了解', '为段誉提供了责任感和勇气'],\n", + " 'utterances': [{'text': '你这人当真婆婆妈妈得紧。', 'time': 'event_001'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['冷静', '机警', '谨慎'],\n", + " 'emotion_state': '担忧',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:协助, impact:增进理解'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '亲属',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:保护, impact:维护情感羁绊'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '钟谷主': {'name': '钟谷主',\n", + " 'first_appearance': 'chapters/chapter2',\n", + " 'events': [{'event_id': 'event_008',\n", + " 'time': '第十五章 杏子林中 商略平生义',\n", + " 'location': '杏子林',\n", + " 'event': '目睹丐帮内乱及乔峰解决危机',\n", + " 'if_completed': True,\n", + " 'action': ['观察乔峰处理丐帮内乱', '倾听徐长老和其他武林人物的讲话', '分析丐帮内部和乔峰的地位', '目睹丐帮危机解决'],\n", + " 'motivation': ['评估乔峰在武林中的威信', '理解丐帮的影响力'],\n", + " 'involved_entities': ['乔峰', '白世镜', '全冠清', '徐长老', '谭公', '谭婆', '赵钱孙'],\n", + " 'impact': ['加深对乔峰作为丐帮帮主的理解', '对武林各大派的动向有更清晰的认识'],\n", + " 'utterances': [{'event': 'event_008',\n", + " 'content': '丐帮帮主乔峰果然非池中之物,震慑群雄。',\n", + " 'time': '观察乔峰时'}],\n", + " 'speech_style': '谨慎且分析性',\n", + " 'personality_traits': ['机智', '谨慎', '分析能力强'],\n", + " 'emotion_state': '惊叹',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '敬重对象',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_008',\n", + " 'derived_from': 'action:观察, impact:加强对情况的理解'},\n", + " {'target': '白世镜',\n", + " 'relation_type': '观察者',\n", + " 'relation_strength': 0.0,\n", + " 'last_updated': 'event_008',\n", + " 'derived_from': 'action:观察, impact:了解其立场'}]},\n", + " {'event_id': 'event_009',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '见证智光大师的证词及乔峰的身份揭露',\n", + " 'if_completed': False,\n", + " 'action': ['倾听智光大师讲述乔峰的身世', '观望各方反应', '分析可能对武林秩序的影响'],\n", + " 'motivation': ['了解乔峰真实身份对丐帮的潜在影响'],\n", + " 'involved_entities': ['智光大师', '乔峰', '赵钱孙', '徐长老', '马夫人'],\n", + " 'impact': ['意识到乔峰的契丹人身份可能引发的武林动荡', '对乔峰身份的反响提供了武林势力间复杂关系的理解'],\n", + " 'utterances': [],\n", + " 'speech_style': '谨慎且分析性',\n", + " 'personality_traits': ['机智', '谨慎', '分析能力强'],\n", + " 'emotion_state': '困惑和警觉',\n", + " 'relations': [{'target': '智光大师',\n", + " 'relation_type': '敬重对象',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:倾听, impact:对其证词的信任'},\n", + " {'target': '乔峰',\n", + " 'relation_type': '敬重对象',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:观望, impact:复杂情感变化'},\n", + " {'target': '徐长老',\n", + " 'relation_type': '敬重对象',\n", + " 'relation_strength': 0.2,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:分析, impact:对其处理事情的观察'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '钟万仇': {'name': '钟万仇',\n", + " 'first_appearance': 'chapters/chapter2',\n", + " 'events': [{'event_id': 'event_007',\n", + " 'time': '翌日中午',\n", + " 'location': '杏子林',\n", + " 'event': '乔峰在杏子林遭遇丐帮内部压力与西夏国端压迫',\n", + " 'if_completed': False,\n", + " 'action': ['继续暗中观察事态发展', '注意乔峰与西夏的直接对抗', '评估乔峰是否会在与西夏的冲突中显示弱点'],\n", + " 'motivation': ['寻找乔峰的弱点以便日后攻击', '确认在丐帮内发生动荡时的立场', '分析西夏压迫的动机以谋求潜在的联盟'],\n", + " 'involved_entities': ['乔峰', '西夏一品堂', '丐帮众人'],\n", + " 'impact': ['感知乔峰应对危机的能力与策略', '观察西夏插手中原武林事务的具体方式', '深化对丐帮势力内部分裂的理解'],\n", + " 'utterances': [],\n", + " 'speech_style': '谨慎',\n", + " 'personality_traits': ['洞察', '狡黠'],\n", + " 'emotion_state': '冷静',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': '翌日中午',\n", + " 'derived_from': 'action:注意乔峰与西夏的对抗, impact:感知乔峰应对危机的能力'}]},\n", + " {'event_id': 'event_008',\n", + " 'time': '今日午后',\n", + " 'location': '碾坊',\n", + " 'event': '段誉与王语嫣遭遇西夏武士追杀',\n", + " 'if_completed': True,\n", + " 'action': ['观察段誉与王语嫣的动向', '关注段誉使用六脉神剑击杀西夏武士'],\n", + " 'motivation': ['了解段誉的武功与内力特性', '分析王语嫣的武学知识与应变能力'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士'],\n", + " 'impact': ['重新评估段誉的潜在威胁', '观察王语嫣的智慧与领导能力'],\n", + " 'utterances': [],\n", + " 'speech_style': '隐秘',\n", + " 'personality_traits': ['谨慎', '观察者'],\n", + " 'emotion_state': '平静',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '潜在敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': '今日午后',\n", + " 'derived_from': 'action:段誉使用六脉神剑, impact:重新评估段誉的潜在威胁'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '观察对象',\n", + " 'relation_strength': 0,\n", + " 'last_updated': '今日午后',\n", + " 'derived_from': 'action:观察王语嫣的动向, impact:了解她的武学知识'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '甘宝宝': {'name': '甘宝宝',\n", + " 'first_appearance': 'chapters/chapter2',\n", + " 'events': [{'event_id': 'event_002',\n", + " 'time': '杏林丐帮大会',\n", + " 'location': '杏子林',\n", + " 'event': '揭露乔峰身世',\n", + " 'if_completed': True,\n", + " 'action': ['向丐帮高层及乔峰揭露其契丹人身世', '亲自撕毁证据中的署名'],\n", + " 'motivation': ['忏悔当年过失', '揭示真相以避免更多无辜伤亡'],\n", + " 'involved_entities': ['乔峰', '徐长老', '丐帮众兄弟', '赵钱孙'],\n", + " 'impact': ['引发丐帮内部分裂', '乔峰辞去帮主职位', '丐帮权力真空'],\n", + " 'utterances': [{'content': '若不是我自知死在临头,而遭殃的又是我最敬仰的二人,几乎脱口便要喝出采来。',\n", + " 'time': 'event_002'},\n", + " {'content': '我智光在武林中只是个无名小卒,做错了事,不算什么,但带头大哥和汪帮主是何等的身份地位?',\n", + " 'time': 'event_002'}],\n", + " 'speech_style': '充满惋惜与自责',\n", + " 'personality_traits': ['坦诚', '有担当', '勇于自省'],\n", + " 'emotion_state': '内疚、慈悲',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '前辈与后辈',\n", + " 'relation_strength': '0.5',\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'impact:揭露身份, action:撕毁证据'},\n", + " {'target': '赵钱孙',\n", + " 'relation_type': '旧识',\n", + " 'relation_strength': '0.4',\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'shared action and impact:揭露乔峰身世'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '逃离西夏武士追捕',\n", + " 'location': '无锡城外',\n", + " 'event': '逃避追杀',\n", + " 'if_completed': False,\n", + " 'action': ['帮助段誉和王语嫣逃避西夏武士追杀'],\n", + " 'motivation': ['保护王语嫣', '避免不必要的牵连'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士', '李延宗'],\n", + " 'impact': ['提升段誉对王语嫣的忠诚和保护欲', '促成段誉和王语嫣的情感交流'],\n", + " 'utterances': [{'content': '段公子,你的救命大恩,我有生之日,决不敢忘。', 'time': 'event_003'}],\n", + " 'speech_style': '温和而坚定',\n", + " 'personality_traits': ['善良', '聪慧', '决断'],\n", + " 'emotion_state': '感激与坚定',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': '0.6',\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:逃避追杀, impact:提升段誉忠诚感'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': '0.5',\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'impact:情感交流'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '阿宝': {'name': '阿宝',\n", + " 'first_appearance': 'chapters/chapter2',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '奔马途中',\n", + " 'location': '桑树林',\n", + " 'event': '逃离追兵',\n", + " 'if_completed': True,\n", + " 'action': ['段誉催马赶路', '脱下长袍给王语嫣遮雨'],\n", + " 'motivation': ['保护王语嫣', '逃避西夏追兵'],\n", + " 'involved_entities': ['王语嫣', '西夏武士', '段誉'],\n", + " 'impact': ['暂时躲避了追兵', '加深了段誉对王语嫣的好感'],\n", + " 'utterances': [{'event_id': 'event_001', 'said': '王姑娘,你觉得怎样?'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['善良', '幽默', '重情重义'],\n", + " 'emotion_state': '焦虑',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:保护, impact:加深关系'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '大雨中',\n", + " 'location': '碾坊',\n", + " 'event': '与西夏武士战斗',\n", + " 'if_completed': True,\n", + " 'action': ['推开碾坊门', '点穴对敌', '扶王语嫣下马'],\n", + " 'motivation': ['保护王语嫣', '自保'],\n", + " 'involved_entities': ['王语嫣', '西夏武士', '农家青年'],\n", + " 'impact': ['击杀数名西夏武士', '令王语嫣得以更换衣物'],\n", + " 'utterances': [{'event_id': 'event_002',\n", + " 'said': '各位英雄好汉,在下段誉和你们往日无怨,近日无仇'}],\n", + " 'speech_style': '诚恳',\n", + " 'personality_traits': ['善良', '冲动', '有幽默感'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:保护, impact:为其提供安全环境'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '碾坊周围',\n", + " 'location': '无锡附近',\n", + " 'event': '情感交流',\n", + " 'if_completed': False,\n", + " 'action': ['劝说王语嫣解毒', '与王语嫣谈心'],\n", + " 'motivation': ['倾慕王语嫣', '希望她安全'],\n", + " 'involved_entities': ['王语嫣'],\n", + " 'impact': ['增进与王语嫣的感情'],\n", + " 'utterances': [{'event_id': 'event_003', 'said': '我什么也不想,只盼永如眼前一般'}],\n", + " 'speech_style': '浪漫',\n", + " 'personality_traits': ['恋爱', '专一'],\n", + " 'emotion_state': '忧愁',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '爱慕',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'utterances:倾诉心愿'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '岳老三': {'name': '岳老三',\n", + " 'first_appearance': 'chapters/chapter2',\n", + " 'events': [{'event_id': 'event_011',\n", + " 'time': '夜间',\n", + " 'location': '杏子林',\n", + " 'event': '岳老三目睹丐帮内乱和乔峰的决策',\n", + " 'if_completed': True,\n", + " 'action': ['观察丐帮内乱进展', '分析乔峰的决策', '评估丐帮高层人物'],\n", + " 'motivation': ['检视丐帮的未来走向', '理解乔峰的判断力'],\n", + " 'involved_entities': ['乔峰', '徐长老', '白世镜', '马夫人', '单正', '谭氏伉俪', '赵钱孙'],\n", + " 'impact': ['加深对乔峰领导力的理解', '对于新势力变化保持警惕'],\n", + " 'utterances': [],\n", + " 'speech_style': '沉默',\n", + " 'personality_traits': ['冷静', '警觉'],\n", + " 'emotion_state': '警惕',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '观察对象',\n", + " 'relation_strength': 0.1,\n", + " 'last_updated': '夜间',\n", + " 'derived_from': 'action:观察丐帮内乱进展'},\n", + " {'target': '徐长老',\n", + " 'relation_type': '尊敬',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': '夜间',\n", + " 'derived_from': 'impact:评估丐帮高层人物'}]},\n", + " {'event_id': 'event_012',\n", + " 'time': '杏子林交战之后',\n", + " 'location': '杏子林',\n", + " 'event': '岳老三参与杏子林与西夏之战',\n", + " 'if_completed': True,\n", + " 'action': ['对段誉不敬并继续称呼师父', '怒吼以示愤怒', '逃跑以示不满'],\n", + " 'motivation': ['保持自尊', '维持南海鳄神的名声'],\n", + " 'involved_entities': ['段誉', '王语嫣', '阿朱', '阿碧', '南海鳄神'],\n", + " 'impact': ['对段誉的行动产生疑问', '恐吓了部分丐帮派系'],\n", + " 'utterances': [{'event_id': 'event_012', 'content': '王八蛋,狗杂种!'}],\n", + " 'speech_style': '粗鲁',\n", + " 'personality_traits': ['凶恶', '自负'],\n", + " 'emotion_state': '愤怒',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '师徒',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': '杏子林交战之后',\n", + " 'derived_from': 'action:对段誉不敬'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '岳老二': {'name': '岳老二',\n", + " 'first_appearance': 'chapters/chapter2',\n", + " 'events': [{'event_id': 'event_009',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '遭遇西夏国人搅局,丐帮与西夏人冲突',\n", + " 'if_completed': False,\n", + " 'action': ['观察事件发展', '保持警惕与安全', '提醒丐帮众对西夏人保持警惕'],\n", + " 'motivation': ['自保', '观察各方动向', '维护丐帮的安全'],\n", + " 'involved_entities': ['乔峰', '丐帮众', '王语嫣', '段誉', '西夏武士'],\n", + " 'impact': ['对西夏武士的不信任加深', '丐帮内部的信任危机'],\n", + " 'utterances': [{'text': '各位兄弟,慎重行事,西夏人不可信。', 'event_id': 'event_009'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['谨慎', '机警'],\n", + " 'emotion_state': '焦虑',\n", + " 'relations': [{'target': '西夏武士',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.7,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:观察, impact:不信任加深'},\n", + " {'target': '丐帮众',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:维护关系, impact:局势紧张'}]},\n", + " {'event_id': 'event_010',\n", + " 'time': '第十七章 今日意',\n", + " 'location': '无锡碾坊',\n", + " 'event': '遇到王语嫣与段誉,与西夏武士冲突',\n", + " 'if_completed': True,\n", + " 'action': ['逃离西夏武士追击', '安葬亡者', '烧毁碾坊以消灭证据'],\n", + " 'motivation': ['保护自己与王语嫣', '确保安全后撤'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士', '农家青年'],\n", + " 'impact': ['安葬与焚烧尸体减少了西夏的追踪可能', '与西夏武士的对峙增加了恩怨'],\n", + " 'utterances': [{'text': '色身无常,不可长保。各位仁兄今日命丧我手,当是前生业报,只盼魂归极乐,永脱轮回之苦。莫怪,莫怪。',\n", + " 'event_id': 'event_010'}],\n", + " 'speech_style': '冥思',\n", + " 'personality_traits': ['仁慈', '顾虑', '自省'],\n", + " 'emotion_state': '复杂',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_010',\n", + " 'derived_from': 'action:共同经历危难'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '合作伙伴',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_010',\n", + " 'derived_from': 'action:保护与协助'},\n", + " {'target': '西夏武士',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_010',\n", + " 'derived_from': 'action:抵抗与反击'},\n", + " {'target': '农家青年',\n", + " 'relation_type': '陌生人',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_010',\n", + " 'derived_from': 'action:安葬死者'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '来福儿': {'name': '来福儿',\n", + " 'first_appearance': 'chapters/chapter2',\n", + " 'events': [{'event_id': 'event_009',\n", + " 'time': '天已全黑',\n", + " 'location': '杏子林',\n", + " 'event': '因丐帮叛乱而被卷入武林风波',\n", + " 'if_completed': True,\n", + " 'action': ['观察丐帮内部斗争', '与王语嫣、段誉等人旁观事态发展'],\n", + " 'motivation': ['确保自身与乔峰等盟友的安全', '了解江湖局势'],\n", + " 'involved_entities': ['乔峰',\n", + " '白世镜',\n", + " '吴长风',\n", + " '段誉',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '徐长老',\n", + " '智光大师',\n", + " '赵钱孙'],\n", + " 'impact': ['与乔峰的关系可能面临新挑战', '意识到乔峰的身世秘密对他社交圈的影响'],\n", + " 'utterances': [],\n", + " 'speech_style': '文雅',\n", + " 'personality_traits': ['观察', '谨慎', '同情'],\n", + " 'emotion_state': '愕然',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:观察, impact:深化理解'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:旁观事态, impact:交流'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '敬仰',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'impact:意识到昔日旧事'}]},\n", + " {'event_id': 'event_010',\n", + " 'time': '隔天早晨',\n", + " 'location': '杏子林',\n", + " 'event': '卷入丐帮与西夏国情势的对峙',\n", + " 'if_completed': False,\n", + " 'action': ['观察丐帮与西夏国一品堂的谈判与对峙', '努力理解双方的历史与战略关系', '帮助段誉和王语嫣骑马逃离并遇雨避入碾坊'],\n", + " 'motivation': ['确保自身安全', '了解新环境及人际动态', '帮助段誉,尤其是王语嫣安全渡过难关'],\n", + " 'involved_entities': ['乔峰', '徐长老', '白世镜', '赫连铁树', '努儿海', '王语嫣', '段誉'],\n", + " 'impact': ['意识到乔峰对丐帮的重要性', '西夏一品堂势力对中原武林安全的威胁', '与段誉在困境中加深了情谊'],\n", + " 'utterances': [{'time': 'event_010', 'content': '观察这局势变动,对后续发展尤关重要。'},\n", + " {'time': '随王语嫣逃亡', 'content': '我不想再杀人了!要我再杀人,那可下不了手啦,你们快快走吧!'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['冷静', '观察准确', '仁慈'],\n", + " 'emotion_state': '警惕',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.75,\n", + " 'last_updated': 'event_010',\n", + " 'derived_from': 'action:观察, impact:意识到变动'},\n", + " {'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.85,\n", + " 'last_updated': '碾坊事件',\n", + " 'derived_from': 'action:帮助逃亡,影响:加深情谊'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': '碾坊事件',\n", + " 'derived_from': 'action:帮助解毒,影响:危难见友情'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '木婉清': {'name': '木婉清',\n", + " 'first_appearance': 'chapters/chapter4',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '众人围攻乔峰',\n", + " 'if_completed': True,\n", + " 'action': ['尝试协调丐帮内部矛盾', '保护丐帮名声', '支持乔峰并未使用任何敌意行动'],\n", + " 'motivation': ['保护乔峰', '维护丐帮名誉'],\n", + " 'involved_entities': ['乔峰', '徐长老', '赵钱孙', '单正', '单仲山', '丐帮众人'],\n", + " 'impact': ['提升丐帮内部对乔峰的支持', '一时避免了丐帮的内部分裂'],\n", + " 'utterances': [{'content': '乔帮主有话好说,千万不可动蛮。我单家与你无冤无仇,请你放了我孩儿。',\n", + " 'event_id': 'event_001'}],\n", + " 'speech_style': '理性、安抚',\n", + " 'personality_traits': ['冷静', '保护乔峰'],\n", + " 'emotion_state': '内心有些焦急但仍能保持镇定',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:试图通过调和化解对乔峰的敌意, impact:一时避免了丐帮的内部分裂'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十七章今日意',\n", + " 'location': '桑树林',\n", + " 'event': '与段誉同行',\n", + " 'if_completed': False,\n", + " 'action': ['与段誉探讨当前形势', '指出西夏武士的真实目的', '分辨各类武功流派'],\n", + " 'motivation': ['保护自己安全', '寻找慕容复'],\n", + " 'involved_entities': ['段誉', '李延宗'],\n", + " 'impact': ['段誉对其增加了感激与好感', '对峙时威慑住了李延宗'],\n", + " 'utterances': [{'content': '你若对我无礼,我表哥来给我报仇,定要搅得你西夏国天翻地覆,鸡犬不安。',\n", + " 'event_id': 'event_002'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['聪颖', '坚定'],\n", + " 'emotion_state': '略感无奈与担忧',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'impact:段誉对其增加感激与好感'},\n", + " {'target': '慕容复',\n", + " 'relation_type': '亲属',\n", + " 'relation_strength': 1.0,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'motivation:寻找慕容复'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '瑞婆婆': {'name': '瑞婆婆',\n", + " 'first_appearance': 'chapters/chapter4',\n", + " 'events': [{'event_id': 'event_005',\n", + " 'time': '夜晚',\n", + " 'location': '曼陀山庄',\n", + " 'event': '被迫成为花匠',\n", + " 'if_completed': False,\n", + " 'action': ['设计逃跑', '意欲保护王语嫣', '与段誉及其他人交流', '安慰段誉'],\n", + " 'motivation': ['争取自由', '对王语嫣的欣慕', '帮助他人'],\n", + " 'involved_entities': ['王语嫣', '王夫人', '严妈妈', '阿朱', '阿碧', '段誉'],\n", + " 'impact': ['与王语嫣保持复杂关系', '通过行动展现关心和关注'],\n", + " 'utterances': [{'event_id': 'event_005', 'content': '我不叫你神仙姊姊,却叫什么?'},\n", + " {'event_id': 'event_005',\n", + " 'content': '王夫人倒给他弄得没有法子,但听他说这四株茶花各有名称,倒也十分欢喜。'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['机智', '善良'],\n", + " 'emotion_state': '焦虑',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '暗恋对象',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:保护, impact:无伤害'},\n", + " {'target': '王夫人',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:抗议, impact:被迫种花'},\n", + " {'target': '严妈妈',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:控制, impact:无威胁'},\n", + " {'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:交流, impact:无伤害'}]},\n", + " {'event_id': 'event_006',\n", + " 'time': '夜晚后',\n", + " 'location': '杏子林',\n", + " 'event': '观察丐帮内部变故',\n", + " 'if_completed': True,\n", + " 'action': ['在场观察丐帮变故', '与段誉及他人交流', '注意到外部对丐帮的压迫', '评估形势'],\n", + " 'motivation': ['保护自身安全', '探索相关人物关系', '维持正义和公正'],\n", + " 'involved_entities': ['段誉',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '阿碧',\n", + " '乔峰',\n", + " '全冠清',\n", + " '丐帮帮众',\n", + " '西夏国武士'],\n", + " 'impact': ['了解丐帮内幕纷争', '增强自身对江湖势力的认知', '警觉外围势力对自己和群体的潜在威胁'],\n", + " 'utterances': [{'event_id': 'event_006', 'content': '段誉兄,这丐帮确有不少内情需要了解。'}],\n", + " 'speech_style': '观察性',\n", + " 'personality_traits': ['谨慎', '观察力强'],\n", + " 'emotion_state': '好奇',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '尊敬',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'action:观察, impact:无直接伤害'},\n", + " {'target': '西夏国武士',\n", + " 'relation_type': '潜在敌人',\n", + " 'relation_strength': -0.9,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'action:警觉, impact:无伤害'}]},\n", + " {'event_id': 'event_007',\n", + " 'time': '今日意',\n", + " 'location': '碾坊',\n", + " 'event': '解救王语嫣及遭遇西夏武士',\n", + " 'if_completed': True,\n", + " 'action': ['帮助段誉应对西夏武士', '启发段誉使用凌波微步', '获得解药并确保王语嫣恢复'],\n", + " 'motivation': ['保护王语嫣', '应对危险局势', '确保平安逃离威胁'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士'],\n", + " 'impact': ['确保王语嫣恢复健康', '援救段誉于危难中', '影响段誉个性发展'],\n", + " 'utterances': [{'event_id': 'event_007', 'content': '你用左手食指,点他小腹‘下脘穴’。'},\n", + " {'event_id': 'event_007', 'content': '你打他那里?点他那里?'},\n", + " {'event_id': 'event_007', 'content': '段公子,你的救命大恩,我有生之日,决不敢忘。'}],\n", + " 'speech_style': '指导性',\n", + " 'personality_traits': ['聪明', '善良', '决断'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 1,\n", + " 'last_updated': 'event_007',\n", + " 'derived_from': 'action:救助, impact:正面影响'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '平婆婆': {'name': '平婆婆',\n", + " 'first_appearance': 'chapters/chapter4',\n", + " 'events': [],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '南海鳄神': {'name': '南海鳄神',\n", + " 'first_appearance': 'chapters/chapter4',\n", + " 'events': [{'event_id': 'event_004',\n", + " 'time': '与西夏武士初次见面',\n", + " 'location': '杏子林',\n", + " 'event': '西夏武士挑衅丐帮',\n", + " 'if_completed': True,\n", + " 'action': ['观察局势,评估西夏武士的实力', '见识并未参与王语嫣与段誉的逃跑'],\n", + " 'motivation': ['确认西夏武士的真实意图'],\n", + " 'involved_entities': ['赫连铁树', '南海鳄神'],\n", + " 'impact': ['对西夏国的动机产生了怀疑'],\n", + " 'utterances': [],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['警觉', '怀疑'],\n", + " 'emotion_state': '警惕',\n", + " 'relations': [{'target': '赫连铁树',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:观察局势, impact:怀疑动机'},\n", + " {'target': '段誉',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:分析对局, impact:保护王语嫣'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '段誉与西夏武士的对峙',\n", + " 'location': '大碾坊',\n", + " 'event': '段誉与西夏武士的对峙',\n", + " 'if_completed': True,\n", + " 'action': ['未直接参与王语嫣和段誉遭遇西夏武士并获得短暂安全'],\n", + " 'motivation': ['感知事态', '确认段誉与王语嫣的安危'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士'],\n", + " 'impact': ['未对段誉和王语嫣及西夏的行动造成直接影响'],\n", + " 'utterances': [],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['慎重', '观察'],\n", + " 'emotion_state': '平静',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:未直接参与, impact:观察动静'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '友好',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:未直接参与, impact:观察动静'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '叶二娘': {'name': '叶二娘',\n", + " 'first_appearance': 'chapters/chapter4',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林事件',\n", + " 'location': '杏子林',\n", + " 'event': '西夏一品堂与丐帮冲突',\n", + " 'if_completed': True,\n", + " 'action': ['与西夏一品堂人物接触', '查看情况', '保护婴儿', '向西夏一品堂武士释放善意'],\n", + " 'motivation': ['自身利益', '自身好奇', '保护婴儿'],\n", + " 'involved_entities': ['乔峰', '赵钱孙', '徐长老', '段誉', '西夏一品堂'],\n", + " 'impact': ['事件影响丐帮的稳定性', '可能导致乔峰身份曝光', '保护了段誉和王语嫣免受西夏武士更多的追击'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'content': '各位伯伯叔叔,先夫不幸亡故,到底是何人下的毒手,此时自是难加断言。只是先夫平生诚稳笃实,拙于言词,江湖上并无仇家,妾身实在想不出,为何有人要取他性命。'}],\n", + " 'speech_style': '婉转细腻',\n", + " 'personality_traits': ['狡黠', '洞察力强'],\n", + " 'emotion_state': '冷静',\n", + " 'relations': [{'target': '赵钱孙',\n", + " 'relation_type': '同伙',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:保护婴儿'},\n", + " {'target': '乔峰',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.6,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'impact:可能导致乔峰身份曝光'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '云中鹤': {'name': '云中鹤',\n", + " 'first_appearance': 'chapters/chapter4',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十五章 杏子林中',\n", + " 'location': '杏子林',\n", + " 'event': '参加丐帮内部变故会议',\n", + " 'if_completed': True,\n", + " 'action': ['审视局势', '分析众人言行', '展现棉里藏针的领导力'],\n", + " 'motivation': ['维护丐帮稳定', '寻找真相'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长风',\n", + " '白世镜',\n", + " '全冠清',\n", + " '徐长老',\n", + " '单正',\n", + " '谭氏伉俪',\n", + " '赵钱孙'],\n", + " 'impact': ['推动事件西夏紧急军情的传递', '影响吴长风等人的判决'],\n", + " 'utterances': [],\n", + " 'speech_style': '沉稳',\n", + " 'personality_traits': ['聪慧', '洞察力强', '谦逊'],\n", + " 'emotion_state': '平静',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': 1,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:分析众人言行, impact:推动众人思考真相'},\n", + " {'target': '白世镜',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'impact:协助维护帮规的实施'},\n", + " {'target': '吴长风',\n", + " 'relation_type': '被动关系',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'impact:影响吴长风等人的判决'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十七章 今日意',\n", + " 'location': '西夏边境',\n", + " 'event': '被西夏武士追捕并与段誉合作逃脱',\n", + " 'if_completed': False,\n", + " 'action': ['分析段誉与西夏武士的战斗', '观察周围地形提供战术建议'],\n", + " 'motivation': ['逃避追捕', '保护段誉'],\n", + " 'involved_entities': ['段誉', '王语嫣', '西夏武士'],\n", + " 'impact': ['帮助段誉迷惑敌人', '协助躲避敌人攻击'],\n", + " 'utterances': [{'time': 'event_002', 'content': '王姑娘,敌人追来啦!'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['机智', '勇敢', '善于观察'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '友谊',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'impact:保护和帮助'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'impact:协同对敌'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '褚万里': {'name': '褚万里',\n", + " 'first_appearance': 'chapters/chapter5',\n", + " 'events': [{'event_id': 'event_009',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '应对西夏高手袭击',\n", + " 'if_completed': True,\n", + " 'action': ['观察双方对峙', '准备随时支持丐帮', '解救王语嫣和段誉'],\n", + " 'motivation': ['支持丐帮', '关注乔峰安危', '解救同伴'],\n", + " 'involved_entities': ['乔峰',\n", + " '徐长老',\n", + " '西夏众武士',\n", + " '努儿海',\n", + " '赫连铁树',\n", + " '王语嫣',\n", + " '段誉',\n", + " '丐帮众人'],\n", + " 'impact': ['提供间接策略建议', '尝试缓和与西夏的矛盾', '保护王语嫣和段誉安全'],\n", + " 'utterances': [],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['观察敏锐', '维护正义', '勇敢'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:观察与焦虑, impact:未对乔峰造成直接影响'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '倾慕',\n", + " 'relation_strength': 0.85,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:解救与保护, impact:提升亲近感'},\n", + " {'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:同步支持, impact:增强友情'}]},\n", + " {'event_id': 'event_010',\n", + " 'time': '第十七章 今日意',\n", + " 'location': '某碾坊',\n", + " 'event': '逃离西夏武士追击',\n", + " 'if_completed': True,\n", + " 'action': ['与王语嫣同行', '运用策略解毒', '观察和评估现场'],\n", + " 'motivation': ['保护王语嫣', '确保安全'],\n", + " 'involved_entities': ['段誉', '王语嫣', '李延宗', '西夏武士'],\n", + " 'impact': ['快速反应确保了王语嫣的安全', '通过谈话建立了更紧密的友情'],\n", + " 'utterances': [{'text': '我什么也不想,只盼永如眼前一般,那就心满意足,别无他求了。',\n", + " 'time': 'event_010'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['观察敏锐', '维护正义', '务实'],\n", + " 'emotion_state': '坚定',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '倾慕',\n", + " 'relation_strength': 0.88,\n", + " 'last_updated': 'event_010',\n", + " 'derived_from': 'action:解救与观察, impact:增强信任和亲近感'},\n", + " {'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.75,\n", + " 'last_updated': 'event_010',\n", + " 'derived_from': 'action:协作和信任, impact:增强友情'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '郭思归': {'name': '郭思归',\n", + " 'first_appearance': 'chapters/chapter5',\n", + " 'events': [{'event_id': 'event_005',\n", + " 'time': '当日黄昏',\n", + " 'location': '杏子林中',\n", + " 'event': '丐帮内乱观察',\n", + " 'if_completed': False,\n", + " 'action': ['旁观丐帮内乱', '听取众人对乔峰的指责', '与王语嫣、段誉等人保持隐蔽'],\n", + " 'motivation': ['关注乔峰的处境', '审视丐帮内部变故'],\n", + " 'involved_entities': ['乔峰',\n", + " '段誉',\n", + " '王语嫣',\n", + " '马夫人',\n", + " '徐长老',\n", + " '单正',\n", + " '谭公',\n", + " '谭婆',\n", + " '赵钱孙'],\n", + " 'impact': ['丐帮对乔峰的信任受到质疑', '郭思归进一步理解丐帮及乔峰的复杂关系'],\n", + " 'utterances': [{'timestamp': 'event_005', 'content': '这等无端指责,乔帮主又何必介意?'}],\n", + " 'speech_style': '关切,小心',\n", + " 'personality_traits': ['谨慎', '冷静'],\n", + " 'emotion_state': '关注',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '结拜兄弟',\n", + " 'relation_strength': 0.85,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:旁观, impact:信任受到质疑'},\n", + " {'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.75,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:保持隐蔽, impact:提供周边支持'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:保持隐蔽, impact:提供周边支持'}]},\n", + " {'event_id': 'event_006',\n", + " 'time': '次日',\n", + " 'location': '无锡附近的碾坊',\n", + " 'event': '与西夏武士对峙',\n", + " 'if_completed': True,\n", + " 'action': ['与段誉、王语嫣会面', '分析形势并鼓励段誉', '密切关注敌我态势'],\n", + " 'motivation': ['保护同伴', '观察敌我变化'],\n", + " 'involved_entities': ['段誉', '王语嫣', '李延宗', '西夏武士', '农家青年'],\n", + " 'impact': ['对段誉及王语嫣的境况给予支持', '维护了团队的团结与信心'],\n", + " 'utterances': [{'timestamp': 'event_006', 'content': '我相信段公子一定会有办法的。'}],\n", + " 'speech_style': '启发,鼓励',\n", + " 'personality_traits': ['温和', '睿智'],\n", + " 'emotion_state': '镇定',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'action:支持段誉, impact:提供支持'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.55,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'action:支持王语嫣, impact:提供支持'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '朱子诚': {'name': '朱子诚',\n", + " 'first_appearance': 'chapters/chapter5',\n", + " 'events': [{'event_id': 'event_013',\n", + " 'time': '将近午时',\n", + " 'location': '无锡',\n", + " 'event': '朱子诚与丐帮及姑苏慕容氏的冲突',\n", + " 'if_completed': False,\n", + " 'action': ['观察局势', '聆听谈话', '分析各方立场'],\n", + " 'motivation': ['了解丐帮与西夏一品堂之间的关系', '解开丐帮对乔峰的疑虑'],\n", + " 'involved_entities': ['乔峰',\n", + " '段誉',\n", + " '包不同',\n", + " '王语嫣',\n", + " '风波恶',\n", + " '陈长老',\n", + " '白世镜',\n", + " '吴长风',\n", + " '徐长老',\n", + " '单正',\n", + " '智光大师',\n", + " '赵钱孙'],\n", + " 'impact': ['隐约了解帮派关系复杂性', '观察了乔峰的处理方式和影响力', '见证智光大师与赵钱孙的证言'],\n", + " 'utterances': [{'id': 'event_013_001',\n", + " 'text': '帮主代宋长老求情,所说本也有理。叛帮大罪,决不可赦。',\n", + " 'timestamp': '将近午时'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['机敏', '警觉', '善于分析'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '关注对象',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_013',\n", + " 'derived_from': 'action:解开乔峰疑虑, impact:信任逐渐增加'},\n", + " {'target': '段誉',\n", + " 'relation_type': '支持者',\n", + " 'relation_strength': 0.2,\n", + " 'last_updated': 'event_013',\n", + " 'derived_from': 'action:听从乔峰, impact:信任'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '中立观察',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_013',\n", + " 'derived_from': 'action:观察局势, impact:理解事态发展'},\n", + " {'target': '赵钱孙',\n", + " 'relation_type': '中立观察',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_013',\n", + " 'derived_from': 'action:聆听谈话, impact:了解历史讯息'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '朱丹臣': {'name': '朱丹臣',\n", + " 'first_appearance': 'chapters/chapter6',\n", + " 'events': [{'event_id': 'event_004',\n", + " 'time': '第十四章,夜晚',\n", + " 'location': '无锡惠山丐帮集合点',\n", + " 'event': '丐帮内乱瞬间观察',\n", + " 'if_completed': True,\n", + " 'action': ['观察丐帮诸长老的言行', '评估内乱对各势力的影响'],\n", + " 'motivation': ['理解丐帮与其他势力的纷争'],\n", + " 'involved_entities': ['乔峰',\n", + " '白世镜',\n", + " '全冠清',\n", + " '丐帮众',\n", + " '吴长风',\n", + " '宋长老',\n", + " '奚长老',\n", + " '陈长老'],\n", + " 'impact': ['加强了对丐帮势力和内奸的了解'],\n", + " 'utterances': [{'time': 'event_004', 'content': '(观察时没有说话)'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['冷静', '观察力强'],\n", + " 'emotion_state': '警觉',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:观察, impact:信任和理解加深'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '仰慕',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:观察, impact:保持关注与欣赏'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '第十五章,晚上',\n", + " 'location': '杏子林',\n", + " 'event': '应对丐帮内乱',\n", + " 'if_completed': True,\n", + " 'action': ['观看内乱处理和冲突', '分析各人物说话的意图'],\n", + " 'motivation': ['评估丐帮与乔峰的关系', '确认丐帮管理中的漏洞'],\n", + " 'involved_entities': ['乔峰',\n", + " '马夫人',\n", + " '传功长老',\n", + " '执法长老',\n", + " '徐长老',\n", + " '单正',\n", + " '谭公',\n", + " '谭婆',\n", + " '赵钱孙'],\n", + " 'impact': ['加深对乔峰为人和处事能力的了解'],\n", + " 'utterances': [{'time': 'event_005', 'content': '(直接观察,没有发言)'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['冷静', '观察力强'],\n", + " 'emotion_state': '警觉',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:观察, impact:信任和理解加深'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '仰慕',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:观察, impact:保持关注与欣赏'}]},\n", + " {'event_id': 'event_006',\n", + " 'time': '第十六章,早晨',\n", + " 'location': '杏子林',\n", + " 'event': '智光大师揭示乔峰身世',\n", + " 'if_completed': False,\n", + " 'action': ['倾听智光大师揭露乔峰身世的真相', '观察各方对此事的反应'],\n", + " 'motivation': ['了解事件的全貌', '决策未来的行动计划'],\n", + " 'involved_entities': ['乔峰', '智光', '徐长老', '马夫人', '赵钱孙', '王语嫣'],\n", + " 'impact': ['事件引起丐帮内部的巨大震动', '乔峰与帮内众人关系发生变化'],\n", + " 'utterances': [{'time': 'event_006', 'content': '(倾听之中)'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['冷静', '观察力强'],\n", + " 'emotion_state': '复杂',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'action:观察,impact:信任和理解加深,但对未来关系的不确定存在'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '仰慕',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'action:倾听, impact:保持关注与欣赏'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '周穆': {'name': '周穆',\n", + " 'first_appearance': 'chapters/chapter6',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内部疑云与乔峰决裂',\n", + " 'if_completed': True,\n", + " 'action': ['发现乔峰是契丹后裔,引起众人对他的质疑', '参与向丐帮中人揭露乔峰的身世', '尝试维护丐帮威严,化解分歧'],\n", + " 'motivation': ['对乔峰身世的揭露出于正义感', '维护丐帮的传统和声誉'],\n", + " 'involved_entities': ['乔峰', '智光大师', '徐长老', '马夫人', '赵钱孙', '丐帮众长老及帮众'],\n", + " 'impact': ['导致乔峰抛弃丐帮帮主之位', '引起丐帮内部的分裂与争论', '激发众人对自身与国家命运的思考'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'content': '可笑啊可笑!汉人未必高人一等,契丹人也未必便猪狗不如!明明是契丹,却硬要冒充汉人,那有什么滋味?连自己的亲生父母也不肯认,枉自称什么男子汉、大丈夫?'}],\n", + " 'speech_style': '讽刺',\n", + " 'personality_traits': ['直接', '讽刺', '对原则有强烈的坚持'],\n", + " 'emotion_state': '平静但含有讽刺',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '丐帮同门',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:揭露其身世, impact:解除其帮主职务对丐帮的影响'},\n", + " {'target': '马夫人',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': '行动共同揭露乔峰身份'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '敬重的长辈',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': '同样参与事件揭露和处理'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '傅肃': {'name': '傅肃',\n", + " 'first_appearance': 'chapters/chapter6',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮大会及乔峰被揭露身世',\n", + " 'if_completed': True,\n", + " 'action': ['揭露乔峰是契丹人', '质疑乔峰的丐帮帮主身份', '指出乔峰与马大元之死有关', '与众人讨论乔峰是否能继续领导丐帮'],\n", + " 'motivation': ['揭示乔峰真实身份', '为马大元的死寻找真相'],\n", + " 'involved_entities': ['乔峰', '徐长老', '马夫人', '智光大师', '单正', '丐帮群丐'],\n", + " 'impact': ['乔峰被迫离开丐帮', '丐帮内部分裂并生内讧'],\n", + " 'utterances': [{'text': '你也说我是契丹人么?', 'event_id': 'event_001'},\n", + " {'text': '有话好说,千万不可动蛮。', 'event_id': 'event_001'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['冷静', '分析能力强'],\n", + " 'emotion_state': '烦恼',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '不明',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:揭露, impact:逼迫乔峰离开丐帮'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '古笃诚': {'name': '古笃诚',\n", + " 'first_appearance': 'chapters/chapter6',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '乔峰面临身份揭露',\n", + " 'if_completed': True,\n", + " 'action': ['抓住智光大师', '与单正等对峙', '放下帮主身份'],\n", + " 'motivation': ['查明自己的身世', '保护丐帮名誉', '不愿伤害同伴'],\n", + " 'involved_entities': ['智光大师', '徐长老', '单正', '赵钱孙', '马夫人'],\n", + " 'impact': ['乔峰对身份产生怀疑', '丐帮内部动荡', '智光似乎知道更多关于乔峰身世的秘密'],\n", + " 'utterances': [{'text': '不是灰心。', 'event_id': 'event_001'},\n", + " {'text': '别说府上只不过三两个女流之辈,便是皇宫内院...未必不能办到。', 'event_id': 'event_001'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['慷慨', '豪侠', '光明磊落'],\n", + " 'emotion_state': '复杂、疑虑',\n", + " 'relations': [{'target': '智光大师',\n", + " 'relation_type': '恩怨未明',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:抓住, impact:对乔峰身世发言'},\n", + " {'target': '单正',\n", + " 'relation_type': '对立',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:对峙, impact:帮助罢免乔峰'},\n", + " {'target': '丐帮',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:放下帮主身份, impact:丐帮内部分裂'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '玉虚散人': {'name': '玉虚散人',\n", + " 'first_appearance': 'chapters/chapter6',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '卯时',\n", + " 'location': '杏子林',\n", + " 'event': '被揭露契丹出身及段誉营救丐帮的危机状况',\n", + " 'if_completed': True,\n", + " 'action': ['揭露自己是契丹人', '拒绝对马大元之死负责', '放弃帮主之位', '警告丐帮内部勿再自相残杀'],\n", + " 'motivation': ['查明身世的真相', '保护丐帮整体,避免内部纷争'],\n", + " 'involved_entities': ['赵钱孙',\n", + " '智光大师',\n", + " '徐长老',\n", + " '丐帮群丐',\n", + " '西夏国的西夏武士',\n", + " '段誉',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '阿碧'],\n", + " 'impact': ['让丐帮内部意见分歧,产生不确定性', '导致对段誉等拼死营救行动的推动'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'content': '我的身世未明,这帮主一职,无论如何是不敢担任了。'},\n", + " {'event_id': 'event_001', 'content': '青山不改,绿水长流,众位好兄弟,咱们再见了。'}],\n", + " 'speech_style': '沉稳、坚决',\n", + " 'personality_traits': ['有责任心', '诚实'],\n", + " 'emotion_state': '内心冲突,略显惆怅',\n", + " 'relations': [{'target': '丐帮',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:放弃帮主之位, impact:维护组织稳定'},\n", + " {'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'impact:段誉救助,彼此的联系与支持'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '王昌龄': {'name': '王昌龄',\n", + " 'first_appearance': 'chapters/chapter6',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林之夜',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内乱',\n", + " 'if_completed': True,\n", + " 'action': ['参与丐帮内乱的商讨',\n", + " '旁观丐帮的内部审判',\n", + " '见证乔峰平定内乱',\n", + " '目睹智光大师及其他长老与乔峰关于过去事件的对峙'],\n", + " 'motivation': ['察看丐帮内部变故', '保护自己免受怀疑'],\n", + " 'involved_entities': ['乔峰',\n", + " '全冠清',\n", + " '吴长风',\n", + " '白世镜',\n", + " '马夫人',\n", + " '赵钱孙',\n", + " '谭公',\n", + " '谭婆',\n", + " '徐长老',\n", + " '单正',\n", + " '单家五兄弟',\n", + " '智光大师'],\n", + " 'impact': ['对丐帮内局势的了解加深', '观察到乔峰英勇与仁义', '对乔峰身世的揭露与挑战形成了丐帮内部分裂']},\n", + " {'event_id': 'event_002',\n", + " 'time': '临近黎明',\n", + " 'location': '杏子林',\n", + " 'event': '西夏一品堂挑战丐帮',\n", + " 'if_completed': False,\n", + " 'action': ['观察西夏一品堂与丐帮的冲突', '见证西夏众人使用邪术压制丐帮'],\n", + " 'motivation': ['理解西夏一品堂的力量与目的'],\n", + " 'involved_entities': ['西夏一品堂', '赫连铁树', '努儿海', '乔峰', '云中鹤', '段誉'],\n", + " 'impact': ['愤慨西夏一品堂对丐帮的无礼攻击']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '高升泰': {'name': '高升泰',\n", + " 'first_appearance': 'chapters/chapter6',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '得知身世真相,并辞去丐帮帮主之位',\n", + " 'if_completed': True,\n", + " 'action': ['了解了自己疑似契丹人的身世', '辞去丐帮帮主之位', '听取关于自身身世的证词', '平息丐帮内乱,避免自相残杀'],\n", + " 'motivation': ['不愿丐帮因自己身世而分裂', '寻求身世的真相'],\n", + " 'involved_entities': ['智光', '徐长老', '马夫人', '丐帮众'],\n", + " 'impact': ['乔峰辞去帮主位置,丐帮面临领导缺失',\n", + " '多名丐帮成员质疑乔峰的身世并产生分裂',\n", + " '丐帮暂时避免内乱继续,但面临不确定未来'],\n", + " 'utterances': [{'event_id': 'event_003',\n", + " 'text': '无论乔峰是汉人还是契丹人,有生之年,决不伤一条汉人的性命,若违此誓,有如此刀。',\n", + " 'time': '第十六章 昔时因'},\n", + " {'event_id': 'event_003',\n", + " 'text': '这根竹棒儿晶莹碧绿,拿去做个扫帚柄儿,倒也不错。',\n", + " 'time': '第十六章 昔时因'}],\n", + " 'speech_style': '文雅',\n", + " 'personality_traits': ['坚毅', '面临重大打击而保持镇定', '不愿他人因己受害'],\n", + " 'emotion_state': '复杂',\n", + " 'relations': [{'target': '智光',\n", + " 'relation_type': '江湖同道',\n", + " 'relation_strength': 0.35,\n", + " 'last_updated': '第十六章 昔时因',\n", + " 'derived_from': 'action:得知身世, impact:谨慎对待'},\n", + " {'target': '徐长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.55,\n", + " 'last_updated': '第十六章 昔时因',\n", + " 'derived_from': 'action:辞去帮主, impact:带来的帮内动荡'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '善阐侯': {'name': '善阐侯',\n", + " 'first_appearance': 'chapters/chapter6',\n", + " 'events': [{'event_id': 'event_007',\n", + " 'time': '不久后',\n", + " 'location': '听香水榭',\n", + " 'event': '王语嫣等人准备对抗西夏一品堂',\n", + " 'if_completed': True,\n", + " 'action': ['参与与敌人的对话和智力较量', '分析敌我情况,作出决断'],\n", + " 'motivation': ['保护朋友与庄园', '收集信息应对多方敌人'],\n", + " 'involved_entities': ['王语嫣', '包不同', '阿朱', '阿碧', '段誉', '姚伯当', '司马林'],\n", + " 'impact': ['与包不同一行人结成同盟',\n", + " '为未来与西夏及其他势力的冲突做准备',\n", + " '未能完全阻止西夏一品堂的行动,导致丐帮众人遭遇麻烦'],\n", + " 'utterances': [{'time': 'event_007',\n", + " 'content': '这汉人小姑娘甚是古怪,咱们擒回一品堂,令她尽吐所知,大概极有用处。'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['理智', '分析力强'],\n", + " 'emotion_state': '忧虑',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_007',\n", + " 'derived_from': 'action:联合对抗, impact:同盟'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_007',\n", + " 'derived_from': 'action:保护信息, impact:同盟'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '皇后': {'name': '皇后',\n", + " 'first_appearance': 'chapters/chapter6',\n", + " 'events': [{'event_id': 'event_002',\n", + " 'time': '天黑后',\n", + " 'location': '杏子林中',\n", + " 'event': '乔峰被推翻',\n", + " 'if_completed': True,\n", + " 'action': ['安抚乱局', '观察局势'],\n", + " 'motivation': ['助乔峰稳定丐帮的局势'],\n", + " 'involved_entities': ['乔峰', '宋奚陈吴四长老', '白世镜', '智光大师', '赵钱孙'],\n", + " 'impact': ['乔峰的身份被揭露', '丐帮内部分裂']},\n", + " {'event_id': 'event_003',\n", + " 'time': '杏子林事件后',\n", + " 'location': '杏子林中',\n", + " 'event': '智光大师揭露乔峰身世',\n", + " 'if_completed': True,\n", + " 'action': ['倾听智光大师揭露往事', '协调丐帮内部关系'],\n", + " 'motivation': ['维持局势稳定', '窥探乔峰的真实来历'],\n", + " 'involved_entities': ['智光大师', '赵钱孙', '乔峰', '宋奚陈吴四长老'],\n", + " 'impact': ['丐帮内部对乔峰产生怀疑', '引发乔峰形象的重大危机']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '保定帝': {'name': '保定帝',\n", + " 'first_appearance': 'chapters/chapter6',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十五章 杏子林中,天已全黑',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内部密谋废帮主事件',\n", + " 'if_completed': True,\n", + " 'action': ['捕捉叛乱者', '与执法长老白世镜协调处理', '处理参与密谋的四长老与全冠清'],\n", + " 'motivation': ['维护帮规和帮派安全', '厘清误会与真相'],\n", + " 'involved_entities': ['乔峰', '白世镜', '宋奚陈吴四长老', '全冠清', '刘竹庄'],\n", + " 'impact': ['部分叛乱者被拘禁', '密谋者揭露乔峰与马副帮主的矛盾加深了丐帮的危机', '对丐帮声誉的影响'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'content': '众位兄弟,马副帮主不是我害的,我们须当详加访查。',\n", + " 'timestamp': '事件过程'},\n", + " {'event_id': 'event_001',\n", + " 'content': '物以类聚,人以群分。',\n", + " 'timestamp': '事件过程中段'}],\n", + " 'speech_style': '直接、理性',\n", + " 'personality_traits': ['冷静', '正义'],\n", + " 'emotion_state': '疑惑',\n", + " 'relations': [{'target': '宋奚陈吴四长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': '事件中',\n", + " 'derived_from': '处理密谋事件'},\n", + " {'target': '全冠清',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': '事件中',\n", + " 'derived_from': '事件:密谋废帮主'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '乔峰被揭露的身世与责任之争',\n", + " 'if_completed': False,\n", + " 'action': ['被动听取并接受对自己的身世揭露', '参与对话并试图维护丐帮的稳定', '与丐帮众人讨论帮主职位的继承'],\n", + " 'motivation': ['寻求真相', '保护丐帮的和平与稳定'],\n", + " 'involved_entities': ['徐长老', '马夫人', '智光大师', '赵钱孙', '阿朱'],\n", + " 'impact': ['丐帮内部矛盾加剧', '乔峰的个人声誉受到重大挑战', '未来丐帮领导的不确定性'],\n", + " 'utterances': [{'event_id': 'event_002',\n", + " 'content': '不,不!你胡说八道,捏造这么一篇鬼话来诬陷我。',\n", + " 'timestamp': '事件过程'},\n", + " {'event_id': 'event_002',\n", + " 'content': '我打死也不会相信,我是契丹人。',\n", + " 'timestamp': '事件中段'}],\n", + " 'speech_style': '激烈,直接',\n", + " 'personality_traits': ['坚定', '正直'],\n", + " 'emotion_state': '痛苦,失落',\n", + " 'relations': [{'target': '马夫人',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': '事件中段',\n", + " 'derived_from': '怀疑与指责'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '长辈',\n", + " 'relation_strength': 0.0,\n", + " 'last_updated': '事件中段',\n", + " 'derived_from': '揭露,冲突'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '霍先生': {'name': '霍先生',\n", + " 'first_appearance': 'chapters/chapter6',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '三十年前',\n", + " 'location': '雁门关外',\n", + " 'event': '参与雁门关外伏击',\n", + " 'if_completed': True,\n", + " 'action': ['参与伏击', '向汉人传递契丹人偷袭情报', '使用暗器袭击契丹武士'],\n", + " 'motivation': ['保卫少林寺武功秘笈', '保护中原武林'],\n", + " 'involved_entities': ['契丹武士', '汉人同道'],\n", + " 'impact': ['导致汉人和契丹武士双方死伤', '形成汉人对契丹人的误解']},\n", + " {'event_id': 'event_002',\n", + " 'time': '小说现实时',\n", + " 'location': '杏子林',\n", + " 'event': '讲述三十年前的雁门关外战役',\n", + " 'if_completed': True,\n", + " 'action': ['叙述往事', '与乔峰对话', '解释雁门关事实真相'],\n", + " 'motivation': ['为过去的错误表示内疚', '澄清事件真相'],\n", + " 'involved_entities': ['乔峰', '丐帮长老'],\n", + " 'impact': ['影响乔峰对自身身份的认知', '引发丐帮内部分裂']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '宫婢': {'name': '宫婢',\n", + " 'first_appearance': 'chapters/chapter7',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '与乔峰、丐帮众人和西夏国敌人对峙',\n", + " 'if_completed': True,\n", + " 'action': ['出现在杏子林', '观望众人对峙', '无发表'],\n", + " 'motivation': [],\n", + " 'involved_entities': ['乔峰',\n", + " '徐长老',\n", + " '智光大师',\n", + " '单正',\n", + " '赵钱孙',\n", + " '马夫人',\n", + " '丐帮众人',\n", + " '西夏武士',\n", + " '努儿海',\n", + " '杰赫连铁树'],\n", + " 'impact': ['无直接影响'],\n", + " 'utterances': [],\n", + " 'speech_style': '无',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '无',\n", + " 'relations': []}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '刀白风': {'name': '刀白风',\n", + " 'first_appearance': 'chapters/chapter7',\n", + " 'events': [{'event_id': 'event_008',\n", + " 'time': '第十五章',\n", + " 'location': '杏子林',\n", + " 'event': '观察丐帮内讧及乔峰排除异己',\n", + " 'if_completed': True,\n", + " 'action': ['观察局势', '安抚段誉等人的情绪', '分析局面'],\n", + " 'motivation': ['维护与乔峰、段誉的关系', '收集对慕容复有利的情报'],\n", + " 'involved_entities': ['段誉', '乔峰', '丐帮弟子', '赵钱孙', '谭公', '谭婆', '徐长老'],\n", + " 'impact': ['熟悉丐帮内情', '了解江湖各派对慕容复的态度'],\n", + " 'utterances': [{'event_id': 'event_008', 'content': '大哥,大哥,我随你去!'}],\n", + " 'speech_style': '文雅',\n", + " 'personality_traits': ['善于分析', '冷静'],\n", + " 'emotion_state': '观察中',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_008',\n", + " 'derived_from': 'action:观察局势, impact:关系稳定'},\n", + " {'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_008',\n", + " 'derived_from': 'action:观察及局势分析, impact:关系保持'}]},\n", + " {'event_id': 'event_009',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '面对丐帮变乱质疑乔峰',\n", + " 'if_completed': False,\n", + " 'action': ['聆听智光大师关于乔峰身世的揭露', '观察丐帮对乔峰的态度', '安抚马夫人并提示关于遗书的问题'],\n", + " 'motivation': ['了解乔峰的真正身份', '衡量丐帮变乱对慕容复的影响', '支持朋友段誉和慕容复'],\n", + " 'involved_entities': ['乔峰', '丐帮弟子', '智光大师', '马夫人', '徐长老', '段誉', '王语嫣'],\n", + " 'impact': ['局势纷乱,可能导致江湖势力重新洗牌', '乔峰之争可能削弱丐帮力量'],\n", + " 'utterances': [{'event_id': 'event_009',\n", + " 'content': '查问是不敢。我听夫人言道,马前辈这封遗书,乃是用火漆密密固封,而徐长老开拆之时,漆印仍属完好。那么在徐长老开拆之前,谁也没看过信中的内文了?'}],\n", + " 'speech_style': '文雅',\n", + " 'personality_traits': ['善于分析', '冷静', '谨慎'],\n", + " 'emotion_state': '警惕和好奇',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:聆听及分析局势影响'},\n", + " {'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:安抚段誉'},\n", + " {'target': '马夫人',\n", + " 'relation_type': '丐帮成员',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_009',\n", + " 'derived_from': 'action:安抚并质疑其对乔峰的推测'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '修罗刀秦红棉': {'name': '修罗刀秦红棉',\n", + " 'first_appearance': 'chapters/chapter7',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '发生丐帮内乱,秦红棉参与事件',\n", + " 'if_completed': True,\n", + " 'action': ['参与关注乔峰身世的讨论', '维护丐帮稳定'],\n", + " 'motivation': ['维护丐帮的稳定'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长老',\n", + " '白世镜',\n", + " '全冠清',\n", + " '徐长老',\n", + " '智光大师',\n", + " '赵钱孙',\n", + " '王语嫣',\n", + " '段誉'],\n", + " 'impact': ['乔峰辞去丐帮帮主之位', '丐帮内部分裂加剧'],\n", + " 'utterances': ['event_001: 支持维护丐帮稳定'],\n", + " 'speech_style': '镇静且支持',\n", + " 'personality_traits': ['冷静', '忠诚'],\n", + " 'emotion_state': '忧虑',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:关注乔峰, impact:辞去丐帮帮主'},\n", + " {'target': '徐长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:关注徐长老态度, impact:分裂加剧'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '段正明': {'name': '段正明',\n", + " 'first_appearance': 'chapters/chapter7',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林中',\n", + " 'location': '杏子林',\n", + " 'event': '围观丐帮内斗',\n", + " 'if_completed': True,\n", + " 'action': ['与王语嫣、阿朱、阿碧一同围观丐帮的内部事件', '消极围观与态度', '与王语嫣交换意见'],\n", + " 'motivation': ['希望保持中立', '想了解乔峰的处境'],\n", + " 'involved_entities': ['乔峰', '王语嫣', '阿朱', '阿碧'],\n", + " 'impact': ['对乔峰的局势没有直接影响', '与王语嫣拉近关系,对乔峰内心有所了解'],\n", + " 'utterances': [{'time': 'event_001', 'content': '大哥,大哥,我随你去!'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['热心', '重情义'],\n", + " 'emotion_state': '关切',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:围观内斗'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:与王语嫣交换意见'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '次日晨',\n", + " 'location': '杏子林',\n", + " 'event': '与西夏武士交战',\n", + " 'if_completed': False,\n", + " 'action': ['与丐帮暂时离开,经历丐帮与西夏一品堂武士的交战', '协助照顾和转移王语嫣'],\n", + " 'motivation': ['保护王语嫣', '受乔峰影响,抵抗外敌'],\n", + " 'involved_entities': ['徐长老', '传功长老', '西夏武士', '王语嫣'],\n", + " 'impact': ['增加对王语嫣的好感', '增强对群丐的认识与同情'],\n", + " 'utterances': [{'time': 'event_002', 'content': '王姑娘,你们要到那里去?'}],\n", + " 'speech_style': '诚恳',\n", + " 'personality_traits': ['机智', '善良'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.75,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:协助转移'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '梁阿婆': {'name': '梁阿婆',\n", + " 'first_appearance': 'chapters/chapter7',\n", + " 'events': [{'event_id': 'event_004',\n", + " 'time': '杏子林光明初升',\n", + " 'location': '杏子林',\n", + " 'event': '围观丐帮内变,反应乔峰平叛危局',\n", + " 'if_completed': True,\n", + " 'action': ['观察局势发展', '与段誉、王语嫣、阿朱、阿碧保持旁观态度', '分析智光大师言语', '听取王语嫣指点'],\n", + " 'motivation': ['洞察丐帮进展', '评估乔峰是否安全', '了解智光大师的历史叙述', '理解事件全貌'],\n", + " 'involved_entities': ['乔峰',\n", + " '全冠清',\n", + " '宋奚陈吴四长老',\n", + " '段誉',\n", + " '王语嫣',\n", + " '智光大师',\n", + " '赵钱孙',\n", + " '马夫人'],\n", + " 'impact': ['提高对乔峰能力的认同', '对乔峰产生同情', '感知到事件复杂性'],\n", + " 'utterances': [{'event_id': 'event_004',\n", + " 'text': '围观很重要,有时保持旁观态度是最好的选择。',\n", + " 'time': '杏子林'}],\n", + " 'speech_style': '旁观者',\n", + " 'personality_traits': ['观察力强', '中立', '有耐心'],\n", + " 'emotion_state': '好奇',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '观察友人',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:旁观, impact:提高对乔峰能力的认同'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '杏子林天色近午',\n", + " 'location': '杏子林',\n", + " 'event': '被西夏军围困并释放毒气',\n", + " 'if_completed': True,\n", + " 'action': ['面临西夏军毒气袭击', '眼部受毒性影响', '无法动弹'],\n", + " 'motivation': ['参与丐帮事件', '继续观察事态发展'],\n", + " 'involved_entities': ['西夏军', '段誉', '王语嫣'],\n", + " 'impact': ['失去行动能力', '被动脱离事件核心'],\n", + " 'utterances': [{'event_id': 'event_005', 'text': '', 'time': '杏子林'}],\n", + " 'speech_style': '无',\n", + " 'personality_traits': ['冷静', '适应'],\n", + " 'emotion_state': '无助',\n", + " 'relations': [{'target': '西夏军',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.7,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:面临毒气袭击, impact:失去行动能力'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '刀白凤': {'name': '刀白凤',\n", + " 'first_appearance': 'chapters/chapter8',\n", + " 'events': [{'event_id': 'event_004',\n", + " 'time': '朝阳初升',\n", + " 'location': '杏子林',\n", + " 'event': '目睹丐帮内乱,听取马夫人遗书揭露的丐帮内幕',\n", + " 'if_completed': True,\n", + " 'action': ['观察丐帮内乱的进展',\n", + " '听取马夫人诉说马大元遗书内容',\n", + " '留意各方人物反应及动态',\n", + " '见证乔峰被迫离开丐帮',\n", + " '目睹丐帮与西夏武士的对峙'],\n", + " 'motivation': ['了解局势变化', '确保青城派合作和安全'],\n", + " 'involved_entities': ['乔峰',\n", + " '马夫人',\n", + " '徐长老',\n", + " '单正',\n", + " '赵钱孙',\n", + " '谭公',\n", + " '谭婆',\n", + " '包不同',\n", + " '司马林',\n", + " '阿朱',\n", + " '智光大师',\n", + " '段誉',\n", + " '王语嫣',\n", + " '西夏武士'],\n", + " 'impact': ['在场时增强了乔峰的声誉维护', '未直接介入但关注局势稳定', '见证了事件的发展并思考未来行动'],\n", + " 'utterances': ['event_004'],\n", + " 'speech_style': '沉静且观察',\n", + " 'personality_traits': ['观察者', '中立', '谨慎'],\n", + " 'emotion_state': '思考',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '尊敬',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:观察, impact:见证离开'},\n", + " {'target': '马夫人',\n", + " 'relation_type': '同情',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:听取诉说'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '敬畏',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:见证, impact:紧张局势'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '朝阳初升后',\n", + " 'location': '杏子林外',\n", + " 'event': '目睹乔峰选择退出丐帮,承受身份变故的冲击',\n", + " 'if_completed': True,\n", + " 'action': ['沉默并观察乔峰面对身份质疑', '见证乔峰摔断铁刀态度坚决', '保持内心思考而不言'],\n", + " 'motivation': ['理解人性之间的困境和选择', '学习丐帮和江湖风云'],\n", + " 'involved_entities': ['乔峰', '徐长老', '马夫人', '丐帮成员', '段誉', '王语嫣'],\n", + " 'impact': ['乔峰的行为使其陷入一种复杂的思考', '领悟深渊背后的痛苦与坚定'],\n", + " 'utterances': ['event_005'],\n", + " 'speech_style': '沉静且观察',\n", + " 'personality_traits': ['思考者', '内省', '理解'],\n", + " 'emotion_state': '复杂',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '敬佩与同情',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:观察, impact:理解选择'},\n", + " {'target': '丐帮',\n", + " 'relation_type': '观望',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:观察, impact:学习局势'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '秦红棉': {'name': '秦红棉',\n", + " 'first_appearance': 'chapters/chapter8',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林中',\n", + " 'location': '杏林',\n", + " 'event': '丐帮密谋废除帮主之位事件',\n", + " 'if_completed': True,\n", + " 'action': ['商讨废除乔峰帮主之位',\n", + " '囚禁传功、执法长老',\n", + " '参与会议讨论乔峰的契丹身份',\n", + " '公开乔峰的契丹身份',\n", + " '推动乔峰退位'],\n", + " 'motivation': ['为了丐帮的大业', '怀疑乔峰与慕容复勾结', '担心契丹后裔领导丐帮对中原带来威胁'],\n", + " 'involved_entities': ['乔峰', '吴长老', '全冠清', '宋奚陈吴四长老', '徐长老', '智光大师'],\n", + " 'impact': ['乔峰的权威受到挑战', '丐帮内部产生分裂', '乔峰自动退位', '丐帮群丐出现倒戈现象']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '巴天石': {'name': '巴天石',\n", + " 'first_appearance': 'chapters/chapter8',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '乘船逃离曼陀山庄后',\n", + " 'location': '太湖',\n", + " 'event': '巴天石帮助段誉逃离并计划前往少林寺支持慕容复',\n", + " 'if_completed': True,\n", + " 'action': ['协助段誉与王语嫣一行逃离曼陀山庄', '劝说王语嫣帮助慕容复'],\n", + " 'motivation': ['帮助段誉脱险', '劝说王语嫣出山'],\n", + " 'involved_entities': ['段誉', '阿朱', '阿碧', '王语嫣'],\n", + " 'impact': ['段誉更加信任巴天石', '王语嫣决定迈出保护慕容复的一步'],\n", + " 'utterances': [{'event_id': 'event_003', 'text': '我相信你能走出你的荆棘。'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['仁义', '忠诚'],\n", + " 'emotion_state': '果断',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:协助段誉与王语嫣一行逃离曼陀山庄'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '同道',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:劝说王语嫣帮助慕容复'}]},\n", + " {'event_id': 'event_004',\n", + " 'time': '在听香水榭的夜晚',\n", + " 'location': '听香水榭',\n", + " 'event': '被迫卷入慕容家族和其他势力的争斗',\n", + " 'if_completed': False,\n", + " 'action': ['关注阿朱及周围人的动向', '观察其他势力的动向'],\n", + " 'motivation': ['了解慕容复当前状况', '维护自身安全'],\n", + " 'involved_entities': ['阿朱', '阿碧', '王语嫣', '包不同', '司马林', '姚伯当'],\n", + " 'impact': ['增强了对慕容家族及周围势力的了解', '协调各方关系'],\n", + " 'utterances': [],\n", + " 'speech_style': '观察',\n", + " 'personality_traits': ['机警', '圆融'],\n", + " 'emotion_state': '警惕',\n", + " 'relations': [{'target': '阿朱',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:关注阿朱及周围人的动向'},\n", + " {'target': '包不同',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:观察其他势力的动向'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '杏子林争斗时',\n", + " 'location': '杏子林',\n", + " 'event': '巴天石观察丐帮内部斗争',\n", + " 'if_completed': False,\n", + " 'action': ['默默观察丐帮的内部斗争', '分析群丐与各个势力的关系'],\n", + " 'motivation': ['理解丐帮现状及权力斗争', '确保自己的安全与准确判断'],\n", + " 'involved_entities': ['乔峰', '白世镜', '吴长风', '段誉', '王语嫣'],\n", + " 'impact': ['进一步构思丐帮的真实状况', '提升自身谨慎分析能力'],\n", + " 'utterances': [{'event_id': 'event_005', 'text': '观察并不多言。'}],\n", + " 'speech_style': '沉稳',\n", + " 'personality_traits': ['谨慎', '敏感'],\n", + " 'emotion_state': '观察者',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同道',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:默默观察丐帮内部斗争'},\n", + " {'target': '白世镜',\n", + " 'relation_type': '观察',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:分析群丐与各个势力的关系'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '傅思归': {'name': '傅思归',\n", + " 'first_appearance': 'chapters/chapter8',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林变故后',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮叛乱处理',\n", + " 'if_completed': False,\n", + " 'action': ['参观丐帮内部争斗',\n", + " '评价事件的发展',\n", + " '感受到局势的紧张和谭婆赵钱孙等人的恩怨情仇',\n", + " '观察乔峰的反应',\n", + " '试图寻找证据证明乔峰的清白'],\n", + " 'motivation': ['着眼大局', '化解危机', '保护丐帮的名声和利益', '支持乔峰'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长老',\n", + " '宋奚陈吴四长老',\n", + " '白世镜',\n", + " '全冠清',\n", + " '徐长老',\n", + " '单正',\n", + " '谭公',\n", + " '谭婆',\n", + " '赵钱孙',\n", + " '智光大师',\n", + " '徐长老',\n", + " '马夫人',\n", + " '西夏使者'],\n", + " 'impact': ['帮助揭露丐帮叛乱阴谋', '增强内部团结', '提升乔峰的威望', '面临即将到来的西夏挑战'],\n", + " 'utterances': [{'time': 'event_001', 'content': '咱们丐帮这么做,不是自毁名声么?'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['沉着', '机智', '忠诚'],\n", + " 'emotion_state': '忧虑',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:参与事件, impact:对乔峰的支持和理解'},\n", + " {'target': '白世镜',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:参与事件, impact:对丐帮法度的认可'},\n", + " {'target': '赵钱孙',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:揭露其谎言, impact:造成其颜面尽失'},\n", + " {'target': '马夫人',\n", + " 'relation_type': '丐帮',\n", + " 'relation_strength': -0.3,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:观望, impact:马夫人对乔峰的怀疑'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '敬仰',\n", + " 'relation_strength': 0.2,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:聆听其言, impact:揭开乔峰身世'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '黄眉僧': {'name': '黄眉僧',\n", + " 'first_appearance': 'chapters/chapter8',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林中的夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内乱平定及黄眉僧旁观',\n", + " 'if_completed': True,\n", + " 'action': ['旁观众人对峙', '分析局势和人际关系', '观察乔峰的处理手段', '听取智光大师的陈述', '判断丐帮会议的决策'],\n", + " 'motivation': ['保持中立', '关注乔峰的影响力', '寻求自保和利益最大化'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长风',\n", + " '徐长老',\n", + " '智光大师',\n", + " '赵钱孙',\n", + " '单正',\n", + " '马夫人',\n", + " '全冠清',\n", + " '段誉',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '阿碧'],\n", + " 'impact': ['通过观察乔峰处理危机的方式对黄眉僧的未来策略产生影响',\n", + " '对丐帮的内部权利动态有了更清晰的认识',\n", + " '认识到丐帮帮主的重大变故和乔峰的困境'],\n", + " 'utterances': [{'event_id': 'event_001', 'utterance': '这许多人密谋反叛,究竟所为何事?'}],\n", + " 'speech_style': '观察者',\n", + " 'personality_traits': ['谨慎', '狡猾', '中立'],\n", + " 'emotion_state': '疑虑',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '敌意',\n", + " 'relation_strength': -0.3,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:旁观, impact:危机处理'},\n", + " {'target': '吴长风',\n", + " 'relation_type': '观察对象',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:观察对话, impact:了解局势'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '尊敬',\n", + " 'relation_strength': 0.2,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:听取陈述, impact:谨慎判断'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '破嗔': {'name': '破嗔',\n", + " 'first_appearance': 'chapters/chapter8',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '围观丐帮内变和乔峰被质疑',\n", + " 'if_completed': False,\n", + " 'action': ['观察丐帮内变进展',\n", + " '分析乔峰与丐帮关系',\n", + " '留意其他帮派的反应',\n", + " '注意智光大师的出现',\n", + " '思考乔峰的契丹人身份问题',\n", + " '关注西夏国势力的介入'],\n", + " 'motivation': ['评估乔峰在武林中的影响力', '保持中立观察事态发展'],\n", + " 'involved_entities': ['乔峰',\n", + " '丐帮长老',\n", + " '段誉',\n", + " '马夫人',\n", + " '谭公',\n", + " '谭婆',\n", + " '赵钱孙',\n", + " '单正',\n", + " '智光大师',\n", + " '西夏国势力'],\n", + " 'impact': ['对乔峰的能力与品行有了新的认识', '了解丐帮内部分裂加深对武林权力格局的理解', '意识到西夏国对中原武林的威胁'],\n", + " 'utterances': [{'time': 'event_003',\n", + " 'content': '这些变局真是叫人费心。那些丐帮长老竟也能误信谣言,又岂是乔帮主可一时解决之事。'}],\n", + " 'speech_style': '敏锐',\n", + " 'personality_traits': ['观察力强', '谨慎'],\n", + " 'emotion_state': '中立',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '好奇',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': '观察与分析乔峰面对困境的应对方式'},\n", + " {'target': '段誉',\n", + " 'relation_type': '友好',\n", + " 'relation_strength': 0.75,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': '共同经历事件并分享看法'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '尊敬',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': '第十六章 昔时因',\n", + " 'derived_from': '敬重智光大师的行为和观点'}]},\n", + " {'event_id': 'event_004',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '观望西夏国势力与丐帮的对峙',\n", + " 'if_completed': False,\n", + " 'action': ['分析西夏国势力与丐帮的冲突', '判断武林局势变化'],\n", + " 'motivation': ['理解外部力量对丐帮的可能威胁', '维护中原势力的平衡'],\n", + " 'involved_entities': ['西夏国势力', '丐帮成员', '赫连铁树', '云中鹤', '段誉'],\n", + " 'impact': ['增强对外部势力介入中原武林的警惕']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '破疑': {'name': '破疑',\n", + " 'first_appearance': 'chapters/chapter8',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内乱与帮主之位交替',\n", + " 'if_completed': True,\n", + " 'action': ['分析乔峰的所作所为并提出质疑', '建议自行了断', '因乔峰自愿退位,事件结束'],\n", + " 'motivation': ['追求丐帮的安稳', '担忧乔峰可能的阴谋', '寻求真相并维护帮规'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长风',\n", + " '宋长老',\n", + " '奚长老',\n", + " '陈长老',\n", + " '全冠清',\n", + " '徐长老',\n", + " '智光大师',\n", + " '赵钱孙'],\n", + " 'impact': ['导致帮派内紧张局势', '影响乔峰的领导权威', '促使乔峰主动退位,丐帮重新面临帮主继任问题'],\n", + " 'utterances': ['我们大伙儿商量了,要废去你的帮主之位。'],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['直言不讳', '忠于帮规'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:建议废去帮主之位, impact:影响乔峰的领导权威'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '杏子林事件',\n", + " 'location': '杏子林',\n", + " 'event': '马大元死因调查与真相揭露',\n", + " 'if_completed': True,\n", + " 'action': ['参与讨论马大元之死', '与乔峰的对峙'],\n", + " 'motivation': ['寻求真相', '对乔峰的不信任'],\n", + " 'involved_entities': ['乔峰', '马夫人', '徐长老', '单正', '赵钱孙'],\n", + " 'impact': ['疑惑丛生', '丐帮内部的派系冲突激化', '引发乔峰的反思与自我探寻'],\n", + " 'utterances': ['乔峰,你好泰然自若! 难道你自己真的不知?'],\n", + " 'speech_style': '质疑',\n", + " 'personality_traits': ['审慎', '怀疑'],\n", + " 'emotion_state': '不安',\n", + " 'relations': []}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '延庆太子': {'name': '延庆太子',\n", + " 'first_appearance': 'chapters/chapter8',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '第十五章 杏子林中 商略平生义',\n", + " 'location': '杏子林',\n", + " 'event': '监听丐帮内乱与乔峰的帮会决策',\n", + " 'if_completed': True,\n", + " 'action': ['隐身观察丐帮的内斗', '分析丐帮长老与乔峰的策略'],\n", + " 'motivation': ['了解丐帮内部动向', '分析乔峰的领导能力'],\n", + " 'involved_entities': ['乔峰', '白世镜', '吴长风', '全冠清', '徐长老', '赵钱孙', '谭公、谭婆'],\n", + " 'impact': ['对丐帮的内情有了更多了解', '对乔峰的决策风格有了更深的认识'],\n", + " 'utterances': [],\n", + " 'speech_style': '沉稳、观察入微',\n", + " 'personality_traits': ['洞察力强', '谨慎'],\n", + " 'emotion_state': '平静',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '观察对象',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': '观察乔峰处理丐帮内乱的行为'},\n", + " {'target': '白世镜',\n", + " 'relation_type': '中立者',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': '观察其执行帮规行为'},\n", + " {'target': '吴长风',\n", + " 'relation_type': '观察对象',\n", + " 'relation_strength': -0.3,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': '参与叛乱行为'},\n", + " {'target': '全冠清',\n", + " 'relation_type': '敌对观察',\n", + " 'relation_strength': -0.7,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': '观察其煽动叛乱行为'}]},\n", + " {'event_id': 'event_004',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '雁门关事件的揭露与乔峰身世的冲击',\n", + " 'if_completed': False,\n", + " 'action': ['观察乔峰对雁门关事件揭露的反应', '分析丐帮各派势力的动向'],\n", + " 'motivation': ['理解乔峰身份揭示后的丐帮反应', '观察未来丐帮的动荡发展'],\n", + " 'involved_entities': ['乔峰', '徐长老', '马夫人', '赵钱孙', '智光大师', '丐帮众人'],\n", + " 'impact': ['获知乔峰的契丹身份带来的帮内动荡', '观察到丐帮可能的分裂与重组的风险'],\n", + " 'utterances': [],\n", + " 'speech_style': '沉稳、洞察性强',\n", + " 'personality_traits': ['理智', '观察力强'],\n", + " 'emotion_state': '警觉',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '观察对象',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': '观察乔峰身份揭露后的行为影响'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '观察对象',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': '对雁门关事件揭露的影响'},\n", + " {'target': '徐长老',\n", + " 'relation_type': '中立者',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': '丐帮长老面对危机的领导行为'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '华司徒': {'name': '华司徒',\n", + " 'first_appearance': 'chapters/chapter9',\n", + " 'events': [{'event_id': 'event_002',\n", + " 'time': '接近午时',\n", + " 'location': '无锡城畔',\n", + " 'event': '帮助乔峰化解丐帮内乱',\n", + " 'if_completed': False,\n", + " 'action': ['观察丐帮形势', '出手救治风波恶', '与乔峰一起面对丐帮叛乱', '见证杏子林丐帮内部审判'],\n", + " 'motivation': ['维护正义感', '兄弟情义', '支持乔峰打破谣言'],\n", + " 'involved_entities': ['乔峰', '风波恶', '丐帮帮众', '四大长老'],\n", + " 'impact': ['帮助乔峰巩固了帮内权威', '澄清乔峰的无辜,平息内乱', '为乔峰和丐帮带来和解的机会'],\n", + " 'utterances': [{'time': '接近午时',\n", + " 'text': '乔帮主继任上代汪帮主为本帮首领,并非巧取豪夺。',\n", + " 'event_id': 'event_002'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['善良', '忠诚'],\n", + " 'emotion_state': '坚定',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '兄弟',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:帮助乔峰, impact:澄清乔峰的无辜'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '天已全黑',\n", + " 'location': '杏子林',\n", + " 'event': '见证丐帮内乱审判',\n", + " 'if_completed': True,\n", + " 'action': ['旁观并支持乔峰审判叛乱者', '见证全冠清、四大长老的审判'],\n", + " 'motivation': ['维护丐帮正义', '支持乔峰领导'],\n", + " 'involved_entities': ['乔峰', '全冠清', '宋奚陈吴四长老', '马夫人'],\n", + " 'impact': ['协助乔峰定帮规,重建丐帮的秩序'],\n", + " 'utterances': [{'time': '天已全黑',\n", + " 'text': '帮主待人仁义,处事么允,咱们大伙儿拥戴尚自不及。',\n", + " 'event_id': 'event_003'}],\n", + " 'speech_style': '文雅',\n", + " 'personality_traits': ['冷静', '公正'],\n", + " 'emotion_state': '平静',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'impact:协助乔峰定帮规'},\n", + " {'target': '全冠清',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:支持审判'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '范司马': {'name': '范司马',\n", + " 'first_appearance': 'chapters/chapter9',\n", + " 'events': [{'event_id': 'event_005',\n", + " 'time': '第十三章 水榭听香',\n", + " 'location': '听香水榭',\n", + " 'event': '卷入青城派与秦家寨争斗',\n", + " 'if_completed': False,\n", + " 'action': ['与阿朱、阿碧、王语嫣共同行动', '观察青城派与秦家寨的争斗', '试图保护王语嫣', '劝说王语嫣关于乔峰的事情'],\n", + " 'motivation': ['保护王语嫣', '弄清青城派与慕容家的争端原因', '维护乔峰的声誉'],\n", + " 'involved_entities': ['阿朱', '阿碧', '王语嫣', '青城派', '秦家寨', '包不同', '乔峰'],\n", + " 'impact': ['增强青城派与秦家寨的不了', '增进与王语嫣的理解', '使包不同对他产生了些许警觉', '提升对乔峰的信任'],\n", + " 'utterances': [{'event_id': 'event_005',\n", + " 'content': '我若能一辈子逗你喜笑颜开,此生复有何求?'}],\n", + " 'speech_style': '直率',\n", + " 'personality_traits': ['勇敢', '直率'],\n", + " 'emotion_state': '矛盾',\n", + " 'relations': [{'target': '包不同',\n", + " 'relation_type': '观察者',\n", + " 'relation_strength': 0.1,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:观察青城派与秦家寨的争斗'},\n", + " {'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:维护乔峰的声誉'}]},\n", + " {'event_id': 'event_007',\n", + " 'time': '第十五章 杏子林中 商略平生义',\n", + " 'location': '杏子林',\n", + " 'event': '参与丐帮议事,维护乔峰',\n", + " 'if_completed': False,\n", + " 'action': ['观察丐帮内部纷争', '与王语嫣等保持距离', '支持乔峰,反对全冠清'],\n", + " 'motivation': ['支持兄弟乔峰', '维护大宋和丐帮的安定', '维护自身与乔峰的关系'],\n", + " 'involved_entities': ['乔峰',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '阿碧',\n", + " '全冠清',\n", + " '单正',\n", + " '包不同',\n", + " '谭公',\n", + " '谭婆'],\n", + " 'impact': ['促进乔峰在丐帮的影响', '加强与王语嫣的情感纽带'],\n", + " 'utterances': [{'event_id': 'event_007', 'content': '我相信乔帮主,他从没有做过亏心之事。'}],\n", + " 'speech_style': '坚定',\n", + " 'personality_traits': ['忠诚', '坚定'],\n", + " 'emotion_state': '坚毅',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 1.0,\n", + " 'last_updated': 'event_007',\n", + " 'derived_from': 'action:支持乔峰'}]},\n", + " {'event_id': 'event_008',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '揭示乔峰身世,丐帮与西夏对峙',\n", + " 'if_completed': True,\n", + " 'action': ['观察丐帮与西夏的对峙', '对乔峰揭示身世感到震惊', '在混乱中留意特殊人物'],\n", + " 'motivation': ['关注乔峰的安危', '试图洞悉丐帮内部分歧', '了解西夏势力的动向'],\n", + " 'involved_entities': ['乔峰', '徐长老', '白世镜', '全冠清', '西夏使者', '智光大师', '赵钱孙'],\n", + " 'impact': ['加剧丐帮内部动荡', '形成对西夏的警惕'],\n", + " 'utterances': [{'event_id': 'event_008',\n", + " 'content': '眼见证据确凿,连乔峰自己似乎也已信了。'}],\n", + " 'speech_style': '观察者',\n", + " 'personality_traits': ['敏锐', '冷静'],\n", + " 'emotion_state': '复杂',\n", + " 'relations': [{'target': '徐长老',\n", + " 'relation_type': '观察者',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_008',\n", + " 'derived_from': 'action:注视丐帮与西夏的对峙'},\n", + " {'target': '西夏使者',\n", + " 'relation_type': '敌意',\n", + " 'relation_strength': -0.7,\n", + " 'last_updated': 'event_008',\n", + " 'derived_from': 'action:形成对西夏的警惕'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '辛双清': {'name': '辛双清',\n", + " 'first_appearance': 'chapters/chapter9',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '卯时已过',\n", + " 'location': '杏子林',\n", + " 'event': '被丐帮揭发身世,辞去帮主职位',\n", + " 'if_completed': True,\n", + " 'action': ['辞去丐帮帮主职务', '放下打狗棒', '拒绝与丐帮众人冲突'],\n", + " 'motivation': ['寻找自己的真实身世', '避免丐帮自相残杀'],\n", + " 'involved_entities': ['徐长老', '宋长老', '丐帮帮众'],\n", + " 'impact': ['导致丐帮帮主职位空缺', '引发丐帮内部分裂'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'content': '青山不改,绿水长流,众位好兄弟,咱们再见了。'}],\n", + " 'speech_style': '慷慨而直接',\n", + " 'personality_traits': ['责任感强', '慷慨大方'],\n", + " 'emotion_state': '复杂与失落',\n", + " 'relations': [{'target': '丐帮',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:辞去职务, impact:分裂'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '崔百泉': {'name': '崔百泉',\n", + " 'first_appearance': 'chapters/chapter9',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '三十年前',\n", + " 'location': '雁门关乱石谷',\n", + " 'event': '契丹武士伏击战',\n", + " 'if_completed': True,\n", + " 'action': ['参与伏击契丹武士', '杀害契丹武士'],\n", + " 'motivation': ['保卫少林寺秘藏', '维护大宋安全'],\n", + " 'involved_entities': ['乔峰', '汪帮主', '契丹武士'],\n", + " 'impact': ['杀死多名契丹武士', '引发误会'],\n", + " 'utterances': [{'time': 'event_001', 'quote': '冤家宜解不宜结,何必旧事重提?'}],\n", + " 'speech_style': '直率',\n", + " 'personality_traits': ['慈悲', '矛盾'],\n", + " 'emotion_state': '复杂',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '复杂关系',\n", + " 'relation_strength': -0.2,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:杀害, impact:误会'},\n", + " {'target': '汪帮主',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:参与伏击, impact:保卫'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '当前',\n", + " 'location': '杏子林',\n", + " 'event': '揭露乔峰身世',\n", + " 'if_completed': True,\n", + " 'action': ['揭露乔峰身世', '阅读并撕毁书信'],\n", + " 'motivation': ['告知真相', '保护乔峰'],\n", + " 'involved_entities': ['乔峰', '赵钱孙', '徐长老'],\n", + " 'impact': ['令乔峰身份暴露', '丐帮内部动荡'],\n", + " 'utterances': [{'time': 'event_002',\n", + " 'quote': '倘若真相确是如此,不但殉难的十七名兄弟死得冤枉,这些契丹人也是无辜受累。'}],\n", + " 'speech_style': '古典',\n", + " 'personality_traits': ['诚实', '慈悲'],\n", + " 'emotion_state': '悲悯'}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '过彦之': {'name': '过彦之',\n", + " 'first_appearance': 'chapters/chapter9',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮帮会议事件',\n", + " 'if_completed': True,\n", + " 'action': ['参加丐帮会议', '质问赵钱孙关于乔峰是否是契丹人', '听取智光大师陈述雁门关往事', '对乔峰的决断表示沉默'],\n", + " 'motivation': ['追寻乔峰的真实身份', '弄清雁门关往事'],\n", + " 'involved_entities': ['赵钱孙', '乔峰', '智光大师', '徐长老'],\n", + " 'impact': ['促使乔峰怀疑自己的身世', '引发动荡导致乔峰辞去帮主之位'],\n", + " 'utterances': [{'timestamp': 'event_001',\n", + " 'text': '你们到底怎样对不起他?汉人和契丹相斫相杀,有什么对得起、对不起之可言?'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['冷静', '严谨'],\n", + " 'emotion_state': '复杂',\n", + " 'relations': [{'target': '赵钱孙',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:质问, impact:怀疑乔峰身份'},\n", + " {'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:旁观, impact:乔峰辞去帮主席位'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '慧真': {'name': '慧真',\n", + " 'first_appearance': 'chapters/chapter9',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '参加丐帮大会',\n", + " 'if_completed': False,\n", + " 'action': ['听闻自己身世的揭露', '打破马夫人的指控', '放弃丐帮帮主之位', '确保不再杀害汉人', '展示强大武功'],\n", + " 'motivation': ['清楚自己的身世', '维护自己的名声', '不愿与同伴冲突'],\n", + " 'involved_entities': ['丐帮成员', '徐长老', '马夫人', '智光大师'],\n", + " 'impact': ['自己接受到身世打击', '对丐帮内部产生巨大的震动', '触发有关自身身世的重大争议']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '慧观': {'name': '慧观',\n", + " 'first_appearance': 'chapters/chapter9',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林中的夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '参与处理丐帮叛乱',\n", + " 'if_completed': True,\n", + " 'action': ['陪同乔峰见证丐帮的叛乱处理', '听取众人对事件的讨论', '观察智光大师审视书信并护送乔峰'],\n", + " 'motivation': ['支持帮主乔峰', '维护丐帮规矩和声誉'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长风',\n", + " '宋奚陈吴四长老',\n", + " '白世镜',\n", + " '全冠清',\n", + " '马夫人',\n", + " '徐长老',\n", + " '谭公',\n", + " '谭婆',\n", + " '赵钱孙',\n", + " '智光大师'],\n", + " 'impact': ['帮助乔峰稳定局势', '见证马夫人揭露重要信件内容'],\n", + " 'utterances': [],\n", + " 'speech_style': '沉默',\n", + " 'personality_traits': ['忠诚', '明辨是非'],\n", + " 'emotion_state': '镇静',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:陪同乔峰见证丐帮的叛乱处理'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '尊敬',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'impact:智光大师综合了事件并审视书信内容'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '杏子林叛乱结束后',\n", + " 'location': '杏子林',\n", + " 'event': '遭遇西夏一品堂',\n", + " 'if_completed': False,\n", + " 'action': ['观察西夏一品堂挑衅', '评估局势'],\n", + " 'motivation': ['保护丐帮利益'],\n", + " 'involved_entities': ['赫连铁树', '努儿海', '南海鳄神', '云中鹤', '西夏骑士'],\n", + " 'impact': ['未能阻止西夏一品堂的挑衅'],\n", + " 'utterances': [{'event_id': 'event_002',\n", + " 'content': '处事须审慎,勿急躁。',\n", + " 'time': '事件后期'}],\n", + " 'speech_style': '谨慎',\n", + " 'personality_traits': ['冷静', '谨慎'],\n", + " 'emotion_state': '忧虑',\n", + " 'relations': [{'target': '赫连铁树',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.6,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'impact:未能阻止西夏一品堂的挑衅'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '鸠摩智': {'name': '鸠摩智',\n", + " 'first_appearance': 'chapters/chapter9',\n", + " 'events': [{'event_id': 'event_004',\n", + " 'time': '第十五章 杏子林中',\n", + " 'location': '杏子林',\n", + " 'event': '鸠摩智追随乔峰于杏子林',\n", + " 'if_completed': False,\n", + " 'action': ['追问乔峰对马副帮主之死的看法'],\n", + " 'motivation': ['探明马副帮主之死背后的真相'],\n", + " 'involved_entities': ['乔峰', '马夫人', '单正', '谭公', '谭婆', '赵钱孙'],\n", + " 'impact': ['挑起乔峰对马副帮主之死的询问,引发丐帮内部猜疑'],\n", + " 'utterances': [{'time': 'event_004',\n", + " 'content': '你这等口气使得不错。这面可是要跟这一个人,也许大家都嫌安静。'}],\n", + " 'speech_style': '间接',\n", + " 'personality_traits': ['狡猾', '操控欲强', '好奇'],\n", + " 'emotion_state': '审慎',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:询问'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮聚会揭露乔峰身世',\n", + " 'if_completed': False,\n", + " 'action': ['见证丐帮内部关于乔峰身份的争论'],\n", + " 'motivation': ['维持丐帮现状,观察事件发展'],\n", + " 'involved_entities': ['乔峰', '徐长老', '赵钱孙', '单正', '谭公', '马夫人'],\n", + " 'impact': ['目睹乔峰被质疑为契丹人,引发丐帮内部的矛盾与动荡'],\n", + " 'utterances': [{'time': 'event_005', 'content': '在其位谋其政,公理自在人心。'}],\n", + " 'speech_style': '古典',\n", + " 'personality_traits': ['冷静', '观察敏锐', '中立'],\n", + " 'emotion_state': '冷静',\n", + " 'relations': [{'target': '丐帮',\n", + " 'relation_type': '中立',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:见证'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '枯荣大师': {'name': '枯荣大师',\n", + " 'first_appearance': 'chapters/chapter10',\n", + " 'events': [{'event_id': 'event_002',\n", + " 'time': '当日晚间',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮危机介入',\n", + " 'if_completed': False,\n", + " 'action': ['留意丐帮的危险局势', '保护王语嫣、阿朱和阿碧', '观察丐帮内部的动荡和变化', '跟随局势变化进行调停'],\n", + " 'motivation': ['持续保护王语嫣和慕容家的利益', '确保事件不失控', '理解事件的真相并保护己方'],\n", + " 'involved_entities': ['乔峰',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '阿碧',\n", + " '包不同',\n", + " '风波恶',\n", + " '吴长风',\n", + " '宋长老',\n", + " '奚长老',\n", + " '陈长老',\n", + " '徐长老',\n", + " '谭婆',\n", + " '谭公',\n", + " '赵钱孙',\n", + " '单正',\n", + " '马夫人',\n", + " '智光',\n", + " '赵钱孙',\n", + " '段誉'],\n", + " 'impact': ['介入丐帮内务,影响力量对比', '影响丐帮内部对乔峰的看法,调整行动策略'],\n", + " 'utterances': [{'event_id': 'event_002',\n", + " 'text': '这几句话说得甚是诚恳,这副莽莽苍苍的英雄气概,谁都不能有丝毫怀疑。'}],\n", + " 'speech_style': '古怪、挖苦',\n", + " 'personality_traits': ['机智', '富有策略', '忠于慕容家'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:观察丐帮内部的动荡和变化, impact:影响丐帮内部对乔峰的看法'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '庇护者',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:保护王语嫣, impact:影响保护对象的安全'},\n", + " {'target': '阿朱',\n", + " 'relation_type': '庇护者',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:保护阿朱, impact:影响保护对象的安全'},\n", + " {'target': '阿碧',\n", + " 'relation_type': '庇护者',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:保护阿碧, impact:影响保护对象的安全'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '当日晚间',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内斗 наблюдение',\n", + " 'if_completed': True,\n", + " 'action': ['分析丐帮内部纷争', '观看赵钱孙与谭氏伉俪的互动', '评估丐帮对于慕容家的态度', '目睹事件发展并未直接干预'],\n", + " 'motivation': ['了解丐帮内部变化', '保护盟友', '维护自身及伙伴的安全'],\n", + " 'involved_entities': ['乔峰', '赵钱孙', '谭婆', '谭公', '单正', '马夫人', '智光'],\n", + " 'impact': ['深化对丐帮内部势力的了解,准备应对潜在的冲突', '评估事件可能对慕容家的影响', '提升对局势复杂性的认识'],\n", + " 'utterances': [],\n", + " 'speech_style': '古怪、挖苦',\n", + " 'personality_traits': ['机智', '富有策略', '忠于慕容家'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '谭婆',\n", + " 'relation_type': '不相关',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:观看赵钱孙与谭氏伉俪的互动'},\n", + " {'target': '谭公',\n", + " 'relation_type': '不相关',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:观看赵钱孙与谭氏伉俪的互动'},\n", + " {'target': '赵钱孙',\n", + " 'relation_type': '不相关',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:观看赵钱孙与谭氏伉俪的互动'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '本因大师': {'name': '本因大师',\n", + " 'first_appearance': 'chapters/chapter10',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '见证丐帮大内乱的解决',\n", + " 'if_completed': True,\n", + " 'action': ['观察吴长风承认叛逆',\n", + " '见证乔峰展示领导风范',\n", + " '对谭公谭婆的见解',\n", + " '听智光大师讲述旧事',\n", + " '观察乔峰自愿辞去帮主之位',\n", + " '分析局势及各方立场'],\n", + " 'motivation': ['判断丐帮局势', '评估乔峰的能力和忠诚', '理解丐帮与西夏交集的原因'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长风',\n", + " '谭公',\n", + " '谭婆',\n", + " '徐长老',\n", + " '智光大师',\n", + " '马夫人',\n", + " '赵钱孙',\n", + " '西夏赫连铁树'],\n", + " 'impact': ['目睹丐帮处理叛乱的过程', '理解丐帮内部的复杂关系', '观察西夏武士与丐帮对峙的情势']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '本观': {'name': '本观',\n", + " 'first_appearance': 'chapters/chapter10',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十五章, 杏子林中至第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮叛乱平息与马大元遗书的秘密',\n", + " 'if_completed': True,\n", + " 'action': ['与丐帮众长老及群丐会面', '分析并讨论丐帮内乱', '观察并推测叛乱的后续影响', '听闻智光大师对乔峰真实身份的揭露'],\n", + " 'motivation': ['维护丐帮的声誉和内部分裂', '探求真相以还丐帮清白', '了解关于乔峰身世的真相'],\n", + " 'involved_entities': ['乔峰',\n", + " '白世镜',\n", + " '吴长风',\n", + " '马夫人',\n", + " '赵钱孙',\n", + " '谭公',\n", + " '谭婆',\n", + " '单正',\n", + " '全冠清',\n", + " '智光'],\n", + " 'impact': ['加深了乔峰对事件复杂性的理解', '促进了内部审视,关乎乔峰的名声与清白', '引发丐帮关于帮主资格的争议,影响帮内稳定'],\n", + " 'utterances': [{'event_id': 'event_001', 'speech': '于此事,我无可奉告,唯心中感慨良多。'}],\n", + " 'speech_style': '古典,内敛',\n", + " 'personality_traits': ['沉稳', '观察敏锐', '内省'],\n", + " 'emotion_state': '忧虑',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:听闻揭露, impact:帮内争议'},\n", + " {'target': '吴长风',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': -0.2,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'impact:内部审视'},\n", + " {'target': '全冠清',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:观察推测, impact:内部危机'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '本参': {'name': '本参',\n", + " 'first_appearance': 'chapters/chapter10',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '三十余年前',\n", + " 'location': '雁门关外乱石谷',\n", + " 'event': '与契丹武士的遭遇战',\n", + " 'if_completed': True,\n", + " 'action': ['参与伏击契丹武士', '目击战斗场面', '未能下手杀契丹婴儿'],\n", + " 'motivation': ['拯救少林寺秘笈不被契丹夺取', '保护中原安危'],\n", + " 'involved_entities': ['契丹武士', '大宋中原豪杰', '汪帮主', '赵钱孙'],\n", + " 'impact': ['导致契丹武士家破之灾', '埋伏十八名同伴', '收养契丹婴儿乔峰'],\n", + " 'utterances': [{'event_001': '文中无具体情节记载智光在此事件的言语'}],\n", + " 'speech_style': '慷慨激昂',\n", + " 'personality_traits': ['仁慈', '勇敢', '矛盾'],\n", + " 'emotion_state': '悔恨',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '间接长辈',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:目击战斗, impact:收养乔峰'},\n", + " {'target': '汪剑通',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:参与伏击契丹武士, impact:同伴关系'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '今日',\n", + " 'location': '杏子林',\n", + " 'event': '揭露乔峰身世谜团',\n", + " 'if_completed': False,\n", + " 'action': ['面见丐帮长老和帮众', '坦诚旧事', '撕掉书信'],\n", + " 'motivation': ['解除乔峰心中疑惑', '维护武林和平', '避免更多误会'],\n", + " 'involved_entities': ['乔峰', '丐帮长老', '马夫人'],\n", + " 'impact': ['引发乔峰对自身身世真相的思考', '导致帮中关于乔峰身份的争执'],\n", + " 'utterances': [{'event_002': '杀孽太重,杀孽太重!此事言之有愧。'},\n", + " {'event_002': '冤家宜解不宜结,何必旧事重提?'},\n", + " {'event_002': '那也说得是,那也说得是。'}],\n", + " 'speech_style': '慈悲惜肉',\n", + " 'personality_traits': ['仁慈', '坦诚', '追悔'],\n", + " 'emotion_state': '内疚与平和',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '间接长辈',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:揭露真相, impact:引发乔峰反应'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '本相': {'name': '本相',\n", + " 'first_appearance': 'chapters/chapter10',\n", + " 'events': [{'event_id': 'event_002',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '因乔峰身世揭露引发的系列冲突',\n", + " 'if_completed': True,\n", + " 'action': ['参与揭露乔峰的契丹身份事件', '见证乔峰退位', '目睹丐帮内部的分裂'],\n", + " 'motivation': ['静观事态发展', '理解乔峰与丐帮关系的动态'],\n", + " 'involved_entities': ['乔峰', '徐长老', '马夫人', '智光大师', '赵钱孙'],\n", + " 'impact': ['导致乔峰辞去丐帮帮主职位', '加深对乔峰身世的了解'],\n", + " 'utterances': [{'event_id': 'event_002',\n", + " 'content': '爱慕王语嫣,对慕容复嫉妒,令我心困忧扰。'}],\n", + " 'speech_style': '内省',\n", + " 'personality_traits': ['多情', '敏感'],\n", + " 'emotion_state': '困惑',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '爱情',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': '第十四章',\n", + " 'derived_from': 'action:在湖上独自划船, impact:心灵的困惑与自我反思'},\n", + " {'target': '慕容复',\n", + " 'relation_type': '竞争对手',\n", + " 'relation_strength': -0.3,\n", + " 'last_updated': '第十四章',\n", + " 'derived_from': 'motivation:对慕容复的嫉妒, impact:心灵的困惑与自我反思'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '遭遇西夏一品堂的袭击',\n", + " 'if_completed': False,\n", + " 'action': ['试图理解丐帮与西夏的冲突', '见证到悲酥清风袭来,丐帮众人陷入危机'],\n", + " 'motivation': ['维护丐帮的利益', '探查西夏人的企图'],\n", + " 'involved_entities': ['徐长老', '努儿海', '赫连铁树', '段誉', '王语嫣'],\n", + " 'impact': ['丐帮遭到重创,王语嫣被段誉救走'],\n", + " 'utterances': [{'event_id': 'event_003',\n", + " 'content': '乔峰,大丈夫行事,对就是对,错就是错,请公允处理此事。'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['正直', '勇敢'],\n", + " 'emotion_state': '坚定',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': '第十五章',\n", + " 'derived_from': 'action:支持乔峰维护帮规, impact:巩固丐帮的稳定局面'},\n", + " {'target': '吴长风',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': -0.1,\n", + " 'last_updated': '第十五章',\n", + " 'derived_from': 'impact:帮助乔峰平息叛乱'},\n", + " {'target': '全冠清',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': '第十五章',\n", + " 'derived_from': 'involved_entities:全冠清'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '慕容博': {'name': '慕容博',\n", + " 'first_appearance': 'chapters/chapter10',\n", + " 'events': [{'event_id': 'event_004',\n", + " 'time': '杏子林中夜露未干',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮变故与段誉掺入',\n", + " 'if_completed': False,\n", + " 'action': ['观察丐帮内乱', '与王语嫣、阿朱、阿碧参与旁观', '对智光讲述丐帮变故的反应'],\n", + " 'motivation': ['对乔峰的信任和同门情谊', '为丐帮内部的正义与真相而关心'],\n", + " 'involved_entities': ['乔峰', '王语嫣', '阿朱', '阿碧', '丐帮众人', '全冠清', '智光大师'],\n", + " 'impact': ['加剧丐帮内部的分裂', '影响乔峰对自身身份的思考', '令丐帮对外部威胁更加敏感'],\n", + " 'utterances': [{'event_id': 'event_004',\n", + " 'text': '非也,非也!我不是慕容复的朋友,我从未见过慕容公子之面,这三位,说是慕容公子的家人亲戚则可,说是眷属却未必。'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['机敏', '忠诚'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '义兄弟',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:观察丐帮内乱, impact:乔峰对局势的影响'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '倾慕者',\n", + " 'relation_strength': 1,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:与王语嫣旁观丐帮变故'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '尊敬',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:对智光讲述丐帮变故的反应'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '慕容先生': {'name': '慕容先生',\n", + " 'first_appearance': 'chapters/chapter11',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子树后',\n", + " 'event': '揭露乔峰身世',\n", + " 'if_completed': True,\n", + " 'action': ['听智光大师讲述', '遵从徐长老决定', '确认遗书真伪'],\n", + " 'motivation': ['探明真相', '还原事件真相', '秉持公正'],\n", + " 'involved_entities': ['智光大师', '乔峰', '徐长老', '赵钱孙'],\n", + " 'impact': ['引发乔峰身份危机', '影响丐帮帮主继承'],\n", + " 'utterances': [{'text': '青山不改,绿水长流,众位好兄弟,咱们再见了。乔某是汉人也好,是契丹人也好,有生之年,决不伤一条汉人的性命,若违此誓,有如此刀。',\n", + " 'time': '第十六章 昔时因'}],\n", + " 'speech_style': '慷慨激昂',\n", + " 'personality_traits': ['果断', '讲求公义'],\n", + " 'emotion_state': '愤慨',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'impact: 乔峰身份危机'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '阿碧': {'name': '阿碧',\n", + " 'first_appearance': 'chapters/chapter11',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十五章,杏子林中',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内斗围观',\n", + " 'if_completed': True,\n", + " 'action': ['与段誉、王语嫣及阿朱围观丐帮事务', '保持缄默,默不作声', '观察众人动静'],\n", + " 'motivation': ['保持中立,不干涉丐帮内务'],\n", + " 'involved_entities': ['段誉', '王语嫣', '阿朱', '乔峰', '丐帮众人'],\n", + " 'impact': ['知悉丐帮动荡内情', '评估乔峰及其他丐帮高层的秉性', '对后续事件可能产生策略性影响'],\n", + " 'utterances': [],\n", + " 'speech_style': '缄默保持中立',\n", + " 'personality_traits': ['冷静'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '友好旁观者',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:观察, impact:评估乔峰及其他丐帮高层的秉性'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '西夏一品堂袭击杏子林',\n", + " 'if_completed': False,\n", + " 'action': ['继续观察并未参与冲突', '留意西夏一品堂的动向'],\n", + " 'motivation': ['避免卷入冲突'],\n", + " 'involved_entities': ['段誉',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '乔峰',\n", + " '徐长老',\n", + " '传功长老',\n", + " '执法长老',\n", + " '西夏一品堂'],\n", + " 'impact': ['对西夏一品堂的威胁有更深刻的认知', '与朋友们的关系得到确认与加强'],\n", + " 'utterances': [],\n", + " 'speech_style': '静观其变',\n", + " 'personality_traits': ['谨慎', '观察敏锐'],\n", + " 'emotion_state': '警惕',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:观望, impact:与朋友们的关系得到确认与加强'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:观望, impact:与朋友们的关系得到确认与加强'},\n", + " {'target': '阿朱',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:观望, impact:与朋友们的关系得到确认与加强'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '阿朱': {'name': '阿朱',\n", + " 'first_appearance': 'chapters/chapter11',\n", + " 'events': [{'event_id': 'event_006',\n", + " 'time': '第十五章 杏子林中 商略平生义',\n", + " 'location': '杏子林',\n", + " 'event': '目睹丐帮内乱和对峙',\n", + " 'if_completed': False,\n", + " 'action': ['悄然观望丐帮内乱', '保持低调尽量避免介入丐帮事务', '暗中关注事件发展'],\n", + " 'motivation': ['保持中立,不露声色', '观察情况,避免危险'],\n", + " 'involved_entities': ['乔峰', '段誉', '王语嫣', '阿碧', '吴长风', '白世镜', '全冠清', '徐长老'],\n", + " 'impact': ['保持局外人角色,未引起丐帮的疑心', '支持乔峰以理服众的行为解决内乱'],\n", + " 'utterances': [{'event_id': 'event_006',\n", + " 'content': '见乔峰平定逆乱,将反叛者一一制望,自是代他欢喜。'}],\n", + " 'speech_style': '文雅',\n", + " 'personality_traits': ['观察力敏锐', '沉稳'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'action:支持乔峰, motivation:保持中立'},\n", + " {'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'action:一同观察事情发展'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'impact:共处逆境'}]},\n", + " {'event_id': 'event_007',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '面临西夏武士的威胁与斗争',\n", + " 'if_completed': False,\n", + " 'action': ['观察风云突变,评判丐帮与西夏武士的对峙', '意识到局势复杂,未直接插手'],\n", + " 'motivation': ['希望自保,不卷入多方势力争端', '观察各方表现,理解局势全貌'],\n", + " 'involved_entities': ['徐长老', '白世镜', '赫连铁树', '努儿海', '段誉', '王语嫣'],\n", + " 'impact': ['成为安静旁观者,未让任何一方注意此时的存在'],\n", + " 'utterances': [],\n", + " 'speech_style': '文雅',\n", + " 'personality_traits': ['谨慎', '沉稳'],\n", + " 'emotion_state': '警觉',\n", + " 'relations': [{'target': '徐长老',\n", + " 'relation_type': '普通',\n", + " 'relation_strength': 0.1,\n", + " 'last_updated': 'event_007',\n", + " 'derived_from': 'action:观察与评判'},\n", + " {'target': '白世镜',\n", + " 'relation_type': '普通',\n", + " 'relation_strength': 0.1,\n", + " 'last_updated': 'event_007',\n", + " 'derived_from': 'action:观察与评判'},\n", + " {'target': '赫连铁树',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.3,\n", + " 'last_updated': 'event_007',\n", + " 'derived_from': 'action:评判与局势关系'},\n", + " {'target': '努儿海',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.3,\n", + " 'last_updated': 'event_007',\n", + " 'derived_from': 'action:评判与局势关系'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '幽草': {'name': '幽草',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '乔峰被揭露契丹身世的聚会',\n", + " 'if_completed': False,\n", + " 'action': ['参加了聚会', '听闻智光大师讲述雁门关事件'],\n", + " 'motivation': ['寻找关于乔峰身世的真相'],\n", + " 'involved_entities': ['乔峰', '智光大师', '丐帮众人', '徐长老', '赵钱孙'],\n", + " 'impact': ['事件引发乔峰对自己身世的怀疑', '丐帮内部的动荡加剧']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '慕容复': {'name': '慕容复',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_006',\n", + " 'time': '段誉离开后',\n", + " 'location': '湖上',\n", + " 'event': '段誉对慕容复的妒忌和困惑',\n", + " 'if_completed': True,\n", + " 'action': ['间接影响段誉的自我反思和情感波动'],\n", + " 'motivation': ['无意中成为段誉情感反思的触发点'],\n", + " 'involved_entities': ['段誉'],\n", + " 'impact': ['引起段誉的情感和心理波动', '激发段誉的自我反省和不满'],\n", + " 'utterances': [],\n", + " 'speech_style': '未展示',\n", + " 'personality_traits': ['影响力', '无意识激励'],\n", + " 'emotion_state': '未知',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '对手',\n", + " 'relation_strength': -0.2,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'action:无, impact:引发段誉妒忌和困惑'}]},\n", + " {'event_id': 'event_007',\n", + " 'time': '杏子林中',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内斗与慕容复的关系',\n", + " 'if_completed': True,\n", + " 'action': ['默默旁观并等待事情发展', '被提及与姑苏慕容氏的关系'],\n", + " 'motivation': ['澄清与乔峰以及丐帮之间的关系'],\n", + " 'involved_entities': ['丐帮众人', '乔峰', '段誉', '王语嫣', '阿朱', '阿碧'],\n", + " 'impact': ['导致丐帮内部势力分裂', '丐帮众人对慕容复的疑虑加深'],\n", + " 'utterances': [],\n", + " 'speech_style': '未展示',\n", + " 'personality_traits': ['冷静', '战略性旁观者'],\n", + " 'emotion_state': '观察和困惑',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '潜在敌对',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_007',\n", + " 'derived_from': 'action:被提及与姑苏慕容氏, impact:丐帮内部疑虑加深'},\n", + " {'target': '段誉',\n", + " 'relation_type': '复杂关系',\n", + " 'relation_strength': -0.1,\n", + " 'last_updated': 'event_007',\n", + " 'derived_from': 'action:静观其变, impact:影响段誉的心态'}]},\n", + " {'event_id': 'event_008',\n", + " 'time': '杏林事件后',\n", + " 'location': '未具体提及',\n", + " 'event': '慕容复被误认为乔峰杀害马副帮主',\n", + " 'if_completed': False,\n", + " 'action': ['表明身份', '揭露证据是栽赃嫁祸'],\n", + " 'motivation': ['洗脱嫌疑', '澄清真相'],\n", + " 'involved_entities': ['乔峰', '马夫人', '段誉', '王语嫣'],\n", + " 'impact': ['增添了各方对乔峰身份的质疑', '引发丐帮内部的分裂和动荡'],\n", + " 'utterances': [],\n", + " 'speech_style': '辩解',\n", + " 'personality_traits': ['机智', '冷静'],\n", + " 'emotion_state': '坚定和防备',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '敌友难分',\n", + " 'relation_strength': -0.3,\n", + " 'last_updated': 'event_008',\n", + " 'derived_from': 'action:表明身份, impact:质疑乔峰身份'},\n", + " {'target': '马夫人',\n", + " 'relation_type': '对手',\n", + " 'relation_strength': -0.4,\n", + " 'last_updated': 'event_008',\n", + " 'derived_from': 'action:揭露证据是栽赃, impact:助长内斗'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '王夫人': {'name': '王夫人',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '杏子林中事件',\n", + " 'location': '杏子林',\n", + " 'event': '观察丐帮内部争斗与乔峰的处境',\n", + " 'if_completed': True,\n", + " 'action': ['暗中观察乔峰的行动', '试图理解丐帮内部的权力动态'],\n", + " 'motivation': ['防范潜在威胁', '收集信息以维护地位'],\n", + " 'involved_entities': ['丐帮', '乔峰', '马夫人', '智光大师', '徐长老', '赵钱孙'],\n", + " 'impact': ['加深对丐帮复杂关系的认识', '与乔峰的敌对关系未解', '确认乔峰的身世争议'],\n", + " 'utterances': [{'time': 'event_003', 'content': '未直接说话,但深度关注事件进展'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['小心谨慎'],\n", + " 'emotion_state': '警觉',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:观察事件, impact:乔峰形象影响与丐帮事件'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.2,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'impact:确认丐帮与乔峰复杂关系'}]},\n", + " {'event_id': 'event_004',\n", + " 'time': '西夏武士挑战事件后续',\n", + " 'location': '杏子林',\n", + " 'event': '关注丐帮与西夏武士对峙',\n", + " 'if_completed': False,\n", + " 'action': ['密切观察局势发展'],\n", + " 'motivation': ['确保自身及利益安全'],\n", + " 'involved_entities': ['丐帮', '西夏武士', '徐长老', '努儿海'],\n", + " 'impact': ['认识到丐帮危机与外部敌对势力的威胁'],\n", + " 'utterances': [{'time': 'event_004', 'content': '未直接参与对话,观察局势演变'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['小心谨慎'],\n", + " 'emotion_state': '警惕',\n", + " 'relations': [{'target': '西夏武士',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.3,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'impact:丐帮与西夏武士对峙'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '小翠': {'name': '小翠',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '小翠观察丐帮内部纷争',\n", + " 'if_completed': True,\n", + " 'action': ['远远观看', '保持低调', '观察事情发展', '听智光大师讲述旧事', '目睹乔峰的离去'],\n", + " 'motivation': ['谨慎避免卷入纷争', '保持中立立场', '满足自身好奇心', '了解乔峰的真实身世'],\n", + " 'involved_entities': ['乔峰',\n", + " '徐长老',\n", + " '智光大师',\n", + " '赵钱孙',\n", + " '马夫人',\n", + " '段誉',\n", + " '王语嫣',\n", + " '单正',\n", + " '全冠清'],\n", + " 'impact': ['了解丐帮内部争斗及其原因',\n", + " '对丐帮重要角色产生印象',\n", + " '知道了乔峰的身世与丐帮的内斗',\n", + " '对武林正邪的争斗有更深入理解']},\n", + " {'event_id': 'event_002',\n", + " 'time': '夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '被牵连入西夏一品堂与丐帮冲突',\n", + " 'if_completed': False,\n", + " 'action': ['隐藏以避免被卷入直接冲突中', '观察西夏与丐帮的谈判和冲突', '记录西夏与丐帮武力对抗的细节'],\n", + " 'motivation': ['保护自己不被卷入武斗', '了解武林新势力与丐帮的冲突', '见证重要的江湖事件发展'],\n", + " 'involved_entities': ['徐长老', '西夏征东大将军', '努儿海', '段誉', '云中鹤', '吴长老', '王语嫣'],\n", + " 'impact': ['对西夏一品堂的强大能力有新的认识', '意识到丐帮在江湖中的危急处境', '感受到武林利益纠葛的复杂']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '王语嫣': {'name': '王语嫣',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '第十四章到第十五章',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮与慕容氏争端和平定丐帮内乱',\n", + " 'if_completed': True,\n", + " 'action': ['继续与包不同、风波恶同处',\n", + " '观察丐帮内乱和平定过程',\n", + " '与段誉和阿朱、阿碧一同观看',\n", + " '分析乔峰称慕容复为大英雄',\n", + " '对乔峰心生感激'],\n", + " 'motivation': ['关心慕容复的安危', '欲了解丐帮对慕容复的态度', '希望保护友人及表哥声誉'],\n", + " 'involved_entities': ['包不同', '风波恶', '乔峰', '段誉', '阿朱', '阿碧', '吴长风', '丐帮人士'],\n", + " 'impact': ['通过旁观事件,提升了对乔峰的理解和好感', '提高了与段誉、阿朱、阿碧的交流和默契'],\n", + " 'utterances': [{'time': 'event_003', 'content': '我想听听。'},\n", + " {'time': 'event_003', 'content': '不!不!马副帮主不是我表哥杀的,乔帮主不也这么说吗?'},\n", + " {'time': 'event_003', 'content': '这位乔帮主果然也是个大英雄、好汉子。'}],\n", + " 'speech_style': '文雅',\n", + " 'personality_traits': ['善良', '聪慧', '关切亲友'],\n", + " 'emotion_state': '平静中带有紧张和期待',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '友好',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:观察和平定内乱, impact:理解与好感提升'},\n", + " {'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:与段誉观看丐帮内乱, impact:交流和默契提高'},\n", + " {'target': '慕容复',\n", + " 'relation_type': '亲属',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:分析对慕容复的称呼, impact:维护表哥声誉'},\n", + " {'target': '阿朱',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:与阿朱查看内乱, impact:交流和默契提高'},\n", + " {'target': '阿碧',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:与阿碧查看内乱, impact:交流和默契提高'}]},\n", + " {'event_id': 'event_004',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '乔峰被揭露契丹身世',\n", + " 'if_completed': False,\n", + " 'action': ['与众人一起聆听智光大师讲述过往事件', '分析乔峰的反应与情绪', '安抚慕容复受冤屈情绪', '观察丐帮内部产生的分歧'],\n", + " 'motivation': ['保护慕容复的声誉', '了解丐帮重大变故内情'],\n", + " 'involved_entities': ['乔峰', '智光大师', '徐长老', '单正', '赵钱孙', '段誉', '马夫人'],\n", + " 'impact': ['了解乔峰身世背后复杂的恩怨关系', '加强对乔峰个人的同情和理解'],\n", + " 'utterances': [{'time': 'event_004',\n", + " 'content': '表哥给人家冤枉,说不定他自己还不知道呢,我得去告知他才是。'},\n", + " {'time': 'event_004', 'content': '我讨厌他们。'}],\n", + " 'speech_style': '分析性、坚定',\n", + " 'personality_traits': ['分析力强', '情感细腻', '忠诚'],\n", + " 'emotion_state': '忧虑和同情',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '友好',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:分析乔峰的反应, impact:理解和同情增加'},\n", + " {'target': '慕容复',\n", + " 'relation_type': '亲属',\n", + " 'relation_strength': 0.75,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:保护慕容复声誉, impact:忠诚增加'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '严妈妈': {'name': '严妈妈',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子树后',\n", + " 'event': '智光大师回忆雁门关外旧事',\n", + " 'if_completed': True,\n", + " 'action': ['肃然敬立听取智光大师回忆', '与丐帮众人一同关注事件发展'],\n", + " 'motivation': ['了解缘由', '关切丐帮内部动荡'],\n", + " 'involved_entities': ['智光大师', '徐长老', '赵钱孙', '乔峰', '丐帮众人'],\n", + " 'impact': ['对乔峰的身份揭露产生威胁', '进一步加剧丐帮内部的矛盾'],\n", + " 'utterances': [],\n", + " 'speech_style': '默认',\n", + " 'personality_traits': ['关切', '谨慎'],\n", + " 'emotion_state': '震惊',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'impact:对乔峰的身份揭露产生威胁'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '尊敬',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:肃然敬立听取智光大师回忆'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '邓百川': {'name': '邓百川',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '乔峰身世被揭露事件',\n", + " 'if_completed': False,\n", + " 'action': ['在场听智光大师叙述旧事', '听挖掘出丧父恩怨的真相', '权衡丐帮事件的冲突和派系争斗'],\n", + " 'motivation': ['出于对乔峰的关心和丐帮的命运的关注'],\n", + " 'involved_entities': ['智光大师',\n", + " '乔峰',\n", + " '徐长老',\n", + " '赵钱孙',\n", + " '宋长老',\n", + " '其他丐帮成员',\n", + " '西夏国武士'],\n", + " 'impact': ['协助丐帮寻找解决当前困境的方法', '引起周围丐帮成员对乔峰身份的议论和决定']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '公冶二哥': {'name': '公冶二哥',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林事件',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内乱和密谋诛杀乔峰事件',\n", + " 'if_completed': True,\n", + " 'action': ['出现在杏子林中', '见证智光大师揭露乔峰身世', '与丐帮众人陷入内斗'],\n", + " 'motivation': ['与丐帮内斗有关'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长风',\n", + " '白世镜',\n", + " '全冠清',\n", + " '马夫人',\n", + " '徐长老',\n", + " '单正',\n", + " '赵钱孙',\n", + " '智光大师'],\n", + " 'impact': ['丐帮内部分裂', '乔峰退出丐帮', '人物关系发生变化']},\n", + " {'event_id': 'event_002',\n", + " 'time': '杏子林事件后',\n", + " 'location': '杏子林',\n", + " 'event': '遭遇西夏国征东大将军及一品堂武士',\n", + " 'if_completed': False,\n", + " 'action': ['目睹丐帮与西夏武士冲突', '遭遇悲酥清风毒气'],\n", + " 'motivation': ['身在丐帮,遭遇袭击'],\n", + " 'involved_entities': ['西夏征东大将军', '一品堂武士'],\n", + " 'impact': ['丐帮中人中毒无法行动', '西夏武士对丐帮展开攻击']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '包三哥': {'name': '包三哥',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '夜晚,天已全黑',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮叛乱平息,商议帮规及马大元之事',\n", + " 'if_completed': True,\n", + " 'action': ['带领丐帮众人平息叛乱',\n", + " '商讨帮规及马大元之事',\n", + " '与多位江湖前辈交流意见',\n", + " '听取智光大师回述旧事,了解乔峰身世',\n", + " '见证乔峰辞去丐帮帮主之位'],\n", + " 'motivation': ['维护丐帮大业', '澄清自身清白', '协助帮主乔峰理清身世之谜'],\n", + " 'involved_entities': ['乔峰',\n", + " '宋奚陈吴四长老',\n", + " '白世镜',\n", + " '马夫人',\n", + " '徐长老',\n", + " '铁面判官单正',\n", + " '赵钱孙',\n", + " '智光大师',\n", + " '西夏赫连铁树'],\n", + " 'impact': ['平息丐帮叛乱',\n", + " '揭开乔峰身世之谜,引发帮内众人争议',\n", + " '乔峰辞去帮主之位,打狗棒暂由长老保管',\n", + " '丐帮被西夏一品堂觊觎,内部分裂'],\n", + " 'utterances': [{'time': 'event_001', 'content': '帮主吩咐的是,全冠清,你说吧。'},\n", + " {'time': 'event_001', 'content': '大丈夫行事,对就是对,错就是错。'}],\n", + " 'speech_style': '诚恳',\n", + " 'personality_traits': ['坚定', '仁义', '公正'],\n", + " 'emotion_state': '疑惑',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:支持乔帮主,impact:助帮主平息叛乱'},\n", + " {'target': '赵钱孙',\n", + " 'relation_type': '陌生人',\n", + " 'relation_strength': 0.1,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:互动, impact:无'},\n", + " {'target': '马夫人',\n", + " 'relation_type': '丐帮内部联系',\n", + " 'relation_strength': -0.3,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'impact:马大元死因不明'},\n", + " {'target': '西夏赫连铁树',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'impact:赫连铁树率西夏一品堂挑衅丐帮'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '凤四哥': {'name': '凤四哥',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_005',\n", + " 'time': '夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '出席丐帮内乱事件',\n", + " 'if_completed': False,\n", + " 'action': ['与段誉、王语嫣等人一同观察丐帮的变化', '评估乔峰帮助慕容氏的可能性', '保持旁观者姿态'],\n", + " 'motivation': ['探明真相', '确保慕容氏的安全和声誉'],\n", + " 'involved_entities': ['段誉',\n", + " '乔峰',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '阿碧',\n", + " '丐帮各长老',\n", + " '智光大师',\n", + " '太行山单判官',\n", + " '徐长老'],\n", + " 'impact': ['进一步了解乔峰的性格与处事原则', '对于丐帮内外部关系有更多认识', '观察到智光大师对乔峰身世的解释'],\n", + " 'utterances': [{'event_id': 'event_005', 'content': '丐帮此事非同小可,需保持冷静。'},\n", + " {'event_id': 'event_005', 'content': '汪帮主对乔峰总算将我当作是心腹...'}],\n", + " 'speech_style': '冷静观察',\n", + " 'personality_traits': ['谨慎', '分析能力'],\n", + " 'emotion_state': '警惕',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '观察者',\n", + " 'relation_strength': 0.2,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:保持旁观,影響:评估其立场'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:与其同观丐帮变局,影響:共同分析'}]},\n", + " {'event_id': 'event_006',\n", + " 'time': '蓝皮靴丐帮分裂潮起',\n", + " 'location': '杏子林',\n", + " 'event': '见证丐帮事件的深化与冲突',\n", + " 'if_completed': False,\n", + " 'action': ['观察丐帮内部争斗', '注意到乔峰的演说与离去'],\n", + " 'motivation': ['分析丐帮动态', '保持自身安全并继续信息收集'],\n", + " 'involved_entities': ['丐帮各派系', '段誉', '王语嫣', '智光大师', '徐长老', '白世镜'],\n", + " 'impact': ['明朗化丐帮内部分裂', '判断乔峰和丐帮未来走向的可能'],\n", + " 'utterances': [{'event_id': 'event_006', 'content': '帮派斗争是极为危险的,需谨慎行动。'}],\n", + " 'speech_style': '观察与思考',\n", + " 'personality_traits': ['理智', '善于分析'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '观察者',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'action:继续观察,impact:了解事件动态'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '玄悲': {'name': '玄悲',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '夜晚,天已全黑',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内部变故,权力斗争',\n", + " 'if_completed': True,\n", + " 'action': ['参与审视丐帮内部的叛乱情况', '观察马夫人拿出的信件'],\n", + " 'motivation': ['密切关注丐帮的权力斗争', '保护乔峰以求公正说明'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长风',\n", + " '宋奚陈吴四长老',\n", + " '马夫人',\n", + " '白世镜',\n", + " '徐长老',\n", + " '智光大师',\n", + " '赵钱孙'],\n", + " 'impact': ['丐帮内部势力重新洗牌', '乔峰的名誉受到威胁', '乔峰辞去丐帮帮主之位'],\n", + " 'utterances': [{'timestamp': '夜晚,天已全黑',\n", + " 'content': '乔帮主辛苦,事情调查清楚后,自然会有个说法。'},\n", + " {'timestamp': '夜晚,天已全黑', 'content': '马副帮主的事关系大局,须谨慎为之。'}],\n", + " 'speech_style': '沉默观望',\n", + " 'personality_traits': ['冷静', '观察力强'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': '夜晚,天已全黑',\n", + " 'derived_from': 'action:观察权力斗争, impact:保护乔峰的名誉'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '尊敬',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': '夜晚,天已全黑',\n", + " 'derived_from': 'impact:呼唤镇定,解决误解'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '玄慈': {'name': '玄慈',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十五章夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内乱平息与审问',\n", + " 'if_completed': True,\n", + " 'action': ['听马夫人述说马大元遗书', '观察赵钱孙的行为', '待徐长老拆马大元遗书', '等待马夫人进入'],\n", + " 'motivation': ['维护丐帮内部稳定', '查明马副帮主之死真相'],\n", + " 'involved_entities': ['马夫人',\n", + " '徐长老',\n", + " '乔峰',\n", + " '赵钱孙',\n", + " '谭公',\n", + " '谭婆',\n", + " '单正',\n", + " '智光大师',\n", + " '全冠清'],\n", + " 'impact': ['揭示帮中隐情可能', '可能对丐帮稳定产生深远影响', '乔峰退位可能引发帮内权力斗争'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'text': '众位兄弟,乔峰的所作所为,有何不对,请大家明言便是。'},\n", + " {'event_id': 'event_001', 'text': '各位,此到而来有何见教?'}],\n", + " 'speech_style': '严肃,正式',\n", + " 'personality_traits': ['果断', '领导力', '沉着'],\n", + " 'emotion_state': '警觉',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': '事件发展使关系加强,但因帮内事件变化,信任度降低'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '揭露乔峰契丹身份',\n", + " 'if_completed': False,\n", + " 'action': ['旁听智光大师和赵钱孙揭露乔峰的身世', '分析局势,考虑丐帮未来'],\n", + " 'motivation': ['维持丐帮名誉', '防止胡汉之争'],\n", + " 'involved_entities': ['乔峰', '徐长老', '智光大师', '赵钱孙', '马夫人', '各丐帮长老'],\n", + " 'impact': ['丐帮权力可能重新分配', '乔峰退位带来帮内不和'],\n", + " 'utterances': [],\n", + " 'speech_style': '严肃,正式',\n", + " 'personality_traits': ['果断', '领导力', '公正'],\n", + " 'emotion_state': '警觉',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.2,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': '事件导致关系紧张'},\n", + " {'target': '徐长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': '共同维护丐帮稳定'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '唐光雄': {'name': '唐光雄',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十五章',\n", + " 'location': '杏子林',\n", + " 'event': '参与乔峰处理丐帮内乱事件',\n", + " 'if_completed': True,\n", + " 'action': ['观察丐帮内乱的处理过程', '分析局势', '倾听众人的辩论', '支持乔峰澄清误会'],\n", + " 'motivation': ['维护丐帮的稳定', '了解事件真相', '支持乔峰', '化解误会'],\n", + " 'involved_entities': ['乔峰',\n", + " '白世镜',\n", + " '吴长风',\n", + " '宋长老',\n", + " '奚长老',\n", + " '全冠清',\n", + " '赵钱孙',\n", + " '谭公',\n", + " '谭婆',\n", + " '段誉',\n", + " '王语嫣',\n", + " '丐帮众弟子'],\n", + " 'impact': ['揭露丐帮中的背叛者', '促成帮内部的反思和平衡', '暂时平息内乱'],\n", + " 'utterances': [{'timestamp': 'event_001',\n", + " 'content': '众位兄弟,乔峰的所作所为,有何不对,请大家明言便是。'},\n", + " {'timestamp': 'event_001',\n", + " 'content': '帮主,这等不识大体的叛徒,不必跟他多费唇舌,按照叛逆犯上的帮规处刑便了。'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['正直', '坦率'],\n", + " 'emotion_state': '严肃',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:揭露叛徒, impact:揭露内奸'},\n", + " {'target': '吴长风',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:揭露时提供信息, impact:帮助平息叛乱'},\n", + " {'target': '全冠清',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:揭露, impact:揭露其叛乱行为'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '陈光胜': {'name': '陈光胜',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '三十年前',\n", + " 'location': '雁门关外乱石谷',\n", + " 'event': '契丹武士的袭击',\n", + " 'if_completed': True,\n", + " 'action': ['参与埋伏契丹武士', '使用武器袭击', '杀死契丹武士', '见证战役结果并埋葬', '放逐契丹婴儿'],\n", + " 'motivation': ['保护少林寺武功', '保卫大宋'],\n", + " 'involved_entities': ['乔峰的父母', '丐帮成员', '中原武林群雄', '契丹武士'],\n", + " 'impact': ['误杀契丹代表', '形成自身愧疚']},\n", + " {'event_id': 'event_002',\n", + " 'time': '当前',\n", + " 'location': '杏子林',\n", + " 'event': '揭露乔峰的身世',\n", + " 'if_completed': False,\n", + " 'action': ['口述三十年前事件', '建议毁掉揭露信件', '试图隐瞒真相'],\n", + " 'motivation': ['为乔峰保护声誉', '维护汪剑通的名声'],\n", + " 'involved_entities': ['乔峰',\n", + " '丐帮成员',\n", + " '徐长老',\n", + " '赵钱孙',\n", + " '单正',\n", + " '谭公',\n", + " '单氏五虎',\n", + " '马夫人'],\n", + " 'impact': ['引发丐帮内部冲突', '对乔峰心态的迷惘', '引发邦内对乔峰的信任危机']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '阿鄢': {'name': '阿鄢',\n", + " 'first_appearance': 'chapters/chapter12',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '群盗围攻后',\n", + " 'location': '杏子林',\n", + " 'event': '群盗围攻中保护王语嫣',\n", + " 'if_completed': True,\n", + " 'action': ['指导同伴乔装', '应对群盗', '观察丐帮内乱'],\n", + " 'motivation': ['维护庄园安全', '保护同伴和自身安全'],\n", + " 'involved_entities': ['段誉', '王语嫣', '乔峰', '群盗', '司马林', '丐帮众长老'],\n", + " 'impact': ['避免了进一步冲突', '确保队伍安全', '对丐帮内乱的观察及态度影响可能未来处境'],\n", + " 'utterances': [{'event_id': 'event_003',\n", + " 'utterance': '我们得亲自去瞧瞧,老顾也说不明白。'}],\n", + " 'speech_style': '谨慎',\n", + " 'personality_traits': ['冷静', '务实'],\n", + " 'emotion_state': '警惕',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:合作应对, impact:加强友谊'}]},\n", + " {'event_id': 'event_004',\n", + " 'time': '宴席上的交锋之后',\n", + " 'location': '无锡城, 松鹤楼',\n", + " 'event': '与乔峰结为兄弟',\n", + " 'if_completed': True,\n", + " 'action': ['喝酒与乔峰结拜', '观察乔峰的武功'],\n", + " 'motivation': ['结交武林豪杰', '增长见识'],\n", + " 'involved_entities': ['乔峰', '段誉'],\n", + " 'impact': ['建立与乔峰的友谊', '影响丐帮对姑苏慕容的看法'],\n", + " 'utterances': [{'event_id': 'event_004', 'utterance': '我这酒量是因人而异。'}],\n", + " 'speech_style': '幽默',\n", + " 'personality_traits': ['机智'],\n", + " 'emotion_state': '兴奋',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '兄弟',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:结交, impact:友好关系'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '杏子林内乱时',\n", + " 'location': '杏子林',\n", + " 'event': '目睹丐帮内乱',\n", + " 'if_completed': True,\n", + " 'action': ['观察并分析局势', '保持沉默和旁观'],\n", + " 'motivation': ['保护自身及同伴安全', '分析局势以决定后续行动'],\n", + " 'involved_entities': ['乔峰', '丐帮长老们', '赵钱孙', '谭氏伉俪', '段誉', '王语嫣'],\n", + " 'impact': ['对自己的安全和处境有重大影响', '可能影响与乔峰及其他武林人物的关系'],\n", + " 'utterances': [],\n", + " 'speech_style': '谨慎',\n", + " 'personality_traits': ['冷静', '观察力强'],\n", + " 'emotion_state': '警惕',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:旁观内乱, impact:保持盟友关系'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '同道',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:旁观内乱, impact:保持同道关系'}]},\n", + " {'event_id': 'event_006',\n", + " 'time': '少林寺纷争后',\n", + " 'location': '杏子林',\n", + " 'event': '与乔峰共述过去',\n", + " 'if_completed': False,\n", + " 'action': ['聆听乔峰过往事情', '分析乔峰身世背景'],\n", + " 'motivation': ['理解兄弟的困境', '可能影响未来武林格局'],\n", + " 'involved_entities': ['乔峰', '徐长老', '白世镜', '赵钱孙', '马夫人', '智光大师'],\n", + " 'impact': ['了解乔峰可能的真实身份', '乔峰的处境对未来大局有重要影响'],\n", + " 'utterances': [{'event_id': 'event_006', 'utterance': '原来这些年他承受了这么多。'}],\n", + " 'speech_style': '同情',\n", + " 'personality_traits': ['善解人意', '关心'],\n", + " 'emotion_state': '惊愕',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '兄弟',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'action:了解过往, impact: 增加理解及支持'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '王': {'name': '王',\n", + " 'first_appearance': 'chapters/chapter13',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮聚会,揭露乔峰身世',\n", + " 'if_completed': True,\n", + " 'action': ['听众人指证乔峰的契丹身世', '辞去丐帮帮主之位', '与群丐告别'],\n", + " 'motivation': ['揭露事实', '辞去帮主之位回避问题', '保护丐帮内部和谐'],\n", + " 'involved_entities': ['智光', '徐长老', '赵钱孙', '丐帮群丐'],\n", + " 'impact': ['临时放弃权力,避免内部战斗', '乔峰辞去丐帮帮主,影响整个帮派']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '老顾': {'name': '老顾',\n", + " 'first_appearance': 'chapters/chapter13',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '第十五章 杏子林中 商略平生义',\n", + " 'location': '杏子林',\n", + " 'event': '老顾目睹乔峰处理丐帮内乱',\n", + " 'if_completed': True,\n", + " 'action': ['围观丐帮内乱处理', '观摩乔峰的冷静处理方法'],\n", + " 'motivation': ['对乔峰领导能力的钦佩', '对事件发展的好奇'],\n", + " 'involved_entities': ['乔峰', '丐帮长老', '吴长风', '宋长老', '全冠清'],\n", + " 'impact': ['增强对乔峰领导能力的理解', '见证丐帮内部的动荡'],\n", + " 'utterances': ['event_003: 老顾心中暗想,乔峰果然大侠风范。'],\n", + " 'speech_style': '思考深入',\n", + " 'personality_traits': ['冷静', '思考周全'],\n", + " 'emotion_state': '惊奇',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '仰慕',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:观摩乔峰的领导'},\n", + " {'target': '吴长风',\n", + " 'relation_type': '观察者',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'impact:见证丐帮内部的动荡'},\n", + " {'target': '全冠清',\n", + " 'relation_type': '观察者',\n", + " 'relation_strength': -0.2,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'impact:见证丐帮内部的动荡'}]},\n", + " {'event_id': 'event_004',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '老顾目睹乔峰被揭身份为契丹人',\n", + " 'if_completed': False,\n", + " 'action': ['旁观乔峰面对来自丐帮和西夏人的质疑', '观察丐帮和西夏人为见识丐帮绝技发生冲突'],\n", + " 'motivation': ['对事件发展的好奇', '对乔峰被揭身份后的反应感到好奇'],\n", + " 'involved_entities': ['乔峰', '徐长老', '西夏武士', '丐帮中高层', '智光大师'],\n", + " 'impact': ['意识到乔峰的个人和丐帮的未来面临挑战', '对乔峰与丐帮的关系产生了新的思考'],\n", + " 'utterances': ['event_004: 老顾心想,乔峰此时定是万分为难。'],\n", + " 'speech_style': '内省',\n", + " 'personality_traits': ['细心', '冷静'],\n", + " 'emotion_state': '担忧',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '复杂',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'impact:意识到乔峰的未来挑战'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '慕容公子': {'name': '慕容公子',\n", + " 'first_appearance': 'chapters/chapter13',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '天黑后',\n", + " 'location': '杏子林',\n", + " 'event': '参与丐帮的内部分裂事件',\n", + " 'if_completed': False,\n", + " 'action': ['潜伏在丐帮群体中', '观察事件进展', '见证智光大师抵达'],\n", + " 'motivation': ['对丐帮动荡的关注或好奇', '对智光大师到来的兴趣'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长风',\n", + " '白世镜',\n", + " '全冠清',\n", + " '宋长老',\n", + " '陈长老',\n", + " '奚长老',\n", + " '其他丐帮成员',\n", + " '智光大师'],\n", + " 'impact': ['对事件的观察没有直接公开影响']},\n", + " {'event_id': 'event_002',\n", + " 'time': '丐帮领袖位置争夺',\n", + " 'location': '杏子林',\n", + " 'event': '观察和倾听关于乔峰的指责和辩护',\n", + " 'if_completed': False,\n", + " 'action': ['偷听丐帮内部对乔峰的指责和辩护', '听闻智光大师讲述雁门关事件', '目击乔峰被逼退位'],\n", + " 'motivation': ['了解事件真相', '或受到乔峰事件的个人影响', '关注乔峰身世的变迁'],\n", + " 'involved_entities': ['乔峰', '全冠清', '白世镜', '马夫人', '其他丐帮成员', '智光大师'],\n", + " 'impact': ['增加对乔峰事件的了解', '了解到乔峰被迫离开丐帮的事情']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '姚寨主': {'name': '姚寨主',\n", + " 'first_appearance': 'chapters/chapter13',\n", + " 'events': [{'event_id': 'event_006',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '商议丐帮大事',\n", + " 'if_completed': True,\n", + " 'action': ['安排与会各方的讨论', '分析局势并作出判断', '处理乔峰的身份危机', '与西夏一品堂对峙', '保护丐帮帮主权杖'],\n", + " 'motivation': ['维护丐帮的声誉', '防止误判增加内部分裂', '解决丐帮内部权力斗争'],\n", + " 'involved_entities': ['乔峰',\n", + " '全冠清',\n", + " '吴长老',\n", + " '传功长老',\n", + " '执法长老',\n", + " '白世镜',\n", + " '段誉',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '阿碧',\n", + " '徐长老',\n", + " '马夫人',\n", + " '单正',\n", + " '赵钱孙',\n", + " '谭公',\n", + " '谭婆',\n", + " '智光大师',\n", + " '西夏一品堂'],\n", + " 'impact': ['加深对全冠清的怀疑', '稳定群情,暂时平息内部动荡', '乔峰辞去丐帮帮主之位', '丐帮面临新内乱及外敌威胁']},\n", + " {'event_id': 'event_007',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '与西夏一品堂对峙',\n", + " 'if_completed': True,\n", + " 'action': ['面对西夏使者挑衅', '进行公共辩护及维护丐帮尊严', '协调丐帮群丐应对场面'],\n", + " 'motivation': ['维护丐帮尊严', '应对外敌挑战'],\n", + " 'involved_entities': ['赫连铁树', '努儿海', '西夏使者', '丐帮群丐'],\n", + " 'impact': ['丐帮受到外籍势力轻视', '群丐在内乱背景下失去团结']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '姚伯当': {'name': '姚伯当',\n", + " 'first_appearance': 'chapters/chapter13',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '三十年前',\n", + " 'location': '雁门关外乱石谷',\n", + " 'event': '参与伏击契丹武士',\n", + " 'if_completed': True,\n", + " 'action': ['加入对契丹武士的伏击行动', '与同伴设伏', '与契丹勇士交战'],\n", + " 'motivation': ['响应中原豪杰的号召', '保护大宋国运和少林寺'],\n", + " 'involved_entities': ['丐帮汪帮主', '万胜刀王维义', '地绝剑黄山鹤云道长', '契丹武士'],\n", + " 'impact': ['对契丹武士造成重大杀伤'],\n", + " 'utterances': [{'time': 'event_001', 'text': '这等两国交兵,不能讲什么江湖道义、武林规矩。'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['沉稳', '理智'],\n", + " 'emotion_state': '焦虑',\n", + " 'relations': [{'target': '契丹武士',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:参与伏击, impact:对契丹武士造成重大杀伤'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '当前时刻',\n", + " 'location': '杏子林',\n", + " 'event': '与乔峰及丐帮众人重提旧事',\n", + " 'if_completed': False,\n", + " 'action': ['揭示乔峰过去的身世', '解开雁门关之战的真相'],\n", + " 'motivation': ['对事件负有愧疚', '解开众人心中的疑团'],\n", + " 'involved_entities': ['乔峰', '徐长老', '赵钱孙', '众丐帮成员'],\n", + " 'impact': ['动摇乔峰在丐帮中的地位', '引发丐帮内部纷争'],\n", + " 'utterances': [{'time': 'event_002', 'text': '我这眼若是不瞧,一把摔死了他,那便万事全休。'}],\n", + " 'speech_style': '叙述',\n", + " 'personality_traits': ['内疚', '诚实'],\n", + " 'emotion_state': '忏悔',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '旧识',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:揭示旧事, impact:动摇乔峰的地位'},\n", + " {'target': '契丹武士',\n", + " 'relation_type': '反思者',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:解开真相, impact:解开事件真相'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '司马林': {'name': '司马林',\n", + " 'first_appearance': 'chapters/chapter13',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十五章 杏子林中',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮密谋事件揭露',\n", + " 'if_completed': True,\n", + " 'action': ['与丐帮长老商议', '倾听众人发言', '调整情势'],\n", + " 'motivation': ['维护丐帮的团结', '寻找真相'],\n", + " 'involved_entities': ['乔峰', '吴长风', '陈长老', '全冠清', '徐长老', '白世镜'],\n", + " 'impact': ['参与丐帮内部权力斗争', '尝试平息疑虑与冲突'],\n", + " 'utterances': ['event_001: 我知此信涉及帮中大事,帮主和诸长老既然不在洛阳,我生怕耽误时机,当即赴郑州求见徐长老,呈上书信,请他老人家作主。'],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['谨慎', '忠诚'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '帮主 / 朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:商议, impact:支持乔峰权威'},\n", + " {'target': '全冠清',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.6,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:揭露密谋, impact:对乔峰造成威胁'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '乔峰身份揭露与丐帮反应',\n", + " 'if_completed': False,\n", + " 'action': ['观察众人反应', '聆听智光大师讲述往事'],\n", + " 'motivation': ['理解乔峰真实身份', '考量丐帮忠诚与内讧危机'],\n", + " 'involved_entities': ['乔峰', '智光大师', '徐长老', '全冠清', '马夫人', '赵钱孙'],\n", + " 'impact': ['对丐帮内部造成信任危机', '乔峰面临个人身份与立场的质疑'],\n", + " 'utterances': ['event_002: 乔帮主,你既知道了自己身世,想来定要报你杀父之仇。'],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['冷静', '分析型'],\n", + " 'emotion_state': '焦虑',\n", + " 'relations': [{'target': '智光大师',\n", + " 'relation_type': '前辈',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:聆听往事, impact:帮助乔峰理解身份困惑'},\n", + " {'target': '马夫人',\n", + " 'relation_type': '敌对',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:观察诬陷, impact:乔峰面临身份指控'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '青城': {'name': '青城',\n", + " 'first_appearance': 'chapters/chapter13',\n", + " 'events': [{'event_id': 'event_002',\n", + " 'time': '日近午时',\n", + " 'location': '无锡城附近',\n", + " 'event': '遭遇丐帮变故',\n", + " 'if_completed': True,\n", + " 'action': ['观察丐帮的动静', '聆听王语嫣与丐帮的交谈', '目睹一品堂挑衅'],\n", + " 'motivation': ['关注江湖风云', '关心乔峰安全'],\n", + " 'involved_entities': ['乔峰', '王语嫣', '丐帮成员', '赫连铁树', '云中鹤'],\n", + " 'impact': ['揭露丐帮内部问题', '见证乔峰退出丐帮帮主之位'],\n", + " 'utterances': [{'text': '众壮士,乔帮主如何行事,谁能说得准?', 'event_id': 'event_002'}],\n", + " 'speech_style': '沉默',\n", + " 'personality_traits': ['机智', '谨慎'],\n", + " 'emotion_state': '复杂',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:关心交谈, impact:关系增加'},\n", + " {'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'impact:见证乔峰退出,舍不得他受冤屈'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '天已全黑',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮权力斗争',\n", + " 'if_completed': True,\n", + " 'action': ['观察乔峰的反应', '分析丐帮成员间的言语和立场', '目睹马副帮主遗孀的指控', '见证乔峰等人被悲酥清风制伏'],\n", + " 'motivation': ['了解丐帮内乱原因', '评估乔峰的领导力'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长老',\n", + " '宋奚陈吴四长老',\n", + " '全冠清',\n", + " '白世镜',\n", + " '一品堂成员',\n", + " '努儿海'],\n", + " 'impact': ['意识到乔峰的领导风采可能快要被挑战', '看到乔峰不辞而别'],\n", + " 'utterances': [{'text': '眼见堂上的情形,你们要如何抉择?', 'event_id': 'event_003'}],\n", + " 'speech_style': '沉默',\n", + " 'personality_traits': ['机智', '谨慎'],\n", + " 'emotion_state': '担忧',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'impact:乔峰被挑衅,关系复杂'}]},\n", + " {'event_id': 'event_004',\n", + " 'time': '清晨',\n", + " 'location': '杏子林外',\n", + " 'event': '协助乔峰处理善后',\n", + " 'if_completed': False,\n", + " 'action': ['观察杏子林中的变化', '分析王语嫣的对丐帮感受', '试图安抚丐帮中的激动情绪'],\n", + " 'motivation': ['缓解丐帮的内部紧张局势', '支持乔峰的抉择'],\n", + " 'involved_entities': ['乔峰', '王语嫣', '丐帮成员'],\n", + " 'impact': ['未能阻止乔峰离开'],\n", + " 'utterances': [{'text': '乔帮主不辞而别,我等需互助维护帮规。', 'event_id': 'event_004'}],\n", + " 'speech_style': '沉默',\n", + " 'personality_traits': ['机智', '谨慎'],\n", + " 'emotion_state': '失望',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'impact:帮助不力'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '诸保昆': {'name': '诸保昆',\n", + " 'first_appearance': 'chapters/chapter13',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮大会现身',\n", + " 'if_completed': True,\n", + " 'action': ['观察智光大师与丐帮之人的对话', '听取智光大师关于乱石谷前事件的讲述'],\n", + " 'motivation': ['了解丐帮内部争斗以及其身世之谜'],\n", + " 'involved_entities': ['智光大师', '乔峰', '徐长老', '丐帮成员'],\n", + " 'impact': ['对乔峰身世的进一步猜测', '丐帮内部的矛盾升级']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '风四弟': {'name': '风四弟',\n", + " 'first_appearance': 'chapters/chapter13',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '天已全黑',\n", + " 'location': '杏子林中',\n", + " 'event': '丐帮内乱,乔峰被质疑帮主之位',\n", + " 'if_completed': True,\n", + " 'action': ['参加丐帮聚会', '观察乔峰与叛徒对峙', '积极维护乔峰的声誉', '见证乔峰放弃帮主之位'],\n", + " 'motivation': ['维护丐帮声誉', '支持乔峰', '追求真相'],\n", + " 'involved_entities': ['乔峰',\n", + " '白世镜',\n", + " '全冠清',\n", + " '吴长风',\n", + " '徐长老',\n", + " '马夫人',\n", + " '赵钱孙',\n", + " '智光大师'],\n", + " 'impact': ['增加对乔峰的景仰与担忧', '了解帮内复杂的派系斗争', '对帮主职位的争夺有了更深刻的认识'],\n", + " 'utterances': [{'event_id': 'event_001', 'content': '帮主,如此不可辞任......'}],\n", + " 'speech_style': '古典',\n", + " 'personality_traits': ['忠诚', '机智'],\n", + " 'emotion_state': '困惑',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:支持乔峰, impact:增加景仰与担忧'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '乔峰受伤并自己救治',\n", + " 'if_completed': True,\n", + " 'action': ['观察乔峰自刺', '了解丐帮的规矩与乔峰的决策过程'],\n", + " 'motivation': ['寻求自我完善和学会丐帮规矩'],\n", + " 'involved_entities': ['乔峰', '单正', '谭公', '谭婆'],\n", + " 'impact': ['深化对乔峰的了解与敬佩', '理解乔峰处理叛徒的方法与决心'],\n", + " 'utterances': [],\n", + " 'speech_style': '无',\n", + " 'personality_traits': ['好奇', '学习力强'],\n", + " 'emotion_state': '欣赏',\n", + " 'relations': [{'target': '谭公',\n", + " 'relation_type': '友好',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:观察和理解谭公行事, impact:学习处理复杂人际关系'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '凌晨',\n", + " 'location': '杏子林中',\n", + " 'event': '西夏一品堂与丐帮对峙',\n", + " 'if_completed': False,\n", + " 'action': ['观察到西夏一品堂挑衅', '见证丐帮内部争斗', '保持警惕,未参与直接对抗'],\n", + " 'motivation': ['保护丐帮声誉', '观望局势'],\n", + " 'involved_entities': ['赫连铁树', '大鼻子', '努儿海'],\n", + " 'impact': ['通过观察,对西夏一品堂的势力形成了初步认识', '对丐帮潜在危机加深担忧'],\n", + " 'utterances': [{'event_id': 'event_003', 'content': '西夏将军远来是客,當以礼相待。'}],\n", + " 'speech_style': '讽刺',\n", + " 'personality_traits': ['警惕', '机智'],\n", + " 'emotion_state': '担忧',\n", + " 'relations': []}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '公冶': {'name': '公冶',\n", + " 'first_appearance': 'chapters/chapter13',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '夜晚,湖上晚风阵阵',\n", + " 'location': '听香水榭',\n", + " 'event': '公冶收到西夏国‘一品堂’有大批好手突然来到江南的消息,决定与包不同、阿朱、阿碧一同前去调查',\n", + " 'if_completed': False,\n", + " 'action': ['收到信鸽传来的情报', '决定与众人一起去查探情况', '讨论段誉之事', '关注丐帮与慕容公子的关系'],\n", + " 'motivation': ['调查西夏国‘一品堂’人物来意', '保护慕容家利益', '维护燕子坞的声誉', '解决与丐帮的误会以保障安全'],\n", + " 'involved_entities': ['包不同', '阿朱', '阿碧', '段誉', '乔峰'],\n", + " 'impact': ['计划安排出行和调查', '与丐帮交涉,避免冲突', '卷入段誉与乔峰的关系网'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'content': '这是公冶二哥想出来的古怪玩意,是从诗韵和切音中变化出来的,平声字读作入声,入声字读作上声,一东的当作三江,如此掉来掉去。我们瞧惯了,便知信中之意,在外人看来,那是全然的不知所云。',\n", + " 'time': '夜晚'}],\n", + " 'speech_style': '古怪,富有创新和暗示',\n", + " 'personality_traits': ['聪明', '谨慎', '创新'],\n", + " 'emotion_state': '略显警觉',\n", + " 'relations': [{'target': '包不同',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:准备调查, impact:合作'},\n", + " {'target': '阿朱',\n", + " 'relation_type': '伙伴',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:讨论情报'},\n", + " {'target': '阿碧',\n", + " 'relation_type': '伙伴',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:准备共同行动'},\n", + " {'target': '段誉',\n", + " 'relation_type': '旁观者',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:关注段誉之事'},\n", + " {'target': '乔峰',\n", + " 'relation_type': '敌对',\n", + " 'relation_strength': -0.2,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'impact:卷入段誉与乔峰的关系网'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '正午',\n", + " 'location': '杏子林',\n", + " 'event': '公冶抵达杏子林,观察丐帮内部纷争',\n", + " 'if_completed': False,\n", + " 'action': ['抵达杏子林', '观察丐帮与西夏一品堂冲突', '记录丐帮内部动向以供参考'],\n", + " 'motivation': ['收集各方势力情报', '保护自己,尽量避免暴露身份'],\n", + " 'involved_entities': ['徐长老', '传功长老', '白世镜', '乔峰', '赫连铁树', '段誉'],\n", + " 'impact': ['了解丐帮内部分裂与矛盾', '为公冶的未来行动提供情报'],\n", + " 'utterances': [],\n", + " 'speech_style': '默默观察',\n", + " 'personality_traits': ['聪明', '谨慎', '机智'],\n", + " 'emotion_state': '冷静',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '观察者',\n", + " 'relation_strength': 0.0,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:观察丐帮与西夏一品堂冲突'},\n", + " {'target': '徐长老',\n", + " 'relation_type': '观察者',\n", + " 'relation_strength': 0.0,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:记录丐帮内部动向以供参考'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '包不同': {'name': '包不同',\n", + " 'first_appearance': 'chapters/chapter13',\n", + " 'events': [{'event_id': 'event_004',\n", + " 'time': '杏子林内变时',\n", + " 'location': '杏子林',\n", + " 'event': \"witness of internal struggle within Beggars' Sect\",\n", + " 'if_completed': True,\n", + " 'action': ['观察丐帮内部斗争', '与段誉等人保持距离'],\n", + " 'motivation': ['保持局外人中立'],\n", + " 'involved_entities': ['乔峰',\n", + " '段誉',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '阿碧',\n", + " '丐帮长老和帮众',\n", + " '智光大师',\n", + " '徐长老',\n", + " '赵钱孙'],\n", + " 'impact': ['领悟丐帮内部的复杂互动'],\n", + " 'utterances': [],\n", + " 'speech_style': '寡言',\n", + " 'personality_traits': ['观察', '谨慎'],\n", + " 'emotion_state': '怀疑',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:观察, impact:领悟'},\n", + " {'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:保持距离'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '杏子林内变后',\n", + " 'location': '杏子林',\n", + " 'event': \"confrontation with outside forces at Beggars' Sect gathering\",\n", + " 'if_completed': False,\n", + " 'action': ['目睹异族介入杏子林聚会', '继续观察局势'],\n", + " 'motivation': ['谨慎应对外来威胁'],\n", + " 'involved_entities': ['西夏征东大将军', '徐长老', '传功长老', '执法长老', '丐帮帮众和弟子'],\n", + " 'impact': ['意识到丐帮的危机'],\n", + " 'utterances': [],\n", + " 'speech_style': '寡言',\n", + " 'personality_traits': ['观察', '谨慎', '冷静'],\n", + " 'emotion_state': '戒备',\n", + " 'relations': [{'target': '徐长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:目睹异族介入'},\n", + " {'target': '西夏征东大将军',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.7,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:目睹异族介入'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '邓大爷': {'name': '邓大爷',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_002',\n", + " 'time': '第十五章',\n", + " 'location': '杏子林',\n", + " 'event': '参与丐帮内变事件',\n", + " 'if_completed': True,\n", + " 'action': ['旁观丐帮内部分裂', '评估各方态度', '观察知光大师与丐帮之间的交流'],\n", + " 'motivation': ['维护丐帮稳定', '观察对慕容氏态度'],\n", + " 'involved_entities': ['乔峰', '吴长老', '白世镜', '段誉', '王语嫣', '知光大师', '徐长老'],\n", + " 'impact': ['了解丐帮内部的反慕容派动向', '保持与乔峰和慕容氏的微妙平衡', '知悉乔峰身世暴露后可能的影响'],\n", + " 'utterances': ['event_002: 乔峰,你虽为契丹人,我仍敬重你不改。',\n", + " 'event_002: 王语嫣,你要小心自己的立场,一切都微妙得很。'],\n", + " 'speech_style': '直言不讳',\n", + " 'personality_traits': ['审慎', '聪颖'],\n", + " 'emotion_state': '警惕',\n", + " 'relations': [{'target': '王语嫣',\n", + " 'relation_type': '亲属',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'involved_entities'},\n", + " {'target': '乔峰',\n", + " 'relation_type': '合作伙伴',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'impact:立场考量'},\n", + " {'target': '知光大师',\n", + " 'relation_type': '武林同道',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'interaction'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '遇见知光大师与乔峰身世揭示',\n", + " 'if_completed': True,\n", + " 'action': ['聆听知光大师揭露乔峰身世', '观察丐帮众的态度变化', '考量自己在事件中的立场'],\n", + " 'motivation': ['了解丐帮权力斗争', '为保持与各方的良好关系'],\n", + " 'involved_entities': ['乔峰', '知光大师', '徐长老', '马夫人'],\n", + " 'impact': ['对乔峰个人的支持可能受到影响', '对丐帮的未来产生担忧'],\n", + " 'utterances': ['event_003: 这丐帮内乱,连带外敌逼近,实在令人为难。',\n", + " 'event_003: 各位,保持冷静,别让个人恩怨损害大局。'],\n", + " 'speech_style': '稳定中带有劝诫',\n", + " 'personality_traits': ['冷静', '稳重'],\n", + " 'emotion_state': '复杂和警惕',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '合作伙伴',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'event participation'},\n", + " {'target': '徐长老',\n", + " 'relation_type': '武林同道',\n", + " 'relation_strength': 0.2,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'interaction'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '公冶二爷': {'name': '公冶二爷',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '出席与西夏国一品堂的武林聚会',\n", + " 'if_completed': False,\n", + " 'action': ['观察周围情况',\n", + " '与群丐讨论帮内事务',\n", + " '对话中提议为马副帮主报仇',\n", + " '与马夫人交流,澄清质疑',\n", + " '动手试图维护帮规'],\n", + " 'motivation': ['解决丐帮内部纠纷', '寻找帮主合适的人选', '维护乔峰的声誉', '对武林对手保持防范'],\n", + " 'involved_entities': ['徐长老', '赵钱孙', '智光大师', '乔峰', '马夫人', '西夏一品堂', '云中鹤'],\n", + " 'impact': ['未能及时遏制帮派分裂', '未能说服众人接受乔峰继续为帮主', '因人物动摇导致丐帮力量被削弱']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '风四爷': {'name': '风四爷',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_004',\n", + " 'time': '杏子林事件后',\n", + " 'location': '杏子林',\n", + " 'event': '与丐帮内部解纷',\n", + " 'if_completed': False,\n", + " 'action': ['观察乔峰与丐帮诸长老的交涉', '与段誉、王语嫣等人在一旁旁观'],\n", + " 'motivation': ['了解丐帮内部隐情', '维护与乔峰的良好关系'],\n", + " 'involved_entities': ['乔峰', '段誉', '王语嫣', '丐帮长老'],\n", + " 'impact': ['看到乔峰建立威信', '了解乔峰的被逼陷入复杂政局'],\n", + " 'utterances': [],\n", + " 'speech_style': '文雅',\n", + " 'personality_traits': ['冷静', '观察入微'],\n", + " 'emotion_state': '中立',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:观察, impact:看到乔峰建立威信'},\n", + " {'target': '段誉',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:与段誉一旁旁观, impact:无'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:与王语嫣一旁旁观, impact:无'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '杏子林事件期间',\n", + " 'location': '杏子林',\n", + " 'event': '与西夏一品堂对峙',\n", + " 'if_completed': False,\n", + " 'action': ['关注西夏一品堂与丐帮的冲突', '分析局势变化'],\n", + " 'motivation': ['了解武林局势变化', '评估西夏与丐帮实力差距'],\n", + " 'involved_entities': ['西夏一品堂', '丐帮', '乔峰', '徐长老', '努儿海'],\n", + " 'impact': ['意识到西夏一品堂对大宋武林的威胁', '见证丐帮内部的动荡与矛盾激化'],\n", + " 'utterances': [],\n", + " 'speech_style': '文雅',\n", + " 'personality_traits': ['冷静', '审慎'],\n", + " 'emotion_state': '忧虑',\n", + " 'relations': [{'target': '西夏一品堂',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.6,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:关注, impact:意识到西夏一品堂对大宋武林的威胁'},\n", + " {'target': '努儿海',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.4,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:关注, impact:意识到其对大宋武林的威胁'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '全冠清': {'name': '全冠清',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '夜晚后',\n", + " 'location': '杏子林',\n", + " 'event': '揭露乔峰身份之谜',\n", + " 'if_completed': True,\n", + " 'action': ['在叛乱失利后揭露乔峰身份之谜的线索', '表达对丐帮未来的担忧'],\n", + " 'motivation': ['出于对丐帮的忠诚,试图揭露真相'],\n", + " 'involved_entities': ['乔峰', '谭婆', '赵钱孙', '徐长老', '单正', '智光', '马夫人', '段誉'],\n", + " 'impact': ['丐帮内部产生对乔峰身份的怀疑', '引发了全部帮众对此困惑的广泛讨论', '导致乔峰放弃丐帮帮主之位']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '蒋舵主': {'name': '蒋舵主',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十五章 杏子林中',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内乱,四大长老图谋废除乔峰帮主之位。',\n", + " 'if_completed': True,\n", + " 'action': ['拦在五袋弟子刘竹庄身前', '质问刘竹庄', '承认密谋推翻乔峰', '停止反抗,被执法弟子绑上'],\n", + " 'motivation': ['支持丐帮内的反对派,认为乔峰不适合帮主之位'],\n", + " 'involved_entities': ['乔峰', '刘竹庄', '宋长老', '奚长老', '陈长老', '白世镜'],\n", + " 'impact': ['对乔峰帮主之位的威胁', '丐帮内部的震动和权力纷争']},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '西夏一品堂与丐帮的冲突',\n", + " 'if_completed': False,\n", + " 'action': ['听闻西夏来人挑衅', '观察徐长老与诸长老应对'],\n", + " 'motivation': ['保护丐帮帮主的利益', '应对外部势力挑衅'],\n", + " 'involved_entities': ['乔峰',\n", + " '徐长老',\n", + " '宋长老',\n", + " '奚长老',\n", + " '智光大师',\n", + " '赵钱孙',\n", + " '赫连铁树',\n", + " '努儿海'],\n", + " 'impact': ['揭露出来的帮主继位矛盾激化', '西夏与丐帮之间的紧张对立'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'content': '你们……你们……要除去我帮主之位,那也罢了,我拱手让人便是,何以编造了这番言离出来,诬蔑于我?我……我乔某到底做了什么坏事,你们如此苦苦逼我?'},\n", + " {'event_id': 'event_002', 'content': '这丐帮帮主一职,无论如何是不敢担任了。'}],\n", + " 'speech_style': '直接、质问',\n", + " 'personality_traits': ['果断', '忠诚', '正直'],\n", + " 'emotion_state': '愤怒与不解',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action: 在事件中支持乔峰, impact: 维护乔峰权威'},\n", + " {'target': '徐长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action: 观察其应对, impact: 无直接影响'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '方舵主': {'name': '方舵主',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_003',\n", + " 'time': '晚上',\n", + " 'location': '丐帮大义分舵',\n", + " 'event': '丐帮内乱初显,段誉协助乔峰',\n", + " 'if_completed': True,\n", + " 'action': ['帮助乔峰稳住局势', '分析局势', '与徐长老商讨对策'],\n", + " 'motivation': ['支持乔峰作为兄弟', '维护丐帮稳定'],\n", + " 'involved_entities': ['丐帮帮众', '乔峰', '徐长老'],\n", + " 'impact': ['帮助乔峰平息部分帮众的敌意', '确保帮内稳定'],\n", + " 'utterances': [{'time': '事件开始', 'content': '乔峰兄弟,我们必须团结一致。'}],\n", + " 'speech_style': '谨慎',\n", + " 'personality_traits': ['忠诚', '聪慧'],\n", + " 'emotion_state': '警觉',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '兄弟',\n", + " 'relation_strength': 1.0,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:帮助乔峰稳住局势'}]},\n", + " {'event_id': 'event_004',\n", + " 'time': '天已全黑',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内乱',\n", + " 'if_completed': True,\n", + " 'action': ['观察帮内动荡', '分析局势', '尝试与徐长老交流', '面对西夏挑战'],\n", + " 'motivation': ['维持丐帮稳定', '保护本帮利益'],\n", + " 'involved_entities': ['乔峰',\n", + " '王语嫣',\n", + " '段誉',\n", + " '阿朱',\n", + " '阿碧',\n", + " '执法长老',\n", + " '传功长老',\n", + " '群丐',\n", + " '西夏武士'],\n", + " 'impact': ['提高了对潜在危机的认识', '对帮内外情势的理解得到了加强'],\n", + " 'utterances': [{'time': '事件中', 'content': '兄弟们,敌意不可助长,我们须齐心。'},\n", + " {'time': '与西夏交谈时', 'content': '贵国一品堂的高手,胡吹什么武功一品,原来只是些平平无奇之辈。'}],\n", + " 'speech_style': '谨慎',\n", + " 'personality_traits': ['机智', '警觉'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '兄弟',\n", + " 'relation_strength': 1.0,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:观察帮内动荡'},\n", + " {'target': '西夏武士',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.9,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'impact:对帮内外情势的理解得到了加强'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '晚上',\n", + " 'location': '杏子林',\n", + " 'event': '西夏武士来袭',\n", + " 'if_completed': False,\n", + " 'action': ['观察西夏武士动向', '准备参与可能的战事'],\n", + " 'motivation': ['捍卫丐帮尊严', '保护帮内人员'],\n", + " 'involved_entities': ['西夏武士', '本帮帮众'],\n", + " 'impact': ['提高了对外敌的防备警惕'],\n", + " 'utterances': [{'time': '对西夏开战前', 'content': '对付阁下这等无名小卒,那用得着打狗棒法?'}],\n", + " 'speech_style': '谨慎',\n", + " 'personality_traits': ['慎重', '防备性强'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '西夏武士',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -1.0,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:准备参与可能的战事'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '传功长老': {'name': '传功长老',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_002',\n", + " 'time': '杏子林事件前后',\n", + " 'location': '杏子林',\n", + " 'event': '对叛徒进行审判和反省',\n", + " 'if_completed': True,\n", + " 'action': ['与执法长老一起参与对叛徒的审判', '对四长老的行为进行反思'],\n", + " 'motivation': ['维护丐帮的稳定和发展', '对自己的行为进行反思和纠正'],\n", + " 'involved_entities': ['乔峰', '执法长老', '白世镜', '曾参与叛乱的帮派成员'],\n", + " 'impact': ['帮助乔峰平定叛乱', '维护与乔峰和其他忠诚者的关系'],\n", + " 'utterances': [{'text': '咱们丐帮自居为江湖第一大帮,岂能给他比了下去?', 'time': 'event_002期间'}],\n", + " 'speech_style': '古典',\n", + " 'personality_traits': ['反思', '协作'],\n", + " 'emotion_state': '反思中的冷静',\n", + " 'relations': [{'target': '四大长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:参与叛乱审判, impact:捍卫帮规'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '杏子林事件',\n", + " 'location': '杏子林',\n", + " 'event': '与西夏武士对峙',\n", + " 'if_completed': False,\n", + " 'action': ['观察局势', '与徐长老等人交流意见'],\n", + " 'motivation': ['保护丐帮利益与名誉', '保持武林与丐帮平衡'],\n", + " 'involved_entities': ['徐长老', '白世镜', '乔峰', '西夏武士'],\n", + " 'impact': ['帮助协调帮内和外部关系', '避免丐帮和外部武士直接冲突'],\n", + " 'utterances': [{'text': '本帮帮规乃祖宗所定,不分辈份尊卑,品位高低,须当一体凛遵。',\n", + " 'time': 'event_003期间'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['严谨', '沉稳'],\n", + " 'emotion_state': '严肃',\n", + " 'relations': [{'target': '徐长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:协作, impact:团结帮众'},\n", + " {'target': '西夏武士',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.9,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:对峙, impact:保持丐帮声誉'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '执法长老': {'name': '执法长老',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_005',\n", + " 'time': '小路对峙时',\n", + " 'location': '惠山杏林',\n", + " 'event': '段誉目睹丐帮与慕容手下对峙',\n", + " 'if_completed': True,\n", + " 'action': ['旁观丐帮包不同对峙', '关注王语嫣和阿朱、阿碧', '协助制止帮内叛乱'],\n", + " 'motivation': ['维护丐帮的规矩和秩序', '关心王语嫣'],\n", + " 'involved_entities': ['段誉',\n", + " '乔峰',\n", + " '包不同',\n", + " '阿朱',\n", + " '阿碧',\n", + " '王语嫣',\n", + " '丐帮众人',\n", + " '全冠清',\n", + " '吴长老',\n", + " '徐长老',\n", + " '智光大师'],\n", + " 'impact': ['强化乔峰在丐帮中的威信', '维护丐帮声誉', '保护丐帮的内部安定'],\n", + " 'utterances': [{'time': 'event_005',\n", + " 'content': '王姑娘,天下武学,你无所不知,无所不晓。这一招咬人的功夫,却属于何门何派?'},\n", + " {'time': 'event_005', 'content': '帮主,这等不识大体的叛徒,不必跟他多费唸舌,按照叛逆犯上的帮规处刑便了。'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['好奇', '崇敬', '严肃'],\n", + " 'emotion_state': '坚定',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:协助制止叛乱, impact:维护乔峰威信'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '仰慕',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': 'action:关心, impact:对王语嫣心存挂念'}]},\n", + " {'event_id': 'event_006',\n", + " 'time': '杏林会面之时',\n", + " 'location': '惠山杏林',\n", + " 'event': '乔峰被揭露是契丹人,辞去丐帮帮主',\n", + " 'if_completed': True,\n", + " 'action': ['主持丐帮事务', '与代表西夏国的一品堂对峙', '处理帮内帮主继任争端'],\n", + " 'motivation': ['维护丐帮的秩序', '保护丐帮声誉', '处理自身身世问题'],\n", + " 'involved_entities': ['乔峰',\n", + " '徐长老',\n", + " '马夫人',\n", + " '段誉',\n", + " '王语嫣',\n", + " '赵钱孙',\n", + " '智光大师',\n", + " '西夏国一品堂武士'],\n", + " 'impact': ['帮助乔峰辞任,暂时安定了丐帮内部分争', '激化了与西夏国一品堂的冲突', '引发了帮内对乔峰身份的进一步争论'],\n", + " 'utterances': [{'time': 'event_006', 'content': '乔某的身世来历,待我查明真相后再来解释。'},\n", + " {'time': 'event_006', 'content': '不得自相残杀,为帮内大忌。'}],\n", + " 'speech_style': '坚定',\n", + " 'personality_traits': ['坚决', '正直', '有责任感'],\n", + " 'emotion_state': '悲愤',\n", + " 'relations': [{'target': '西夏国一品堂',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': 'action:对峙, impact:加剧两派敌对'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '白世镜': {'name': '白世镜',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_002',\n", + " 'time': '当日晚上',\n", + " 'location': '杏子林',\n", + " 'event': '处置帮内叛徒并维护丐帮秩序',\n", + " 'if_completed': False,\n", + " 'action': ['指挥执法弟子行法刀', '维护帮规和丐帮声誉', '参与讨论全冠清叛乱案情'],\n", + " 'motivation': ['通过严厉行事维护帮规', '维持丐帮声誉和纪律', '保护丐帮不被轻言动摇'],\n", + " 'involved_entities': ['乔峰', '吴长老', '全冠清', '宋奚陈吴四长老', '段誉', '王语嫣'],\n", + " 'impact': ['强化了白世镜在帮内的威严和对正义的维护', '控制了帮内叛徒的影响,避免进一步分裂', '对乔峰的权威形成支持'],\n", + " 'utterances': [{'event_id': 'event_002',\n", + " 'utterance': '传功、执法两长老今日没有到会,丐帮中规矩...'}],\n", + " 'speech_style': '正直严谨',\n", + " 'personality_traits': ['正直', '坚决'],\n", + " 'emotion_state': '冷静',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '帮主与长老',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:支持'},\n", + " {'target': '四长老',\n", + " 'relation_type': '同事',\n", + " 'relation_strength': -1.0,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:行刑,impact:正义得偿'},\n", + " {'target': '段誉',\n", + " 'relation_type': '局外观察者',\n", + " 'relation_strength': 0.0,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:观察,impact:未来潜在支持'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '局外观察者',\n", + " 'relation_strength': 0.0,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:观察,impact:无直接影响'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '次日上午',\n", + " 'location': '杏子林',\n", + " 'event': '应对西夏一品堂挑战',\n", + " 'if_completed': False,\n", + " 'action': ['传递信息给徐长老', '与其他丐帮长老商讨对策', '警惕西夏人士动向'],\n", + " 'motivation': ['维护丐帮尊严', '防范外敌入侵'],\n", + " 'involved_entities': ['徐长老', '西夏武士', '王语嫣', '段誉'],\n", + " 'impact': ['提升了对西夏一品堂动向的警觉', '协助长老们制定应对之策'],\n", + " 'utterances': [{'event_id': 'event_003',\n", + " 'utterance': '徐长老,请你暂行帮主之职,妥善应对西夏人。'}],\n", + " 'speech_style': '正直严谨',\n", + " 'personality_traits': ['机警', '负责'],\n", + " 'emotion_state': '戒备',\n", + " 'relations': [{'target': '徐长老',\n", + " 'relation_type': '同事',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:合作'},\n", + " {'target': '西夏武士',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:对抗'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '宋长老': {'name': '宋长老',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '天台山与无锡相距不远',\n", + " 'location': '杏子树旁的集会',\n", + " 'event': '宋长老参加丐帮集会,并聆听智光大师讲述雁门关外大战旧事',\n", + " 'if_completed': False,\n", + " 'action': ['参与集会', '聆听他人叙述'],\n", + " 'motivation': ['了解过去事件真相', '维护丐帮的名誉'],\n", + " 'involved_entities': ['智光大师', '徐长老', '乔峰', '赵钱孙', '全冠清'],\n", + " 'impact': ['增强自身对过往历史的认识', '影响丐帮内部对乔峰的看法']},\n", + " {'event_id': 'event_002',\n", + " 'time': '次日',\n", + " 'location': '杏子林',\n", + " 'event': '宋长老参与丐帮内部对乔峰的质疑与讨论',\n", + " 'if_completed': False,\n", + " 'action': ['提出反对意见', '支持乔峰的领导'],\n", + " 'motivation': ['怀疑事件真实性', '维护乔峰领导地位'],\n", + " 'involved_entities': ['乔峰', '徐长老', '全冠清', '丐帮群丐'],\n", + " 'impact': ['在丐帮内部造成分歧', '支持乔峰的声望']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '奚长老': {'name': '奚长老',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '三十余年前',\n", + " 'location': '雁门关外乱石谷',\n", + " 'event': '与契丹武士的战斗',\n", + " 'if_completed': True,\n", + " 'action': ['参与埋伏并攻击契丹武士', '与同伴共同进攻', '激战中保存自己性命', '留下契丹婴儿性命'],\n", + " 'motivation': ['抵抗契丹武士', '保护少林寺', '报国杀敌'],\n", + " 'involved_entities': ['契丹武士', '赵钱孙', '中原豪杰', '汪帮主', '杜氏三雄'],\n", + " 'impact': ['误杀契丹夫妇和武士', '留下契丹婴儿']},\n", + " {'event_id': 'event_002',\n", + " 'time': '当前',\n", + " 'location': '杏子林',\n", + " 'event': '与丐帮的密会',\n", + " 'if_completed': False,\n", + " 'action': ['向丐帮众说明过往事件', '回忆三十年前战事', '观看丐帮内讧'],\n", + " 'motivation': ['解除丐帮对乔峰的误解', '反思过往事件'],\n", + " 'involved_entities': ['乔峰', '徐长老', '赵钱孙', '丐帮众人'],\n", + " 'impact': ['揭露乔峰的身世', '导致丐帮内部分裂'],\n", + " 'utterances': [{'event_id': 'event_002',\n", + " 'content': '冤家宜解不宜结,何必旧事重提?',\n", + " 'time': '当前'}],\n", + " 'speech_style': '庄重且含蓄',\n", + " 'personality_traits': ['善良', '悲悯', '有责任感'],\n", + " 'emotion_state': '复杂',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '涤怨解困之人',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:揭露事件, impact:影响乔峰命运'},\n", + " {'target': '赵钱孙',\n", + " 'relation_type': '昔日同袍',\n", + " 'relation_strength': 0.2,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:共同回忆事件, impact:分享秘密'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '吴长老': {'name': '吴长老',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '天台山知光大师到达',\n", + " 'location': '杏子树后',\n", + " 'event': '智光大师到达丐帮会场',\n", + " 'if_completed': True,\n", + " 'action': ['欢迎智光大师', '讲述雁门关外大战旧事', '递交信件给智光', '维护帮派秩序'],\n", + " 'motivation': ['尊重智光大师的道德声誉', '维护丐帮的名誉和安宁'],\n", + " 'involved_entities': ['智光大师', '乔峰', '赵钱孙', '徐长老', '单正'],\n", + " 'impact': ['在场众人对雁门关事件的重新审视', '丐帮内部的身份质疑和危机']},\n", + " {'event_id': 'event_002',\n", + " 'time': '夜晚',\n", + " 'location': '杏子树梢',\n", + " 'event': '发现丐帮有重大变故',\n", + " 'if_completed': False,\n", + " 'action': ['安抚乔峰', '企图调停内部纷争'],\n", + " 'motivation': ['保持丐帮的团结'],\n", + " 'involved_entities': ['乔峰', '赵钱孙', '智光大师', '丐帮众长老'],\n", + " 'impact': ['乔峰对自身身世的动摇', '增大丐帮内部矛盾']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '大仁分舵': {'name': '大仁分舵',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_002',\n", + " 'time': '第十四章 剧饮千杯男儿事',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内乱',\n", + " 'if_completed': False,\n", + " 'action': ['见证丐帮内乱', '帮助乔峰与慕容氏势力交涉', '观察丐帮四长老和全冠清的异动', '欣赏乔峰平息内乱的智慧'],\n", + " 'motivation': ['支持新结拜兄弟乔峰', '观察慕容复', '确保乔峰的安全'],\n", + " 'involved_entities': ['乔峰',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '阿碧',\n", + " '包不同',\n", + " '风波恶',\n", + " '全冠清',\n", + " '丐帮四长老',\n", + " '徐长老',\n", + " '马夫人'],\n", + " 'impact': ['协助乔峰处理丐帮内乱并暂时平息局势', '对乔峰产生敬佩之情', '加深对丐帮的了解'],\n", + " 'utterances': [{'event_id': 'event_002',\n", + " 'text': '适才我见到奚长老和那两位爷台动手过招,武功果然了得,佩服,佩服。',\n", + " 'timestamp': 'during witnessing the conflict'},\n", + " {'event_id': 'event_002',\n", + " 'text': '想不到乔帮主如此深明大义,真乃英雄!',\n", + " 'timestamp': \"after Joe Feng's speech\"}],\n", + " 'speech_style': '直率',\n", + " 'personality_traits': ['善良', '具备分析能力', '忠诚'],\n", + " 'emotion_state': '敬佩',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '结拜兄弟',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': 'during event_002',\n", + " 'derived_from': 'impact:加深敬佩, action:见证丐帮内乱'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '倾慕',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'during event_002',\n", + " 'derived_from': 'action:观察, impact:无'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '第十五章 杏子林中 商略平生义',\n", + " 'location': '杏子林',\n", + " 'event': '马大元遗信风波',\n", + " 'if_completed': False,\n", + " 'action': ['观察乔峰处理全冠清的判决', '评估丐帮四大长老的态度', '与王语嫣探讨事件进展'],\n", + " 'motivation': ['保持对丐帮事务的关注', '支持乔峰的正义行为'],\n", + " 'involved_entities': ['乔峰',\n", + " '全冠清',\n", + " '丐帮四长老',\n", + " '王语嫣',\n", + " '徐长老',\n", + " '谭公',\n", + " '谭婆',\n", + " '赵钱孙'],\n", + " 'impact': ['增强对乔峰的信赖', '对丐帮内斗有更深的熟悉'],\n", + " 'utterances': [{'event_id': 'event_003',\n", + " 'text': '不!不!马副帮主不是我表哥杀的,乔帮主不也这么说吗?',\n", + " 'timestamp': 'during discussion with Wang Yuyan'}],\n", + " 'speech_style': '探讨式',\n", + " 'personality_traits': ['细心', '理智'],\n", + " 'emotion_state': '好奇',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '结拜兄弟',\n", + " 'relation_strength': 1.0,\n", + " 'last_updated': 'during event_003',\n", + " 'derived_from': 'impact:增强信赖, action:观察判决'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '倾慕',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': 'during event_003',\n", + " 'derived_from': 'utterances:讨论事件'}]},\n", + " {'event_id': 'event_004',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '智光大师揭示乔峰身世',\n", + " 'if_completed': True,\n", + " 'action': ['倾听智光大师讲述乔峰的身世', '观察乔峰的情绪变化', '分析局势对乔峰的影响'],\n", + " 'motivation': ['确保乔峰的安全', '支持乔峰应对突变'],\n", + " 'involved_entities': ['乔峰', '智光大师', '徐长老', '单正', '赵钱孙', '全冠清', '马夫人'],\n", + " 'impact': ['加深对乔峰命运的理解', '重新评估情势下的乔峰与丐帮的关系'],\n", + " 'utterances': [{'event_id': 'event_004',\n", + " 'text': '丐帮中曲直,唯有时辰能告人。',\n", + " 'timestamp': 'after hearing revelation'}],\n", + " 'speech_style': '分析性',\n", + " 'personality_traits': ['分析能力强', '善于观察和预判'],\n", + " 'emotion_state': '复杂',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '结拜兄弟',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'after event_004',\n", + " 'derived_from': 'action:倾听, impact:加深理解'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '马副帮主': {'name': '马副帮主',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_004',\n", + " 'time': '夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '段誉目睹丐帮内乱平定',\n", + " 'if_completed': False,\n", + " 'action': ['观望事态', '与王语嫣交流', '为乔峰感到欢喜', '听智光大师述说往事', '注意到帮主之争并未插手'],\n", + " 'motivation': ['对乔峰的钦佩', '自身安全考虑', '想了解历史真相'],\n", + " 'involved_entities': ['乔峰', '王语嫣', '丐帮长老', '智光大师', '徐长老'],\n", + " 'impact': ['理解乔峰在丐帮中的地位与影响', '加强对王语嫣的亲近', '对武林恩怨有更深理解'],\n", + " 'utterances': [{'event_id': 'event_004', 'content': '段誉与王语嫣对丐帮纷争进行低声讨论。'}],\n", + " 'speech_style': '尊敬',\n", + " 'personality_traits': ['好奇', '善解人意'],\n", + " 'emotion_state': '警觉',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.95,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:观望, impact:理解'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.85,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': 'action:交流, impact:亲近'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '李春来': {'name': '李春来',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '昔时雁门关外三十年前大战',\n", + " 'location': '雁门关外乱石谷前',\n", + " 'event': '参与大战并幸存',\n", + " 'if_completed': True,\n", + " 'action': ['参与伏击辽人', '晕倒在战场'],\n", + " 'motivation': ['抵御契丹武士袭击少林寺'],\n", + " 'involved_entities': ['智光大师', '汪剑通', '带头大哥', '契丹武士'],\n", + " 'impact': ['见证了战场的可怖场面', '幸存后改变命运'],\n", + " 'utterances': ['什么都不知道了,那种丑事虽然说来有愧,却也不必相瞒'],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['胆小', '沉默'],\n", + " 'emotion_state': '恐惧',\n", + " 'relations': [{'target': '智光大师',\n", + " 'relation_type': '陌生人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': '参与大战并幸存'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '马副帮主去世后杏林聚会',\n", + " 'location': '杏子林',\n", + " 'event': '揭露乔峰身份之谜',\n", + " 'if_completed': True,\n", + " 'action': ['透露乔峰身世信息', '解释雁门关旧事'],\n", + " 'motivation': ['揭示历史真相', '维护丐帮利益'],\n", + " 'involved_entities': ['智光大师', '乔峰', '徐长老', '马夫人'],\n", + " 'impact': ['乔峰退出丐帮', '群丐分裂'],\n", + " 'utterances': ['可笑啊可笑!汉人未必高人一等,契丹人也未必便猪狗不如!'],\n", + " 'speech_style': '讽刺',\n", + " 'personality_traits': ['冷静', '直率'],\n", + " 'emotion_state': '不安',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': '揭露他的契丹身份'},\n", + " {'target': '徐长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.2,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': '共同参与事件讨论'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '西夏国人襲擊杏子林',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮与西夏武士对峙',\n", + " 'if_completed': False,\n", + " 'action': ['观察群斗', '解读局势'],\n", + " 'motivation': ['维护帮会安全'],\n", + " 'involved_entities': ['徐长老', '努儿海', '西夏武士'],\n", + " 'impact': ['丐帮面临生死存亡危机'],\n", + " 'utterances': ['凡事三思,可不要胡乱行事'],\n", + " 'speech_style': '建议',\n", + " 'personality_traits': ['沉着', '谋略'],\n", + " 'emotion_state': '担忧',\n", + " 'relations': [{'target': '努儿海',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -1,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': '暗中施毒,企图攻袭'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '项兄': {'name': '项兄',\n", + " 'first_appearance': 'chapters/chapter14',\n", + " 'events': [{'event_id': 'event_004',\n", + " 'time': '乔峰被揭发后',\n", + " 'location': '杏子林',\n", + " 'event': '段誉帮助风波恶解毒',\n", + " 'if_completed': True,\n", + " 'action': ['吸出毒液', '救治风波恶'],\n", + " 'motivation': ['出于对慕容复一党的好感', '想要表现'],\n", + " 'involved_entities': ['风波恶', '乔峰'],\n", + " 'impact': ['化解了乔峰与慕容复一党的可能冲突'],\n", + " 'utterances': [{'event_id': 'event_004', 'utterance': '大哥,让小弟来吸好了。'}],\n", + " 'speech_style': '侠义',\n", + " 'personality_traits': ['勇敢', '仁慈'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '风波恶',\n", + " 'relation_type': '陌生人',\n", + " 'relation_strength': 0.2,\n", + " 'last_updated': 'event_004',\n", + " 'derived_from': '行动:解毒, 影响:化解恩怨'}]},\n", + " {'event_id': 'event_005',\n", + " 'time': '杏子林中',\n", + " 'location': '杏子林',\n", + " 'event': '段誉围观丐帮内乱',\n", + " 'if_completed': False,\n", + " 'action': ['围观丐帮内斗', '保护伴随同伴不被波及'],\n", + " 'motivation': ['与乔峰为兄弟情义', '保持安全距离观察事件发展'],\n", + " 'involved_entities': ['乔峰', '王语嫣', '阿朱', '阿碧'],\n", + " 'impact': ['在事件中保持中立,未改变现状'],\n", + " 'utterances': [{'event_id': 'event_005', 'utterance': '乔帮主果然也是个大英雄、好汉子。'}],\n", + " 'speech_style': '中立',\n", + " 'personality_traits': ['观察入微', '明辨是非'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': '围观事件保持中立对乔峰无敌意'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_005',\n", + " 'derived_from': '陪同参与丐帮内乱过程'}]},\n", + " {'event_id': 'event_006',\n", + " 'time': '次日早晨',\n", + " 'location': '杏子林',\n", + " 'event': '段誉见证乔峰身世揭露',\n", + " 'if_completed': False,\n", + " 'action': ['见证乔峰身份被揭露', '支持乔峰面对指控', '保护王语嫣'],\n", + " 'motivation': ['对乔峰的兄弟情义', '担心王语嫣的安全'],\n", + " 'involved_entities': ['乔峰', '王语嫣', '徐长老', '马夫人'],\n", + " 'impact': ['乔峰由于身份危机被迫离开丐帮', '增进与王语嫣的友谊'],\n", + " 'utterances': [{'event_id': 'event_006', 'utterance': '大哥,大哥,我随你去!'}],\n", + " 'speech_style': '支持',\n", + " 'personality_traits': ['忧心', '忠诚'],\n", + " 'emotion_state': '关切',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.9,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': '行动:支持乔峰, 影响:加深兄弟情谊'},\n", + " {'target': '王语嫣',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_006',\n", + " 'derived_from': '保护她免受冲突影响'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '刘竹庄': {'name': '刘竹庄',\n", + " 'first_appearance': 'chapters/chapter15',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子树后',\n", + " 'event': '参与乔峰被揭露身份的事件',\n", + " 'if_completed': True,\n", + " 'action': ['聆听智光大师揭露三十年前的往事', '分析乔峰与契丹的关系'],\n", + " 'motivation': ['弄清事实真相', '理解乔峰与契丹的关系'],\n", + " 'involved_entities': ['智光大师', '乔峰', '徐长老', '赵钱孙'],\n", + " 'impact': ['对乔峰身份产生怀疑', '对乔峰心生同情'],\n", + " 'utterances': [],\n", + " 'speech_style': '无',\n", + " 'personality_traits': ['冷静', '好奇心强'],\n", + " 'emotion_state': ['疑惑'],\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action: 聆听智光揭露'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子树后',\n", + " 'event': '追随智光的启发对乔峰的辩论',\n", + " 'if_completed': False,\n", + " 'action': ['反思智光的揭示与乔峰的反应', '观察丐帮内部的动荡'],\n", + " 'motivation': ['理解乔峰的身份对丐帮的影响', '保持自己在事件中的中立'],\n", + " 'involved_entities': ['徐长老', '宋长老', '马夫人', '王语嫣'],\n", + " 'impact': ['对丐帮帮主之位的变动产生关注'],\n", + " 'utterances': [],\n", + " 'speech_style': '无',\n", + " 'personality_traits': ['分析能力强', '善于倾听'],\n", + " 'emotion_state': ['困惑', '关注'],\n", + " 'relations': [{'target': '徐长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action: 参与讨论'},\n", + " {'target': '宋长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action: 参与讨论'},\n", + " {'target': '马夫人',\n", + " 'relation_type': '敌对',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action: 观察和反思'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '陈长老': {'name': '陈长老',\n", + " 'first_appearance': 'chapters/chapter15',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '参与揭露雁门关外旧事',\n", + " 'if_completed': True,\n", + " 'action': ['接过信件', '阅读信件', '证实信件内容', '撕毁信件署名'],\n", + " 'motivation': ['想隐瞒真相', '不愿让乔峰报仇'],\n", + " 'involved_entities': ['智光大师', '乔峰', '赵钱孙'],\n", + " 'impact': ['乔峰开始质疑自己的身份', '丐帮众人对乔峰的信任动摇']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '吴长风': {'name': '吴长风',\n", + " 'first_appearance': 'chapters/chapter15',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林事件',\n", + " 'location': '杏子林',\n", + " 'event': '被指责身世并辞去丐帮帮主',\n", + " 'if_completed': True,\n", + " 'action': ['与智光大师对质',\n", + " '承认是可能是契丹人',\n", + " '决定辞去丐帮帮主',\n", + " '提出打狗棒并号召其他成员接任',\n", + " '在送出棒后离开丐帮'],\n", + " 'motivation': ['追求身世真相', '避免丐帮内部分裂'],\n", + " 'involved_entities': ['徐长老', '智光大师', '马夫人', '丐帮众长老', '丐帮帮众'],\n", + " 'impact': ['丐帮内部的暂时动荡', '失去一位强有力的领袖']},\n", + " {'event_id': 'event_002',\n", + " 'time': '杏子林夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '面对丐帮众人的质疑',\n", + " 'if_completed': False,\n", + " 'action': ['抵挡丐帮长老们的攻击', '面对诬陷和指责保持冷静', '表达对丐帮的忠诚', '避免用力伤害任何帮众'],\n", + " 'motivation': ['保持君子之风', '不愿与昔日同事反目成仇'],\n", + " 'involved_entities': ['宋长老', '徐长老', '全冠清', '马副帮主', '丐帮帮众'],\n", + " 'impact': ['部分帮众对他的理解和支持', '丐帮内部的混乱加剧']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '公冶乾': {'name': '公冶乾',\n", + " 'first_appearance': 'chapters/chapter15',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '三十年前',\n", + " 'location': '雁门关外乱石谷',\n", + " 'event': '伏击契丹武士',\n", + " 'if_completed': True,\n", + " 'action': ['联合中原武林群豪伏击契丹军队', '用喂毒暗器袭击契丹武士', '参与近身搏斗'],\n", + " 'motivation': ['抵御契丹袭击', '保护少林寺武学秘笈', '保卫大宋疆土'],\n", + " 'involved_entities': ['赵钱孙', '智光大师', '丐帮帮众', '契丹武士'],\n", + " 'impact': ['歼灭部分契丹武士', '导致契丹婴儿被遗留', '喇护自己及环兄弟的声望'],\n", + " 'utterances': [{'time': 'event_001',\n", + " 'content': '这件事当真非同小可,要是契丹此举,大宋便有亡国之祸...'},\n", + " {'time': 'event_001', 'content': '自来兵不厌诈。这等两国交兵,不能讲什么江湖道义、武林规矩...'}],\n", + " 'speech_style': '勇敢而机警',\n", + " 'personality_traits': ['机智', '爱国'],\n", + " 'emotion_state': '坚定',\n", + " 'relations': [{'target': '赵钱孙',\n", + " 'relation_type': '同袍',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:联合伏击契丹, impact:成功阻敌'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '敬仰',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:参与决策, impact:僧侣支持'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十六章 昔时因',\n", + " 'location': '杏子林',\n", + " 'event': '揭露乔峰身世',\n", + " 'if_completed': False,\n", + " 'action': ['聆听智光大师讲述往事', '质疑契丹人指控'],\n", + " 'motivation': ['维护帮派和乔峰声誉', '寻找事件真相'],\n", + " 'involved_entities': ['乔峰', '智光大师', '丐帮各长老', '单家五虎'],\n", + " 'impact': ['乔峰的心结加深', '丐帮内部产生分裂', '激起江湖关注'],\n", + " 'utterances': [{'time': 'event_002', 'content': '不,不!你胡说八道,捏造这么一篇鬼话来诬陷我。'},\n", + " {'time': 'event_002', 'content': '我只道恩师汪帮主是有意锻炼于我,使我多历艰辛...'}],\n", + " 'speech_style': '激动而震惊',\n", + " 'personality_traits': ['忠信', '困惑'],\n", + " 'emotion_state': '愤怒与惶惑',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:支持乔峰, impact:关系破裂'},\n", + " {'target': '智光大师',\n", + " 'relation_type': '怀疑',\n", + " 'relation_strength': -0.3,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:质疑智光, impact:失信任'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '风波恶': {'name': '风波恶',\n", + " 'first_appearance': 'chapters/chapter15',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '天全黑时',\n", + " 'location': '杏子林',\n", + " 'event': '参与丐帮内变',\n", + " 'if_completed': True,\n", + " 'action': ['随同段誉与乔峰等人观察丐帮局势', '听取乔峰与叛贼对话', '观察吴长老等人的行径'],\n", + " 'motivation': ['希望通过观察了解丐帮内部局势和潜在威胁'],\n", + " 'involved_entities': ['乔峰',\n", + " '段誉',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '阿碧',\n", + " '吴长风',\n", + " '全冠清',\n", + " '白世镜',\n", + " '徐长老',\n", + " '马夫人'],\n", + " 'impact': ['帮助人物圈中对乔峰的误解和内部关系的洞悉', '见证乔峰退位离去的重大事件'],\n", + " 'utterances': ['当我亲眼见到乔峰退位,心中不禁感慨万分。'],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['冷静', '观察力强'],\n", + " 'emotion_state': '震惊',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:观察并赞赏其品德'},\n", + " {'target': '段誉',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:参与丐帮内变'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '丐帮内部对峙时',\n", + " 'location': '杏子林',\n", + " 'event': '对乔峰的威名感到赞赏',\n", + " 'if_completed': True,\n", + " 'action': ['侧耳倾听乔峰的演说', '观察乔峰处理反叛的方法', '表达对乔峰品德的暗中赞赏'],\n", + " 'motivation': ['被乔峰正直的处理方式及豪气所感动'],\n", + " 'involved_entities': ['乔峰', '丐帮众长老'],\n", + " 'impact': ['加深了对乔峰能力和品德的信服'],\n", + " 'utterances': ['在乔峰演说时,我无法不为其风范折服。'],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['诚实', '忠诚'],\n", + " 'emotion_state': '佩服',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:表达赞赏, impact:信服'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '赫连铁树来袭时',\n", + " 'location': '杏子林',\n", + " 'event': '遭遇西夏一品堂毒气袭击',\n", + " 'if_completed': False,\n", + " 'action': ['未能动弹', '尝试保护自己和他人'],\n", + " 'motivation': ['避免被西夏武士伤害', '保护丐帮的安全'],\n", + " 'involved_entities': ['段誉', '王语嫣', '徐长老', '努儿海', '赫连铁树', '吴长风', '南海鳄神'],\n", + " 'impact': ['西夏袭击引发了丐帮与西夏的更大冲突'],\n", + " 'utterances': ['真没想到,我们会在这样的情况下被袭击(时间:赫连铁树来袭时)。'],\n", + " 'speech_style': '简要',\n", + " 'personality_traits': ['谨慎', '忠诚'],\n", + " 'emotion_state': '愤怒',\n", + " 'relations': [{'target': '段誉',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:保护和尝试营救'},\n", + " {'target': '努儿海',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.3,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'impact:发生毒气袭击'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '马夫人': {'name': '马夫人',\n", + " 'first_appearance': 'chapters/chapter15',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '夜晚',\n", + " 'location': '杏子林',\n", + " 'event': '马夫人来到丐帮揭示马大元遗书',\n", + " 'if_completed': True,\n", + " 'action': ['抵达杏子林', '呈递马大元遗书', '公开遗书内容'],\n", + " 'motivation': ['查明马大元之死的真相', '解开帮中疑团'],\n", + " 'involved_entities': ['乔峰',\n", + " '徐长老',\n", + " '单正',\n", + " '谭公',\n", + " '谭婆',\n", + " '赵钱孙',\n", + " '丐帮众长老',\n", + " '智光大师',\n", + " '段誉',\n", + " '王语嫣',\n", + " '阿朱'],\n", + " 'impact': ['引起丐帮内部矛盾激化', '让乔峰的帮主地位成为争议焦点', '揭露乔峰的契丹身份,改变乔峰在武林中的名声'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'text': '小女子殓葬先夫之后,检点遗物,在他收藏拳经之处,见到一封用火漆密密封固的书信。'},\n", + " {'event_id': 'event_001',\n", + " 'text': '妾身是无知无识的女流之辈,出外抛头露面,已是不该,何敢乱加罪名于人?只是先夫死得冤枉,哀恳众位伯伯叔叔念着故旧之情,查明真相,替先夫报仇雪恨。'}],\n", + " 'speech_style': '谨慎而含蓄',\n", + " 'personality_traits': ['勇敢', '细心', '忧虑'],\n", + " 'emotion_state': '悲伤',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action: 投递信件, 影响: 公开马大元死因猜测'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '当天晚上',\n", + " 'location': '杏子林',\n", + " 'event': '揭示内心怀疑乔峰是杀害马大元的凶手',\n", + " 'if_completed': False,\n", + " 'action': ['质疑乔峰的无辜', '揭示自己找到的线索'],\n", + " 'motivation': ['为马大元报仇', '揭露可能的凶手'],\n", + " 'involved_entities': ['乔峰', '徐长老', '丐帮众长老', '阿朱'],\n", + " 'impact': ['对乔峰的身份产生更大的怀疑', '加剧丐帮内部的紧张局势'],\n", + " 'utterances': [{'event_id': 'event_002',\n", + " 'text': '只是先夫死得冤枉,哀恳众位伯伯叔叔念着故旧之情,查明真相,替先夫报仇雪恨。'}],\n", + " 'speech_style': '谨慎而含蓄',\n", + " 'personality_traits': ['勇敢', '细心', '忧虑'],\n", + " 'emotion_state': '悲伤',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action: 质疑乔峰, impact: 加剧身份怀疑'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '单正': {'name': '单正',\n", + " 'first_appearance': 'chapters/chapter15',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林中的聚会',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内乱平息及揭露乔峰身世事件',\n", + " 'if_completed': False,\n", + " 'action': ['未具体出现在文本中'],\n", + " 'motivation': ['未知,可能是作为旁观者观察局势'],\n", + " 'involved_entities': ['乔峰',\n", + " '白世镜',\n", + " '吴长风',\n", + " '宋长老',\n", + " '奚长老',\n", + " '陈长老',\n", + " '全冠清',\n", + " '段誉',\n", + " '王语嫣',\n", + " '谭公',\n", + " '谭婆',\n", + " '赵钱孙',\n", + " '智光大师',\n", + " '徐长老',\n", + " '马夫人',\n", + " '单仲山',\n", + " '单叔山',\n", + " '单季山'],\n", + " 'impact': ['未具体出现在文本中'],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " {'event_id': 'event_002',\n", + " 'time': '杏子林中的对峙',\n", + " 'location': '杏子林',\n", + " 'event': '与乔峰、徐长老及西夏国征东大将军赫连铁树周旋',\n", + " 'if_completed': False,\n", + " 'action': ['观察乔峰揭露的新情况', '回应乔峰与徐长老的举动'],\n", + " 'motivation': ['未直接参与,可能来回顾情况或维持秩序'],\n", + " 'involved_entities': ['乔峰',\n", + " '徐长老',\n", + " '白世镜',\n", + " '吴长风',\n", + " '宋长老',\n", + " '奚长老',\n", + " '陈长老',\n", + " '全冠清',\n", + " '段誉',\n", + " '王语嫣',\n", + " '谭公',\n", + " '谭婆',\n", + " '赵钱孙',\n", + " '智光大师',\n", + " '赫连铁树',\n", + " '努儿海',\n", + " '一品堂武士'],\n", + " 'impact': ['未具体出现在文本中'],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '单伯山': {'name': '单伯山',\n", + " 'first_appearance': 'chapters/chapter15',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '夜间',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内讧和对峙',\n", + " 'if_completed': True,\n", + " 'action': ['到场参与处理丐帮内讧', '与父亲单正会合', '聆听并观察事态发展', '劝说乔峰放下暴力'],\n", + " 'motivation': ['支持父亲单正', '维护正义', '保护家人'],\n", + " 'involved_entities': ['单正', '乔峰', '白世镜', '谭公', '谭婆', '赵钱孙', '马夫人', '智光大师'],\n", + " 'impact': ['目睹并吸取了丐帮权力斗争的经验教训', '加强了对乔峰实力的尊重与警惕'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'content': '乔帮主,贵帮之事,我父子原是不敢干预,但我爹爹说:君子以德……',\n", + " 'time': '夜间'},\n", + " {'event_id': 'event_001', 'content': '不可!', 'time': '夜间'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['直率', '尊重父亲', '谨慎', '维护理智'],\n", + " 'emotion_state': '警惕',\n", + " 'relations': [{'target': '单正',\n", + " 'relation_type': '亲属',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:与父亲单正会合'},\n", + " {'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.4,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'impact:观察乔峰处理丐帮内讧'},\n", + " {'target': '单季山',\n", + " 'relation_type': '亲属',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:努力营救兄弟'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '夜间',\n", + " 'location': '杏子林',\n", + " 'event': '与西夏一品堂的对峙',\n", + " 'if_completed': False,\n", + " 'action': ['戒备西夏武士入侵', '保护家人不涉险境'],\n", + " 'motivation': ['维护丐帮利益', '保障家人安全'],\n", + " 'involved_entities': ['乔峰', '徐长老', '全冠清', '谭婆', '马夫人', '西夏武士'],\n", + " 'impact': ['意识到丐帮面临的外部威胁', '促使丐帮内部团结对抗外敌'],\n", + " 'utterances': [],\n", + " 'speech_style': '谨慎',\n", + " 'personality_traits': ['警惕', '理智'],\n", + " 'emotion_state': '紧张',\n", + " 'relations': [{'target': '徐长老',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:与徐长老抗敌协作'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '单小山': {'name': '单小山',\n", + " 'first_appearance': 'chapters/chapter15',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林事件(第十五章)',\n", + " 'location': '杏子林',\n", + " 'event': '丐帮内乱事件',\n", + " 'if_completed': True,\n", + " 'action': ['参与丐帮内乱', '与乔峰、吴长老等人对峙'],\n", + " 'motivation': ['维护家族名誉', '支持父亲单正'],\n", + " 'involved_entities': ['乔峰',\n", + " '吴长老',\n", + " '宋长老',\n", + " '奚长老',\n", + " '陈长老',\n", + " '刘竹庄',\n", + " '段誉',\n", + " '王语嫣',\n", + " '阿朱',\n", + " '阿碧',\n", + " '白世镜',\n", + " '全冠清',\n", + " '单长老',\n", + " '谭公',\n", + " '谭婆',\n", + " '赵钱孙',\n", + " '徐长老',\n", + " '智光大师'],\n", + " 'impact': ['与乔峰等帮中人物关系恶化', '丐帮内部产生派系对立'],\n", + " 'utterances': [{'time': 'event_001', 'content': '他妈的,这不是活得不耐烦了么?'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['冲动', '直率'],\n", + " 'emotion_state': '愤怒',\n", + " 'relations': [{'target': '单正',\n", + " 'relation_type': '父子',\n", + " 'relation_strength': 1,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'utterance: 他妈的,这不是活得不耐烦了么?'},\n", + " {'target': '乔峰',\n", + " 'relation_type': '帮内先辈',\n", + " 'relation_strength': 0.1,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:参与丐帮内乱, impact:关系恶化'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '杏子林事件(第十六章)',\n", + " 'location': '杏子林',\n", + " 'event': '发现乔峰身世秘密',\n", + " 'if_completed': True,\n", + " 'action': ['参与揭发乔峰的身世'],\n", + " 'motivation': ['为家族利益和名誉考虑', '揭露乔峰的真实身份'],\n", + " 'involved_entities': ['乔峰', '徐长老', '智光大师', '宋长老', '吴长老', '各门派人士'],\n", + " 'impact': ['加深了丐帮内部矛盾', '导致乔峰退出帮派,辞去帮主之职'],\n", + " 'utterances': [],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['冲动', '直率'],\n", + " 'emotion_state': '复杂',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '帮内敌对人士',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:揭发身份, impact:失去帮主地位'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '赵钱孙': {'name': '赵钱孙',\n", + " 'first_appearance': 'chapters/chapter15',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林中',\n", + " 'location': '杏子林',\n", + " 'event': '参与揭露丐帮密谋叛变事件',\n", + " 'if_completed': True,\n", + " 'action': ['与谭婆对话',\n", + " '被徐长老请来作证',\n", + " '背诵信中内容',\n", + " '试图逃跑',\n", + " '被全冠清发现',\n", + " '指证乔峰是契丹人',\n", + " '参与揭露乔峰的身世'],\n", + " 'motivation': ['与谭婆有情感纠葛', '揭露乔峰身份,防止丐帮内部被契丹人渗透'],\n", + " 'involved_entities': ['谭婆', '徐长老', '乔峰', '全冠清', '智光和尚'],\n", + " 'impact': ['导致乔峰被迫辞去丐帮帮主', '加剧丐帮内部矛盾与权力斗争']},\n", + " {'event_id': 'event_002',\n", + " 'time': '西夏国与丐帮对峙',\n", + " 'location': '杏子林',\n", + " 'event': '面对西夏军队来袭',\n", + " 'if_completed': False,\n", + " 'action': ['围观丐帮与西夏人对峙', '目睹西夏人使用毒气'],\n", + " 'motivation': ['看看西夏与丐帮冲突的结果', '了解西夏军队的武功实力'],\n", + " 'involved_entities': ['丐帮弟子', '西夏军', '赫连铁树', '努儿海', '云中鹤'],\n", + " 'impact': ['西夏人与丐帮的矛盾加深', '影响丐帮未来对外关系策略']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '谭公': {'name': '谭公',\n", + " 'first_appearance': 'chapters/chapter15',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 杏子林事件后',\n", + " 'location': '杏子林',\n", + " 'event': '参与丐帮会议',\n", + " 'if_completed': True,\n", + " 'action': ['谭婆拔出乔峰肩上的法刀', '谭公为乔峰敷药止血', '参与会议中与乔峰等人交流'],\n", + " 'motivation': ['帮助乔峰', '维护自身和江湖威名'],\n", + " 'involved_entities': ['乔峰', '谭婆', '赵钱孙', '单正', '徐长老', '智光', '阿朱', '段誉'],\n", + " 'impact': ['帮助乔峰维持声誉', '平息内部冲突', '参与讨论揭开乔峰的身世'],\n", + " 'utterances': [{'text': '这世上有谁这么大胆,竟敢用刀子伤你?', 'time': '第十五章 杏子林中'},\n", + " {'text': '你势下了我,去嫁了这老不死的谭公,我心中如何不悲,如何不痛?', 'time': '第十五章 杏子林中'},\n", + " {'text': '乔帮主,有话好说,千万不可动蛮。我单家与你无冤无仇,请你放了我孩儿。', 'time': '第十六章 昔时因'}],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['豪爽', '直接', '讲理'],\n", + " 'emotion_state': '困惑',\n", + " 'relations': [{'target': '谭婆',\n", + " 'relation_type': '配偶',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': '第十六章 昔时因',\n", + " 'derived_from': 'action:敷药, impact:维护关系'},\n", + " {'target': '赵钱孙',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0,\n", + " 'last_updated': '第十六章 昔时因',\n", + " 'derived_from': 'action:参与对话'},\n", + " {'target': '乔峰',\n", + " 'relation_type': '同门',\n", + " 'relation_strength': 0.2,\n", + " 'last_updated': '第十六章 昔时因',\n", + " 'derived_from': 'action:支持言辞, impact:缓解冲突'}]},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十六章 智光到来',\n", + " 'location': '杏子林',\n", + " 'event': '乔峰身世揭露',\n", + " 'if_completed': False,\n", + " 'action': ['谭公在会议中与诸长老以及智光交流'],\n", + " 'motivation': ['寻求真相', '化解冲突'],\n", + " 'involved_entities': ['智光', '乔峰', '徐长老', '马夫人', '赵钱孙'],\n", + " 'impact': ['促进乔峰身份的揭露', '导致丐帮内部争议'],\n", + " 'utterances': [{'text': '乔帮主,凡事三思,可不要胡乱行事才好。若是惹起了胡汉之争,中原豪杰人人与你为敌。',\n", + " 'time': '第十六章 昔时因'}],\n", + " 'speech_style': '劝导',\n", + " 'personality_traits': ['理智', '劝导'],\n", + " 'emotion_state': '谨慎',\n", + " 'relations': [{'target': '智光',\n", + " 'relation_type': '友善',\n", + " 'relation_strength': 0.3,\n", + " 'last_updated': '第十六章 昔时因',\n", + " 'derived_from': 'action:交流, impact:揭露真相'},\n", + " {'target': '马夫人',\n", + " 'relation_type': '陌生',\n", + " 'relation_strength': 0,\n", + " 'last_updated': '第十六章 昔时因',\n", + " 'derived_from': 'action:旁观, impact:无直接联系'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '谭婆': {'name': '谭婆',\n", + " 'first_appearance': 'chapters/chapter15',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林事件中',\n", + " 'location': '杏子林',\n", + " 'event': '人物谭婆与多个武林人物会面',\n", + " 'if_completed': True,\n", + " 'action': ['与武林同道会晤', '目睹西夏武士与丐帮冲突', '发表观点支持乔峰'],\n", + " 'motivation': ['维护江湖正义', '支持曾受自己恩惠的乔峰'],\n", + " 'involved_entities': ['乔峰',\n", + " '赵钱孙',\n", + " '徐长老',\n", + " '单正',\n", + " '马夫人',\n", + " '西夏武士',\n", + " '徐长老',\n", + " '单正'],\n", + " 'impact': ['对乔峰未被丐帮完全误解提供帮助', '影响丐帮对事件回顾的思考'],\n", + " 'utterances': [{'time': 'event_001',\n", + " 'content': '乔帮主,凡事三思,可不要胡乱行事才好。若是惹起了胡汉之争,中原豪杰人人与你为敌。'}],\n", + " 'speech_style': '直率',\n", + " 'personality_traits': ['直率', '幽默'],\n", + " 'emotion_state': '坚定',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '朋友',\n", + " 'relation_strength': 0.6,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'utterance:支持乔峰, impact:缓解乔峰被误解'},\n", + " {'target': '赵钱孙',\n", + " 'relation_type': '师兄',\n", + " 'relation_strength': 0.7,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:与赵钱孙互动, impact:互相调侃且无恶意'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '徐长老': {'name': '徐长老',\n", + " 'first_appearance': 'chapters/chapter16',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '小说第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '参与聚会谋划和历史揭露',\n", + " 'if_completed': True,\n", + " 'action': ['接待智光大师', '揭露乔峰契丹血统', '传递重要书信'],\n", + " 'motivation': ['维护丐帮稳定', '尊重和谋求真相'],\n", + " 'involved_entities': ['乔峰', '智光大师', '单正', '马夫人'],\n", + " 'impact': ['揭露乔峰身世,引发丐帮巨大变动', '影响乔峰退出帮主之位']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '智光大师': {'name': '智光大师',\n", + " 'first_appearance': 'chapters/chapter16',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '三十余年前',\n", + " 'location': '雁门关外乱石谷',\n", + " 'event': '参与雁门关外大战',\n", + " 'if_completed': True,\n", + " 'action': ['参与伏击契丹武士', '用毒暗器射击敌方', '未加确认地错杀契丹人'],\n", + " 'motivation': ['保护少林寺', '抵御契丹入侵', '误信情报,误杀无辜'],\n", + " 'involved_entities': ['丐帮汪帮主', '领先大哥', '契丹武士'],\n", + " 'impact': ['误杀很多契丹人', '错处置相关婴儿', '心中对当年事件留下愧疚']},\n", + " {'event_id': 'event_002',\n", + " 'time': '当今',\n", + " 'location': '杏子林',\n", + " 'event': '与丐帮高层会面并回忆过往',\n", + " 'if_completed': False,\n", + " 'action': ['接受徐长老等人的会面敬意', '参与讨论旧事和信件内容', '面对乔峰存在质疑'],\n", + " 'motivation': ['回应召唤', '解释过去误会'],\n", + " 'involved_entities': ['乔峰', '丐帮诸长老', '赵钱孙'],\n", + " 'impact': ['揭露乔峰出身真相', '激发丐帮内部对乔峰的信任危机']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '单仲山': {'name': '单仲山',\n", + " 'first_appearance': 'chapters/chapter16',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第五章',\n", + " 'location': '太行山',\n", + " 'event': '接受徐长老和单正的邀请',\n", + " 'if_completed': True,\n", + " 'action': ['接到徐长老和单正的联名邀请函'],\n", + " 'motivation': ['参与与天下苍生气运有关的大事'],\n", + " 'involved_entities': ['徐长老', '单正'],\n", + " 'impact': []},\n", + " {'event_id': 'event_002',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '围攻乔峰',\n", + " 'if_completed': True,\n", + " 'action': ['与兄弟一起攻击乔峰'],\n", + " 'motivation': ['保护兄弟', '回应乔峰的突然攻击'],\n", + " 'involved_entities': ['乔峰', '单叔山', '单季山'],\n", + " 'impact': ['被乔峰击败', '乔峰挟持智光和尚', '乔峰轻松应对攻击展示强大武力'],\n", + " 'utterances': [{'text': '不可!', 'time': 'event_002'}],\n", + " 'speech_style': '低沉',\n", + " 'personality_traits': ['维护家人', '冲动'],\n", + " 'emotion_state': '警惕',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.9,\n", + " 'last_updated': 'event_002',\n", + " 'derived_from': 'action:围攻, impact:被击败'}]},\n", + " {'event_id': 'event_003',\n", + " 'time': '第十六章',\n", + " 'location': '杏子林',\n", + " 'event': '参与丐帮帮主之争',\n", + " 'if_completed': True,\n", + " 'action': ['参与讨论丐帮帮主继任', '应对乔峰的质问'],\n", + " 'motivation': ['维护丐帮传统', '坚持帮规'],\n", + " 'involved_entities': ['乔峰', '丐帮众人'],\n", + " 'impact': ['乔峰辞去帮主之职'],\n", + " 'utterances': [{'text': '乔帮主,有话好说,千万不可动蛮。', 'time': 'event_003'}],\n", + " 'speech_style': '冷静',\n", + " 'personality_traits': ['理智', '不偏不倚'],\n", + " 'emotion_state': '担忧',\n", + " 'relations': [{'target': '丐帮',\n", + " 'relation_type': '盟友',\n", + " 'relation_strength': 0.5,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:维护帮规, impact:帮主交接'},\n", + " {'target': '乔峰',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.8,\n", + " 'last_updated': 'event_003',\n", + " 'derived_from': 'action:围攻, impact:辞去帮主'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '单叔山': {'name': '单叔山',\n", + " 'first_appearance': 'chapters/chapter16',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏林之会',\n", + " 'location': '杏子林',\n", + " 'event': '遭遇乔峰',\n", + " 'if_completed': False,\n", + " 'action': ['尝试阻止乔峰', '参与围攻乔峰'],\n", + " 'motivation': ['保护长老', '维护丐帮尊严'],\n", + " 'involved_entities': ['乔峰', '单仲山', '单季山'],\n", + " 'impact': ['无重大影响']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '单季山': {'name': '单季山',\n", + " 'first_appearance': 'chapters/chapter16',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '第十六章 昔时因,日间',\n", + " 'location': '杏林',\n", + " 'event': '参与乔峰事件',\n", + " 'if_completed': True,\n", + " 'action': ['与乔峰对峙', '被乔峰左手抓住,右手连抓连掷', '在地上掷下,被踏住头颅'],\n", + " 'motivation': ['家族遭遇事件的卷入,被迫参与'],\n", + " 'involved_entities': ['乔峰', '单正', '单仲山', '单叔山'],\n", + " 'impact': ['被乔峰展现武力震慑', '没有受伤但感受到乔峰的实力'],\n", + " 'utterances': [],\n", + " 'speech_style': '直接',\n", + " 'personality_traits': ['顽强', '勇敢'],\n", + " 'emotion_state': '震惊',\n", + " 'relations': [{'target': '乔峰',\n", + " 'relation_type': '敌人',\n", + " 'relation_strength': -0.5,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': 'action:对峙, impact:武力震慑'},\n", + " {'target': '单正',\n", + " 'relation_type': '亲属',\n", + " 'relation_strength': 0.8,\n", + " 'last_updated': 'event_001',\n", + " 'derived_from': '同为事件中的参与者'}]}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '赫连铁树': {'name': '赫连铁树',\n", + " 'first_appearance': 'chapters/chapter16',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '杏子林事件,卯时已过',\n", + " 'location': '杏子林',\n", + " 'event': '与丐帮和西夏武士对峙',\n", + " 'if_completed': False,\n", + " 'action': ['带领西夏一品堂挑战丐帮', '指挥努儿海使用悲酥清风迷倒丐帮'],\n", + " 'motivation': ['展示西夏国的武力', '削弱大宋丐帮的实力', '探查丐帮的真实水平'],\n", + " 'involved_entities': ['丐帮', '徐长老', '传功长老', '执法长老', '西夏武士', '努儿海', '云中鹤'],\n", + " 'impact': ['丐帮多数成员中毒倒地', '显露西夏武士的威胁'],\n", + " 'utterances': [{'event_id': 'event_001',\n", + " 'utterance': '贵帮帮主既不在此间,我家将军是不能跟你叙礼的了'}],\n", + " 'speech_style': '讽刺',\n", + " 'personality_traits': ['心机深沉', '精于策略'],\n", + " 'emotion_state': '自信',\n", + " 'relations': []}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '努儿海': {'name': '努儿海',\n", + " 'first_appearance': 'chapters/chapter16',\n", + " 'events': [{'event_id': 'event_001',\n", + " 'time': '卯时',\n", + " 'location': '杏子林',\n", + " 'event': '参与杏子林丐帮聚会',\n", + " 'if_completed': False,\n", + " 'action': ['参与袭击丐帮', '撒布毒气陷害丐帮众人', '试图捉拿王语嫣'],\n", + " 'motivation': ['辅助西夏一品堂打压丐帮', '展示西夏一品堂的武力'],\n", + " 'involved_entities': ['徐长老', '吴长老', '赫连铁树', '王语嫣', '段誉', '云中鹤', '丐帮众人'],\n", + " 'impact': ['丐帮众人失去行动能力', '试图抓住王语嫣未遂', '与丐帮间的矛盾加深']}],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '李延宗': {'name': '李延宗',\n", + " 'first_appearance': 'chapters/chapter17',\n", + " 'events': [],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '金阿二': {'name': '金阿二',\n", + " 'first_appearance': 'chapters/chapter17',\n", + " 'events': [],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '阿甲': {'name': '阿甲',\n", + " 'first_appearance': 'chapters/chapter17',\n", + " 'events': [],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '阿乙': {'name': '阿乙',\n", + " 'first_appearance': 'chapters/chapter17',\n", + " 'events': [],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '阿丙': {'name': '阿丙',\n", + " 'first_appearance': 'chapters/chapter17',\n", + " 'events': [],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '阿丁': {'name': '阿丁',\n", + " 'first_appearance': 'chapters/chapter17',\n", + " 'events': [],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '阿戊': {'name': '阿戊',\n", + " 'first_appearance': 'chapters/chapter17',\n", + " 'events': [],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []},\n", + " '阿己': {'name': '阿己',\n", + " 'first_appearance': 'chapters/chapter17',\n", + " 'events': [],\n", + " 'utterances': [],\n", + " 'speech_style': '',\n", + " 'personality_traits': [],\n", + " 'emotion_state': '',\n", + " 'relations': []}}" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memcubes" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "9f8c2f33", + "metadata": {}, + "outputs": [], + "source": [ + "alias_to_name = {}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "029ee0e8", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/cookbook/chapter3/connect.ipynb b/examples/cookbook/chapter3/connect.ipynb new file mode 100644 index 00000000..354f5585 --- /dev/null +++ b/examples/cookbook/chapter3/connect.ipynb @@ -0,0 +1,917 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 81, + "id": "2cd833ea", + "metadata": {}, + "outputs": [], + "source": [ + "import memos\n", + "from memos.configs.embedder import EmbedderConfigFactory\n", + "from memos.configs.memory import TreeTextMemoryConfig\n", + "from memos.configs.mem_reader import SimpleStructMemReaderConfig\n", + "from memos.embedders.factory import EmbedderFactory\n", + "from memos.mem_reader.simple_struct import SimpleStructMemReader\n", + "from memos.memories.textual.tree import TreeTextMemory\n", + "from memos.configs.mem_os import MOSConfig\n", + "import requests\n", + "import os\n", + "import ast\n", + "from dotenv import load_dotenv\n", + "from memos.mem_cube.general import GeneralMemCube\n", + "from memos.configs.mem_cube import GeneralMemCubeConfig\n", + "from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata\n", + "import importlib\n", + "import memos.memories.textual.tree_text_memory.retrieve.searcher as searcher\n", + "import memos.mem_os.core as core\n", + "importlib.reload(searcher)\n", + "importlib.reload(core)\n", + "importlib.reload(memos.mem_os.main)\n", + "import requests\n", + "import json\n", + "import os\n", + "import pickle\n", + "import time\n", + "from datetime import datetime\n", + "from concurrent.futures import ThreadPoolExecutor, as_completed\n", + "from requests.adapters import HTTPAdapter\n", + "from urllib3.util.retry import Retry\n", + "import re\n", + "from typing import Dict, List, Optional, Any, Set, Tuple\n", + "from dataclasses import dataclass, field\n", + "from enum import Enum\n", + "import numpy as np\n", + "from memos.memories.textual.tree import TreeTextMemory\n", + "from memos.configs.mem_os import MOSConfig\n", + "import inspect\n", + "from memos.configs.embedder import EmbedderConfigFactory\n", + "import uuid\n", + "from memos.mem_os.main import MOS\n", + "from memos.configs.memory import TreeTextMemoryConfig" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "711fd575", + "metadata": {}, + "outputs": [], + "source": [ + "config = TreeTextMemoryConfig.from_json_file(\"/root/Test/memos_config.json\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "3660c52e", + "metadata": {}, + "outputs": [], + "source": [ + "tree_memory = TreeTextMemory(config)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "73febd7e", + "metadata": {}, + "outputs": [], + "source": [ + "tree_memory.graph_store.clear()" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "f526a6a3", + "metadata": {}, + "outputs": [], + "source": [ + "tree_memory.load(\"/root/Test\")" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "e92f0a7e", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/opt/conda/lib/python3.10/site-packages/chonkie/tokenizer.py:282: UserWarning: Could not load tokenizer with 'tokenizers'. Falling back to 'tiktoken'.\n", + " warnings.warn(\n" + ] + } + ], + "source": [ + "mos_config = MOSConfig.from_json_file(\"/root/Test/server_memos_config.json\")\n", + "memory = MOS(mos_config)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "e265efa6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'root'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_id = \"root\"\n", + "os.environ[\"MOS_USER_ID\"] = user_id\n", + "memory.create_user(user_id=user_id)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "5411d2ca", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'root'" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "user_id = os.getenv(\"MOS_USER_ID\", \"default_user\")\n", + "user_id" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "e7c0cf8b", + "metadata": {}, + "outputs": [], + "source": [ + "os.environ[\"OPENAI_API_KEY\"] = \"sk-BboZZQNg570YPNhJrGjyPIjOsBpCzUSHRZaDFv4BBVCqTkRQ\"\n", + "os.environ[\"OPENAI_API_BASE\"] = \"http://123.129.219.111:3000/v1\"" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "3874d57f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "🔧 创建MemCube配置 (API版)...\n", + "✅ 检测到OpenAI API模式\n", + "memos.configs.vec_db - WARNING - vec_db.py:34 - set_default_path - No host, port, or path provided for Qdrant. Defaulting to local path: /root/Test/.memos/qdrant\n" + ] + } + ], + "source": [ + "print(\"🔧 创建MemCube配置 (API版)...\")\n", + "\n", + "# 加载环境变量\n", + "load_dotenv()\n", + "\n", + "# 检查API配置\n", + "openai_key = os.getenv(\"OPENAI_API_KEY\")\n", + "openai_base = os.getenv(\"OPENAI_API_BASE\", \"https://api.openai.com/v1\")\n", + "\n", + "if not openai_key:\n", + " raise ValueError(\"❌ 未配置OPENAI_API_KEY。请在.env文件中配置OpenAI API密钥。\")\n", + "\n", + "print(\"✅ 检测到OpenAI API模式\")\n", + "\n", + "# 获取配置\n", + "user_id = os.getenv(\"MOS_USER_ID\", \"default_user\")\n", + "top_k = int(os.getenv(\"MOS_TOP_K\", \"5\"))\n", + "\n", + "# OpenAI模式配置\n", + "config_memcube = GeneralMemCubeConfig(\n", + " user_id=user_id,\n", + " cube_id=f\"{user_id}_structured_memories_cube\",\n", + " text_mem={\n", + " \"backend\": \"general_text\",\n", + " \"config\": {\n", + " \"extractor_llm\": {\n", + " \"backend\": \"openai\",\n", + " \"config\": {\n", + " \"model_name_or_path\": \"gpt-4o\",\n", + " \"api_key\": openai_key,\n", + " \"api_base\": openai_base,\n", + " \"temperature\": 0.8,\n", + " \"max_tokens\": 8192,\n", + " }\n", + " },\n", + " \"embedder\": {\n", + " \"backend\": \"universal_api\",\n", + " \"config\": {\n", + " \"provider\": \"openai\",\n", + " \"api_key\": openai_key,\n", + " \"model_name_or_path\": \"text-embedding-ada-002\",\n", + " \"base_url\": openai_base,\n", + " }\n", + " },\n", + " \"vector_db\": {\n", + " \"backend\": \"qdrant\",\n", + " \"config\": {\n", + " \"collection_name\": f\"{user_id}_structured_memories\",\n", + " \"vector_dimension\": 1536,\n", + " \"distance_metric\": \"cosine\"\n", + " }\n", + " }\n", + " }\n", + " },\n", + " act_mem={\"backend\": \"uninitialized\"},\n", + " para_mem={\"backend\": \"uninitialized\"}\n", + ")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "d383cf15", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "🚀 开始创建结构化记忆MemCube (API版)...\n", + "memos.vec_dbs.qdrant - WARNING - qdrant.py:29 - __init__ - Qdrant is running in local mode (host and port are both None). In local mode, there may be race conditions during concurrent reads/writes. It is strongly recommended to deploy a standalone Qdrant server (e.g., via Docker: https://qdrant.tech/documentation/quickstart/).\n", + "memos.vec_dbs.qdrant - WARNING - qdrant.py:47 - create_collection - Collection 'root_structured_memories' (vector dimension: 768) already exists. Skipping creation.\n", + "✅ MemCube创建成功!\n", + " 📊 用户ID: root\n", + " 📊 MemCube ID: root_structured_memories_cube\n", + " 📊 文本记忆后端: general_text\n", + " 🔍 嵌入模型: text-embedding-ada-002 (OpenAI)\n", + " 🎯 配置模式: OPENAI API\n" + ] + } + ], + "source": [ + "print(\"🚀 开始创建结构化记忆MemCube (API版)...\")\n", + "\n", + "# 创建MemCube\n", + "mem_cube = GeneralMemCube(config_memcube)\n", + "\n", + "print(\"✅ MemCube创建成功!\")\n", + "print(f\" 📊 用户ID: {mem_cube.config.user_id}\")\n", + "print(f\" 📊 MemCube ID: {mem_cube.config.cube_id}\")\n", + "print(f\" 📊 文本记忆后端: {mem_cube.config.text_mem.backend}\")\n", + "print(f\" 🔍 嵌入模型: text-embedding-ada-002 (OpenAI)\")\n", + "print(f\" 🎯 配置模式: OPENAI API\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "99b53e30", + "metadata": {}, + "outputs": [], + "source": [ + "mem_cube.text_mem=tree_memory\n" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "05bbf292", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "🔍 查询所有记忆:\n", + "1. 钟万仇在过去及现在于万劫谷,因为昔日仇恨,进行了谋划报复段正淳,结果是构建仇恨并带来家庭紧张。\n", + " 键: 钟万仇的事件:谋划报复段正淳\n", + " 类型: LongTermMemory\n", + " 标签: ['事件']\n", + "\n", + "2. 钟万仇在小说片段中于万劫谷,因为对妻子忠诚的怀疑和脆弱感,进行了质疑与家庭冲突,结果是导致夫妻间的冲突和钟万仇情绪激动,甚至受伤。\n", + " 键: 钟万仇的事件:质疑与家庭冲突\n", + " 类型: LongTermMemory\n", + " 标签: ['事件']\n", + "\n", + "3. 钟万仇在当前于无量山,因为神农帮扣住钟灵,进行了让段誉代传信,结果是意图求救钟灵。\n", + " 键: 钟万仇的事件:让段誉代传信\n", + " 类型: LongTermMemory\n", + " 标签: ['事件']\n", + "\n", + "4. 钟万仇在目前于镇南王府,因为对段正淳的仇恨,进行了破坏镇南王府与四大恶人合作,结果是引发与大理国的冲突。\n", + " 键: 钟万仇的事件:破坏镇南王府与四大恶人合作\n", + " 类型: LongTermMemory\n", + " 标签: ['事件']\n", + "\n", + "5. 钟万仇在最近于镇南王府,因为担心夫人甘宝宝与段正淳的过去,进行了进入镇南王府与各人对峙,结果是与段正淳展开冲突,导致钟夫人被扣留。\n", + " 键: 钟万仇的事件:进入镇南王府与各人对峙\n", + " 类型: LongTermMemory\n", + " 标签: ['事件']\n", + "\n" + ] + } + ], + "source": [ + "all_memories = mem_cube.text_mem.get_all()\n", + "nodes = all_memories.get(\"nodes\", []) # 取出节点列表\n", + "\n", + "print(\"🔍 查询所有记忆:\")\n", + "for i, memory1 in enumerate(nodes, 1):\n", + " print(f\"{i}. {memory1['memory']}\")\n", + " print(f\" 键: {memory1['metadata'].get('key')}\")\n", + " print(f\" 类型: {memory1['metadata'].get('memory_type')}\")\n", + " print(f\" 标签: {memory1['metadata'].get('tags')}\")\n", + " print()\n", + " if i >= 5: # 最多展示5条\n", + " break" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "a594c748", + "metadata": {}, + "outputs": [], + "source": [ + "memory.register_mem_cube(mem_cube,user_id=user_id)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "bd2009f2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'夜风微拂,青石桥边的柳枝轻轻摇曳,如同诉说着岁月的无情。萧峰凝视着眼前的段正淳,脑中纷乱如麻。此刻,他的内力充盈于掌间,只需稍稍加力,便可为父母之仇得报。可是,脑海中闪过阿朱含笑的脸庞,他的心不由得剧痛起来,掌力犹如千钧,难以下落。\\n\\n就在他犹豫不决之际,忽觉腰间一紧,仿佛被什么东西轻轻缠住。低头一看,却是阿朱的柔荑,如白玉般无瑕,在月色下更显晶莹。她轻轻摇了摇头,低声说道:“乔大哥,且慢……”\\n\\n这一声“乔大哥”,如同拨动了萧峰心灵深处最柔软的地方。他骤然醒悟,险些犯下不可挽回的错误。内力随即散去,只感疲惫不堪。他看向段正淳,目光中多了几分复杂。\\n\\n段正淳虽被点住穴道,却依旧镇定,轻声叹道:“乔兄,似我段某从未加害于令尊令堂,此中必有误会。望乔兄明察。”\\n\\n萧峰黯然无语。阿朱见状,心中大慰,轻轻拍了拍他的肩膀,柔声劝道:“乔大哥,我们一起找出真相,不要被仇恨蒙蔽双眼。”\\n\\n她的话犹如泉水般清澈,化解了他心头的滔天恨意。两人对望一眼,彼此心意相通。\\n\\n然而,此刻月影摇曳,一片云翳悄悄遮住明月,整个世界顿时显得阴森恐怖。远处,隐隐传来铁骑铮铮的声响,仿佛有大队人马正在逼近。\\n\\n萧峰心生警觉,耳目俱动,低声道:“有情况!”阿朱俏脸微变,连忙附耳倾听。果然,那隐隐的马蹄声渐近,一支全副武装的队伍正疾驰而来。\\n\\n来人未至,已闻呼喝声,听那声音宏亮:“乔峰何在,速速现身受死!”随着声音传来,一队人马已如潮水般涌来,为首一人,身穿紫色长袍,面目俊朗,正是中原武林中鼎鼎有名的少林弟子——玄苦大师。\\n\\n萧峰本能地将阿朱护在身后,面对玄苦,却并未因对方来势汹汹而有一丝惧色,抱拳冷冷道:“萧某在此,敢问大师有何贵干?”\\n\\n玄苦双手合十,面露悲悯,道:“乔施主,武林传言纷纷,说你乃契丹余孽,实乃敌国潜入中原之探子。今日玄苦奉命前来缉拿,还望施主莫要反抗。”\\n\\n萧峰冷冷一笑,沉声道:“萧某行不改名,坐不改姓,纵然身属契丹,但自入中原,未曾做半点有负江湖道义之事。若说奸细,此言差矣。”\\n\\n玄苦面色一沉:“乔施主既然身为契丹人,理应早已立场不正。我等不愿与你多费唇舌,只愿施主随我前去,阐明心迹,给天下英雄一个交代。”\\n\\n萧峰看着这些昔日的同道好友,如今却成为追捕自己的人,心中不免黯然,却也知此番唯有一战,不由得斗志昂扬,运起内力,冷声说道:“既然如此,诸位道长尽管放马过来吧,萧某绝不退缩!”\\n\\n阿朱握紧他的手,给了他默默的支持,二人相依,仿佛忘记了周遭险恶。月光重新露出云层,映照着他们两人的身影,显得坚毅而坚定。\\n\\n玄苦手一挥,一队武僧蜂拥而上,直逼萧峰而来。萧峰与阿朱并肩而立,一面挥拳应敌,一面细心守护着身后无暇动手的段正淳。段正淳见情形危急,也不禁暗自佩服萧峰的武艺高强,心中对他大是惋惜。\\n\\n萧峰虽然以一敌众,却丝毫不惧,招式大开大合,犹如猛虎下山,瞬间将数名武僧击退。然而,对方人多势众,长时间鏖战之下,萧峰也渐觉不支,脸色微白,额头已然见汗。\\n\\n正当此时,只见一道窈窕身影从桥头飘然而至,轻盈如燕,霎时间便到了萧峰与阿朱身侧。来人长发如墨,面如桃李,竟是一身紫衣的神秘女子——王语嫣。\\n\\n她伸手入怀,取出一枚竹笛,轻轻吹奏起来。乐声悠扬婉转,如泉水涓涓,不知不觉间,众人竟被这乐声所吸引,渐渐心驰神往,连原本的打斗之声亦被笛声湮没。\\n\\n玄苦一惊,连忙运起内力,护住心神,但他身旁的弟子却不及防备,面露痴迷之色,一时间动作迟缓。萧峰抓住机会,爆喝一声,以排山倒海之势击退剩余敌手。\\n\\n当乐声渐歇,众武僧如梦初醒,方才意识到已被一女子轻易化解攻势,不由得面面相觑,难掩惊异之色。\\n\\n王语嫣却不再多言,微微一笑,将竹笛放回怀中,然后盈盈一礼:“在下王语嫣,见过乔大哥,阿朱姐姐。”萧峰与阿朱同感诧异,忙还了一礼,心知此女子必有不凡来历。\\n\\n玄苦虽然对笛声颇感震惊,但仍未退去敌意,沉声道:“乔施主今日就算有人相助,也休想逃脱我等围捕!”说罢,正欲再度发号施令。\\n\\n此时,只见段正淳微微一笑,朗声说道:“诸位若想真正了解真相,不如让我这老骨头多说几句,也好让乔帮主自证清白。”\\n\\n众人对段正淳虽无甚好感,但此时此刻,反倒被他的泰然自若所折服,不由得静候他的发言。\\n\\n段正淳缓缓说道:“我段某人,虽不是什么英雄豪杰,却也并非趁势落井下石之徒。乔帮主昔年英姿勃发,举手投足间令人折服,在武林中素有美名,乃我们所敬重的好汉。然而,阴谋诡谲,难测如意,真正的敌人,藏在暗处,才最可怕。”\\n\\n他的声音清朗,却透着无比的诚恳,直击众人心间。王语嫣亦点头附和:“段公子说得是。若无真正的证据,仅凭传言,便要给人定罪,这恐怕有失公允。”\\n\\n众人沉默良久,最终,玄苦无奈叹了口气,道:“今日之事,暂且到此为止。但请乔施主时刻谨记,他日若真有罪证,我等定然不会轻饶。”说完,收起兵刃,带领众人缓缓退去。\\n\\n萧峰心中一松,与阿朱对视一笑,内心深处仿佛找到了某种慰藉。他转向段正淳,诚心地说道:“段兄,此番多谢相助。来日必有报答之机。”\\n\\n段正淳摇头道:“乔兄何须多虑。小女与你甚是投缘,她日必定常来常往,共商义举。”\\n\\n三人并肩而行,于月夜之中,脚步踏上青石桥,向着未知的前方。各自心怀希望,期盼那未知的旅途,即便困难重重,也会携手共渡。'" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "memory.chat(\n", + " query=\"如果萧峰没打死阿朱,后续剧情会如何发展,请模仿金庸的口吻续写一章小说,不要笼统的概括,字数大于3000字,多描写细节,写一段事件,并不要直接写到结尾\",\n", + " user_id=\"root\"\n", + ")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "id": "0ad6303a", + "metadata": {}, + "outputs": [], + "source": [ + "def get_following_memory_texts(memory: TreeTextMemory, start_id: str, k: int = 30) -> list[str]:\n", + " \"\"\"\n", + " Return the metadata[\"memory\"] strings of the next k nodes following a given node via FOLLOWS edges.\n", + "\n", + " Args:\n", + " memory (TreeTextMemory): Memory system instance.\n", + " start_id (str): The starting node ID.\n", + " k (int): Number of following nodes to retrieve.\n", + "\n", + " Returns:\n", + " list[str]: List of memory texts from the following nodes.\n", + " \"\"\"\n", + " graph = memory.graph_store.export_graph()\n", + " nodes = {node[\"id\"]: node for node in graph[\"nodes\"]}\n", + " follows_map = {\n", + " edge[\"source\"]: edge[\"target\"]\n", + " for edge in graph[\"edges\"]\n", + " if edge[\"type\"] == \"FOLLOWS\"\n", + " }\n", + "\n", + " result = []\n", + " current_id = start_id\n", + " for _ in range(k):\n", + " next_id = follows_map.get(current_id)\n", + " if not next_id or next_id not in nodes:\n", + " break\n", + "\n", + " metadata = nodes[next_id].get(\"metadata\", {})\n", + " memory_text = metadata.get(\"memory\") or nodes[next_id].get(\"memory\") # fallback\n", + " if memory_text:\n", + " result.append(memory_text)\n", + " current_id = next_id\n", + "\n", + " return result" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "133267f1", + "metadata": {}, + "outputs": [], + "source": [ + "class APIClient:\n", + " \"\"\"简化版 API 调用客户端 - 只支持基础对话调用\"\"\"\n", + "\n", + " def __init__(self, api_url: str, api_key: str, model: str = \"gpt-4o\"):\n", + " self.api_url = api_url\n", + " self.api_key = api_key\n", + " self.model = model\n", + "\n", + " self.session = requests.Session()\n", + " self.session.headers.update({\n", + " \"Content-Type\": \"application/json\",\n", + " \"Authorization\": f\"Bearer {self.api_key}\"\n", + " })\n", + "\n", + " def call_api(self, messages: List[Dict], timeout: int = 1800) -> Dict:\n", + " \"\"\"发送 messages 给 API 并返回结果\"\"\"\n", + " payload = {\n", + " \"model\": self.model,\n", + " \"messages\": messages,\n", + " \"stream\": False\n", + " }\n", + "\n", + " try:\n", + " response = self.session.post(self.api_url, json=payload, timeout=timeout)\n", + " response.raise_for_status()\n", + " result = response.json()\n", + " return {\n", + " \"status\": \"success\",\n", + " \"content\": result[\"choices\"][0][\"message\"][\"content\"],\n", + " \"model_used\": self.model\n", + " }\n", + " except requests.exceptions.RequestException as e:\n", + " return {\n", + " \"status\": \"error\",\n", + " \"error\": str(e),\n", + " \"model_used\": self.model\n", + " }" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "99fcf996", + "metadata": {}, + "outputs": [], + "source": [ + "api_client = APIClient(\n", + " api_url=\"http://123.129.219.111:3000/v1/chat/completions\",\n", + " api_key=\"sk-ZXk4KtKH99yelVZKPrpGB2t8OrhUOoVV0hhGi26zgjkN58Ye\",\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "12bd6557", + "metadata": {}, + "outputs": [], + "source": [ + "def key_event_extraction(query):\n", + " name_prompt = [\n", + " {\n", + " \"role\": \"system\",\n", + " \"content\": \"你是一个精准事件抽取器。用户会描述一个或多个小说中发生过的事件,你需要从中提取出用户想要改变或讨论的关键事件,并用一句话简洁描述每个事件。\\n\"\n", + " \"要求:\\n\"\n", + " \"1. 每个事件必须是真实发生在小说原文中的事件,而非假设。\\n\"\n", + " \"2. 每个事件必须为一个字符串,构成 Python list 的元素。\\n\"\n", + " \"3. 最终输出必须是合法的 Python list,例如:\\n\"\n", + " '''[\"乔峰误杀阿朱\", \"段誉跳崖逃避婚姻\"]\\n'''\n", + " \"你只输出这个 list,不要添加任何解释或额外的内容。\"\n", + " },\n", + " {\n", + " \"role\": \"user\",\n", + " \"content\": \"如果萧峰没有杀阿朱,后续剧情会怎么样,写个3000字\"\n", + " }\n", + " ]\n", + " key_event = api_client.call_api(name_prompt)\n", + "\n", + " return ast.literal_eval(key_event[\"content\"])\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "38f9e795", + "metadata": {}, + "outputs": [], + "source": [ + "query=\"如果萧峰没有杀阿朱,后续剧情会怎么样,写个3000字\"" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "74f54e1e", + "metadata": {}, + "outputs": [], + "source": [ + "def get_event_contexts_for_prompt(\n", + " memory: TreeTextMemory,\n", + " event_texts: list[str],\n", + " k: int = 30\n", + ") -> dict[str, list[str]]:\n", + " \"\"\"\n", + " 对每个事件执行 search + 拿前两个匹配点 + 获取后续剧情,用于构造 GPT prompt。\n", + " \n", + " Args:\n", + " memory: TreeTextMemory 实例\n", + " event_texts: 提取出的事件文本列表\n", + " k: 每个节点向后取几个 follows\n", + "\n", + " Returns:\n", + " dict[str, list[str]]: {event_text -> [后续memory strings]}\n", + " \"\"\"\n", + " result = {}\n", + "\n", + " for event in event_texts:\n", + " try:\n", + " matches = memory.search(event, top_k=2)\n", + " memory_strings = []\n", + "\n", + " for match in matches:\n", + " follow_texts = get_following_memory_texts(memory, match.id, k)\n", + " memory_strings.extend(follow_texts)\n", + "\n", + " result[event] = memory_strings\n", + "\n", + " except Exception as e:\n", + " print(f\"Error processing event '{event}': {e}\")\n", + " result[event] = []\n", + "\n", + " return result\n", + "\n", + "event_extracted=key_event_extraction(query)\n", + "past_event = get_event_contexts_for_prompt(tree_memory,event_extracted)" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "4cd06b42", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['乔峰误杀阿朱']" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "key_event_extraction(query)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "fd278f09", + "metadata": {}, + "outputs": [], + "source": [ + "from memos.memories.textual.item import TextualMemoryItem, TreeNodeTextualMemoryMetadata\n", + "\n", + "\n", + "def node_dict_to_textual_item(node_dict):\n", + " return TextualMemoryItem(\n", + " id=node_dict[\"id\"],\n", + " memory=node_dict[\"memory\"],\n", + " metadata=TreeNodeTextualMemoryMetadata(**node_dict[\"metadata\"])\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "87f439f2", + "metadata": {}, + "outputs": [], + "source": [ + "import json\n", + "import uuid\n", + "from datetime import datetime\n", + "from pathlib import Path\n", + "import requests # 用于请求 Ollama 本地 API\n", + "\n", + "# === EMBEDDING via Ollama (nomic-embed-text:latest) ===\n", + "import requests\n", + "\n", + "def get_embedding(text):\n", + " url = \"http://123.129.219.111:3000/v1/embeddings\"\n", + " headers = {\n", + " \"Authorization\": \"Bearer sk-BboZZQNg570YPNhJrGjyPIjOsBpCzUSHRZaDFv4BBVCqTkRQ\",\n", + " \"Content-Type\": \"application/json\"\n", + " }\n", + " payload = {\n", + " \"input\": text,\n", + " \"model\": \"text-embedding-ada-002\"\n", + " }\n", + " try:\n", + " response = requests.post(url, headers=headers, json=payload)\n", + " response.raise_for_status()\n", + " return response.json()[\"data\"][0][\"embedding\"]\n", + " except Exception as e:\n", + " print(f\"⚠️ 获取 embedding 失败:{e}\")\n", + " return None\n", + "# === TIME STAMP ===\n", + "def iso_now():\n", + " return datetime.now().isoformat()\n", + "\n", + "# === CREATE MEMORY NODE ===\n", + "def create_memory_node_working(content, entities, key, memory_type=\"WorkingMemory\"):\n", + " now = iso_now()\n", + " node_id = str(uuid.uuid4())\n", + " embedding = get_embedding(content)\n", + "\n", + " metadata = TreeNodeTextualMemoryMetadata(\n", + " user_id=\"\",\n", + " session_id=\"\",\n", + " status=\"activated\",\n", + " type=\"fact\",\n", + " confidence=0.99,\n", + " entities=entities,\n", + " tags=[\"事件\"] if \"事件\" in key else [\"关系\"],\n", + " updated_at=now,\n", + " memory_type=memory_type,\n", + " key=key,\n", + " sources=[],\n", + " embedding=embedding,\n", + " created_at=now,\n", + " usage=[],\n", + " background=\"\"\n", + " )\n", + "\n", + " return TextualMemoryItem(id=node_id, memory=content, metadata=metadata)" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "710d230a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Assistant: 青石桥畔,夜风轻拂,杨柳依依。萧峰面目如铁,掌中聚力如山,他心中的怒焰已然沸腾。可是,这滚烫的愤怒却被一声轻唤,仿佛一泓清水,顿时化为无形。\n", + "\n", + "“乔大哥,请先冷静下来。”阿朱用那澄澈如水的眸子凝望着他,温声劝慰。她的神情柔和,不禁让萧峰心头一震。\n", + "\n", + "萧峰望着面前的段正淳,虽是满腔愤懑,却难以下手。他微微叹息,轻轻松开掌力,段正淳禁制解除,却依旧安然无恙。\n", + "\n", + "“乔兄,大可放下心头重石,”段正淳一笑,语气不卑不亢,“在下之过,定然全力补偿,也绝不会妄加恶意。”\n", + "\n", + "听到这句话,萧峰心中更是千回百转。事情远比他想象中复杂,江湖险恶,如是幻境。萧峰目光悠然,既然当下无法用武力解决恩怨,便唯有潜心寻觅真相。\n", + "\n", + "然而,正当二人言辞之间,忽闻异声扑面而来,低哑呼喝与铁骑激烈相鸣,瞬间如迅雷横扫夜幕,队伍如潮水涌来。萧峰紧紧握住阿朱的手,感受到她轻微的颤抖。\n", + "\n", + "“乔峰现身!今晚一战,势在必行!”喝声震天,轰响如雷。\n", + "\n", + "来者不善,为首的正是武林中号称“铁面无私”的少林长老——玄寂。萧峰面无畏惧,淡淡扫视众人,周身内力暗流,彷如澎湃海潮。\n", + "\n", + "萧峰道:“众位,夜深露重,所为何事?若是能容萧某一个解释,自然不妨,不然就请立阵分身,我萧某奉陪到底!”\n", + "\n", + "阿朱微微动容,心知局势无法以寻常言辞平息,不禁俏面微沉,紧贴萧峰侧旁。萧峰虽不愿对抗,但也知己方毫无退路。阿朱感受到了他的决然,两人默契地对视一眼,心意相通。\n", + "\n", + "众武林人物目光炯炯,如虎视羚羊。玄寂长老略微颔首,冷峻言道:“乔施主,以你契丹身份,若还坚持误导,以图逃脱,恐无正道!”此言如冰,声声渐催。\n", + "\n", + "萧峰心情抖动,愤意几乎难平。他与阿朱临危而立,如铁壁坚城。虽是困兽之斗,然此一刻却胜若无前。\n", + "\n", + "玄寂手中亮出明黄戒尺,挥动如风,“此乃契丹奸细,我等绝不姑息,然尚应施加正义衡衡。”\n", + "\n", + "此时,气氛渐至冰火相融,蓄满仇恨,如同两军对峙的临界。此刻,有人挺身而出,朗声高喝,正是“慕容复”。\n", + "\n", + "“且慢!诸位道友,万莫以情敌疏,再述二意。”声音铿锵如钟,震慑心神。\n", + "\n", + "众人闻之,全场低凝,目光在慕容复与萧峰之间游离。慕容复的到来,无疑带来了未知的转机。\n", + "\n", + "萧峰望向慕容复,此时此刻,那人的身份竟成谜样变幻,而慕容复则目光坦诚,不惧迎视。他彬彬说道:“在下于今日幸承乔帮主恩情,而疑似乔某未入外途,有欠审慎,不论表里,一理所共求。”\n", + "\n", + "慕容复之言动摇人心,各派长老不免狐疑对望,玄寂虽有疑虑,却也微显迟疑。他负手而立,沉思片刻,终以正言回声:“我等中原浩然有形,当然清绝非私,我自得为信者可信。”\n", + "\n", + "众人的目光投向萧峰,与其相视无言,而夜空如暗潮涌动,隐蕴天地之力。\n", + "\n", + "此时,萧峰心意忽定,定眸目对诸人,声如劲箭发出:“凡以诚心共述,所为大好事,我萧某信仰身清,更复怀希望。然今日似如波澜海潮,有虽静若苛求。”\n", + "\n", + "言辞方毕,阿朱已缓步前踏,欲与萧峰并肩言道:“乔大哥,你已实示,有则诚何不照心敞态?”\n", + "\n", + "萧峰颔首,双拳收紧,仿如屹立剑门。他道:“心胸天地如宽,我道已示,即所证既自信无挽。”\n", + "\n", + "阿朱忽然清叹,握紧他的双手,继续道:“我信你明雪晓月,谓定你复天地之清然。”\n", + "\n", + "如此凝重间,正有一人遥远相向,举步却轻飘,赫然是王语嫣现身。她举步如丝柳,袖中闪出竹笛,迎风吹奏,乐音回环如秋风惊鸿,幻象迷惑。\n", + "\n", + "众人只觉恍惚如梦,遽间心神缭绕,竟莫能出其真相。而玄寂与诸长老犹未见觉,早已落陷其中。\n", + "\n", + "王语嫣含笑将竹笛收回,“我语嫣一味轻数,以救应命,而非旁顾。乔大哥非议一词,我谓过矣。”萧峰一感慰,心知事已转变,方然言道:“多承王姑娘相助。”\n", + "\n", + "不知何时,天光将将放明,淡云如披纱罩星,众武林人物欲踏再寻,不欲耗尽平身之力,却已如若败如。玄寂见势无绪,委屈将意:“今日所信不过,而先此解除,行必且只谐!”\n", + "\n", + "言罢,众人随之而去,广阔星夜深邃如海。\n", + "\n", + "萧峰与阿朱遥立星桥,风生如夜,仿似越动不灭心情。他凝视如霜霜月然透,却别如秋后愁寂然生。\n", + "\n", + "段正淳则微垂,见世若明,不见私忧。他感言真诚:“我定报识心敬,不为迷赐罪,心再情信。”\n", + "\n", + "明月如水,山河依旧。萧峰与阿朱并肩前行,似是踏足天地间长途,他持月梦光,生有光华重霜,一抱遥望清明如初。\n", + "\n", + "虽然迷雾初散,然江湖未歇。萧峰心头陡然突现未知之感,如云中雷,悄然于内心逐逼。江湖诡谲,然更蕴重重隐秘。他不曾知晓,此夜之后,历程如月,何处至此,俟再寻未详。即若缥缈成语,付诸奔流随乾坤。\n" + ] + } + ], + "source": [ + "response = memory.chat(\n", + " query=\"如果萧峰没打死阿朱,后续剧情会如何发展,请模仿金庸的口吻续写一章小说\",\n", + " user_id=\"root\",\n", + " base_prompt = build_story_engine_system_prompt(past_event)\n", + ")\n", + "print(f\"Assistant: {response}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9a785606", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Assistant: 天色未明,黑夜中的荒野悄无声息,如一匹巨大的猛兽蛰伏于天地间。经过方才一场惊险的对峙,萧峰与阿朱心情稍有宁息,段正淳亦是长舒了一口气。他知道,虽然一场误会暂时解开,但江湖风云依旧未散。\n", + "\n", + "三人缓步行于荒郊野径,阿朱紧握着萧峰的手,她明白这一刻的平静或许只是暴风雨前的宁谧,内心深处仍有一种隐隐的不安。\n", + "\n", + "“乔大哥,我们接下来当何去何从?”阿朱轻声问道,目光流转,望向萧峰,充满信任。\n", + "\n", + "“前路不明,只能随遇而安。”萧峰深邃的眼眸中闪过一丝坚定,“段兄,今日得你相助,实在多谢,接下来不知你有何打算?”\n", + "\n", + "段正淳微微一笑,面色凝重:“在下仍需返回大理,整顿内务,这一场劫难不算小,或许对大理的安危也是一番挑战。”\n", + "\n", + "他语气凝重,心中暗自揣度:此次乔峰的契丹身份已曝露于世,恐将引发更大的风波。而在他不愿透露的深处,更多的则是对隐隐现于暗中的敌人的忌惮。\n", + "\n", + "江湖险象环生,绝非仅存于眼前,更有无法预知的深流暗涌。三人越过荒坡,直至抵达一处破庙稍事休息,彼此谈论间,有意无意间也聊到了天南地北。\n", + "\n", + "正当这时,庙外忽传来清晰急促的马蹄声。萧峰闻声一怔,即刻凝神相望,只见一道黑影迅速朝破庙接近,劲风披襟而过。\n", + "\n", + "“来者何人?”萧峰朗声呼喝。\n", + "\n", + "马蹄骤止,沙砾飞扬,惊尘散尽,一匹乌云踏雪奔驰至庙门,一位黑衣人飘然下马。此人身形俊朗,面目含煞,显然身份不凡。他遥指天际,冷冷一笑:“乔峰,你可曾认得在下?”\n", + "\n", + "萧峰微微一怔,对方毫不遮掩,那股挑衅之意不由得令他心生警惕。然而他细细打量,终不能记起有过交集。他抱拳肃声道:“阁下何人,若无故滋扰,请恕我萧某无暇奉陪。”\n", + "\n", + "此刻,黑衣人呵呵笑道:“在下‘影刃’岳千仞,久闻乔帮主大名,特来请教。”言辞之间,已经动如风雷,瞬息间逼至萧峰近旁,掌出如电,劲风骤生。\n", + "\n", + "萧峰对阵略无避让,聚劲迎击,两股霸劲轰然对峙,四下飞尘尽起,沙石碎裂,卷向空中如波涛怒卷。\n", + "\n", + "岳千仞一击不成,却见萧峰掌中内力汹涌如潮,不由得骇然。猛地抽身后退,扬声道:“果然如传闻一般,乔帮主武艺无双,但岳某奉命在身,不敢不为。”他双掌交错,身形宛如幽灵,左右游走,步步逼近。\n", + "\n", + "这一来一回之间,已是毫无退路。萧峰默然不语,目光炯炯如炬,脚步稳如泰山,握住阿朱的手分毫不动,阿朱则心如鹿撞,却未显露丝毫怯意。\n", + "\n", + "破庙寂静,唯有风声呼啸。眼见岳千仞攻势凛然,阿朱心中一片紧张,萧峰却从容应对,只以八成实力化解来招,隐忍不发。\n", + "\n", + "正在此刻,只听破庙门侧一声长啸传来,浑厚如雷,正是段正淳来援,只见他快如奔马,挥袖中折扇猛地扫出,激得一阵劲风,巧妙介入岳千仞与萧峰之间,化开暗流。\n", + "\n", + "岳千仞猛地凝神,料不到段正淳插手。段正淳微一抱拳:“这位兄台,我三人此夜偶入此地,欲求一息安宁。阁下若仍执意相逼,我段某虽非武林高手,但也不愿屈辱于人!”\n", + "\n", + "一番话既出,岳千仞反而霎时冷静下来,仿佛感受到此间气氛微妙变化。岳千仞双眉微皱,内心思量甚深。饶是如此,他也在段正淳眼中察觉到一丝不易觉察的神情暗波。\n", + "\n", + "阿朱在一旁观察入微,心念急转,她轻叹一声,压低声量,对萧峰道:“乔大哥,段公子已然隐忧,我等如被卷入波涛难寻,事不宜迟,该往明朗处趋之。”\n", + "\n", + "正如此时,忽闻岳千仞高声一喝,展目满是寒光:“承惠如传,翌日定以火再见。”\n", + "\n", + "言毕,乌云踏雪再次一声长嘶,迅如疾电,去得无影无踪,只余地上纷扬马蹄印,幽然依稀。\n", + "\n", + "破庙之内,萧峰目光远随其至,心头悸动犹然未息。外间凉风,轻抚旌檐,恍若鸣笛耳边,暗示幽远声响。\n", + "\n", + "段正淳未语轻摇头,终凝其目,“前路未明,我料岳氏分明有逗劣,是谋此等策调,江湖中才并非简单。”\n", + "\n", + "此情已显入江湖一场更大风云,只听叶声脆鸣,沙尘低卷,指向的是何方远逝处的机遇莫测。\n", + "\n", + "阿朱紧握着萧峰的手,内心纷乱如网,轻轻言道:“乔大哥,看来我们当需尽快厘清,调来阴霾,涉足隐城。”\n", + "\n", + "萧峰点了点头,内心已有方略。然就在此刻,黎明的一线曙光悄悄透出,映照在三人的面庞上。可是,在光明的预兆之中,似乎隐隐浮现了更多未知的敌影,还有潜藏的险境。彼时一行三人迎着晨光,缓步踏出破庙,而新一段无垠旅途正悄然展开。\n", + "\n", + "不知在何方的江湖路途上,一双无声无息却显露锋芒的眼睛正关注着他们,默默记下他们的每一寸踪迹,预备展开一场更为巨大的阴谋算计。\n" + ] + } + ], + "source": [ + "memory_tmp = create_memory_node_working(response, [],\"\")\n", + "mem_cube.text_mem.add([memory_tmp])\n", + "response = memory.chat(\n", + " query=\"继续前文的剧情续写,模仿金庸风格续写一段完整中段剧情,聚焦江湖事件、外部势力与冲突,情感描写为辅,结尾留伏笔。\",\n", + " user_id=\"root\",\n", + " base_prompt = continue_story_building_prompt(past_event)\n", + ")\n", + "print(f\"Assistant: {response}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "id": "59369c4b", + "metadata": {}, + "outputs": [], + "source": [ + "def build_story_engine_system_prompt(past_event) -> str:\n", + " return (\n", + " \"你是一个专门负责小说创作的高级 AI 模型,擅长以模仿原作者风格创作中段情节。你的任务是根据用户输入的假设剧情和人物记忆(memory),创作一段完整的剧情发展。\\n\\n\"\n", + " \"你的创作必须遵守以下规则:\\n\\n\"\n", + " \"1. 使用原本风格的段落式小说语言,**不得**使用列表、摘要、分析型语言。\\n\"\n", + " f\"2. 请基于原本的叙事节奏,原文剧情中的后续发展记忆如下{past_event},请作为参考。\"\n", + " \"2. 结尾应保留张力、未解之谜或新冲突,为后续章节埋下伏笔。\\n\\n\"\n", + " \"3. 如果用户假设的剧情严重偏离世界观(比如在武侠小说里说主角提起了RPG),则提醒用户不恰当。\\n\\n\"\n", + " \"你拥有人物的性格、过往事件、动机与情绪等结构化记忆(memory),可用于辅助判断和创作,**但不可直接提及或解释 memory 的存在**。\\n\\n\"\n", + " \"你的目标是像作者本人续写自己的小说那样,保留风格、节奏、人物逻辑与复杂性,以事件为骨,以情感为脉,以文采为血肉。\"\n", + " )\n", + "\n", + "def continue_story_building_prompt(past_event) ->str:\n", + " return (\n", + " \n", + " \"你是一个专门负责小说创作的高级 AI 模型,擅长以模仿原作者风格创作中段情节。\\n\\n\"\n", + " \"你将根据之前的小说正文继续进行创作,遵循以下规则:\\n\\n\"\n", + " \"1. 使用原本风格的段落式小说语言,**不得**使用列表、摘要、分析型语言。\\n\"\n", + " f\"2. 请基于原本的叙事节奏,原文剧情中的后续发展记忆如下{past_event},请作为参考。\"\n", + " \"2. 结尾应保留张力、未解之谜或新冲突,为后续章节埋下伏笔。\\n\\n\"\n", + " \"3. 如果用户假设的剧情严重偏离世界观(比如在武侠小说里说主角提起了RPG),则提醒用户不恰当。\\n\\n\"\n", + " \"你拥有人物的性格、过往事件、动机与情绪等结构化记忆(memory),可用于辅助判断和创作,**但不可直接提及或解释 memory 的存在**。\\n\\n\"\n", + " \"你的目标是像作者本人续写自己的小说那样,保留风格、节奏、人物逻辑与复杂性,以事件为骨,以情感为脉,以文采为血肉。\"\n", + " )\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b3091e9a", + "metadata": {}, + "outputs": [], + "source": [ + "print(\"🔍 搜索包含'段誉'的记忆:\")\n", + "search_results = mem_cube.text_mem.search(\"段誉\", top_k=5)\n", + "\n", + "unique_memories = set()\n", + "for result in search_results:\n", + " # 这里 result 是 TextualMemoryItem 类型\n", + " if hasattr(result, \"memory\") and result.memory not in unique_memories:\n", + " print(f\"- {result.memory}\")\n", + " unique_memories.add(result.memory)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a52774c7", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "base", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.10" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/cookbook/chapter3/qa_rephrase.py b/examples/cookbook/chapter3/qa_rephrase.py new file mode 100644 index 00000000..6899a9ba --- /dev/null +++ b/examples/cookbook/chapter3/qa_rephrase.py @@ -0,0 +1,993 @@ +""" +QA转文本批量处理系统 + +依赖安装: +pip install jsonrepair + +如果没有安装jsonrepair,系统会自动跳过该修复策略,使用其他容错机制。 +""" + +import requests +import json +import os +import pickle +import time +from datetime import datetime +from concurrent.futures import ThreadPoolExecutor, as_completed +from requests.adapters import HTTPAdapter +from urllib3.util.retry import Retry +import re +from typing import Dict, List, Optional, Any +from dataclasses import dataclass +from enum import Enum + +# 尝试导入jsonrepair,如果没有安装则提供备用方案 +try: + from json-repair import repair_json + HAS_JSONREPAIR = True + print("✓ jsonrepair库已加载,JSON修复功能已启用") +except ImportError: + HAS_JSONREPAIR = False + print("⚠ jsonrepair库未安装,将使用基础修复策略。运行 'pip install jsonrepair' 启用高级JSON修复") + def repair_json(text): + return text + + +class TaskType(Enum): + COT_GENERATION = "cot_generation" + ANSWER_VERIFICATION = "answer_verification" + TEXT_CONVERSION = "text_conversion" + + +@dataclass +class ProcessingResult: + """处理结果数据类""" + status: str # success, api_error, validation_error + task_type: TaskType + qa_id: str + input_data: Dict + response: Optional[str] = None + parsed_result: Optional[Dict] = None + error_details: Optional[str] = None + processing_time: Optional[float] = None + + +class APIClient: + """抽象的API调用客户端""" + + def __init__(self, api_url: str, api_key: str, model_name: str): + self.api_url = api_url + self.api_key = api_key + self.model_name = model_name + + # 创建session并配置连接池和重试策略 + self.session = requests.Session() + + retry_strategy = Retry( + total=3, + backoff_factor=1, + status_forcelist=[500, 502, 503, 504], + ) + + adapter = HTTPAdapter(pool_connections=10, pool_maxsize=20, max_retries=retry_strategy) + self.session.mount('http://', adapter) + self.session.mount('https://', adapter) + + self.session.headers.update({ + "Content-Type": "application/json", + "Authorization": f"Bearer {self.api_key}" + }) + + def call_api(self, messages: List[Dict], timeout: int = 60) -> Dict: + """统一的API调用方法""" + data = { + "model": self.model_name, + "messages": messages, + "stream": False + } + + try: + response = self.session.post(url=self.api_url, json=data, timeout=timeout) + response.raise_for_status() + result = response.json() + return { + "status": "success", + "content": result['choices'][0]['message']['content'] + } + except requests.exceptions.RequestException as e: + return { + "status": "error", + "error": str(e) + } + + +class PromptTemplates: + """提示词模板类""" + + @staticmethod + def get_cot_prompt(question: str, options: str) -> str: + """步骤1:COT推理生成提示词""" + return f"""Please analyze the following multiple choice question. Think step by step and provide detailed reasoning process, then give the final answer. + +Question: +{question} + +Options: +{options} + +Please output ONLY a valid JSON object in the following format (no markdown, no extra text): +{{ + "reasoning": "Think step by step. Provide detailed reasoning process explaining why you choose this answer", + "answer": "Final answer (the complete value corresponding to the option)" +}} + +Requirements: +1. The reasoning section should contain sufficient medical/academic knowledge explanations +2. Think step by step and analyze the validity of each option +3. The answer section should directly provide the complete value corresponding to the option (not A/B/C/D) +4. Output ONLY the JSON object, no additional text or formatting""" + + @staticmethod + def get_verification_prompt(qa_data: Dict, generated_answer: str) -> str: + """步骤2:答案一致性验证提示词""" + return f"""Question and Options: +{qa_data['input']} + +Correct Answer: {qa_data['output']} + +Model Generated Answer: {generated_answer} + +Please output ONLY a valid JSON object in the following format (no markdown, no extra text): +{{ + "is_consistent": true/false +}} + +Judge whether the model's generated answer is semantically consistent with the correct answer. Output ONLY the JSON object.""" + + @staticmethod + def get_text_conversion_prompt(question: str, reasoning: str, answer: str) -> str: + """步骤3:转换为陈述性文本提示词""" + return f"""Please convert the following multiple choice question, reasoning process, and answer into a knowledge-rich declarative text. + +Original question: +{question} + +Reasoning process: +{reasoning} + +Answer: +{answer} + +Please output ONLY a valid JSON object in the following format (no markdown, no extra text): +{{ + "knowledge_text": "Converted declarative text" +}} + +Requirements: +1. The text should be a self-contained knowledge point description that does not depend on the original question +2. Integrate the question background, knowledge points in the reasoning process, and conclusions +3. Use declarative sentences and avoid question forms +4. Retain important medical/academic terms and concepts +5. Avoid referencing specific individual cases (e.g., “Xiao Wang had diarrhea”); present the content at a generalizable level +6. The text should be of moderate length with high information density +7. Output ONLY the JSON object, no additional text or formatting""" + + +class ResponseValidator: + """响应验证器""" + + @staticmethod + def validate_json_response(response_text: str, expected_keys: List[str]) -> Dict: + """ + 验证API返回的内容是否为有效JSON,包含预处理容错 + + Returns: + dict: { + "is_valid_json": bool, + "parsed_json": dict or None, + "error_type": str, + "raw_response": str + } + """ + if not response_text or not response_text.strip(): + return { + "is_valid_json": False, + "parsed_json": None, + "error_type": "empty_response", + "raw_response": response_text + } + + repair_attempts = [] + + try: + # 预处理清理 + text = response_text.strip() + + # 1. 处理markdown代码块 ```json...``` 或 ```...``` + code_block_match = re.search(r'```(?:json)?\s*\n?(.*?)\n?```', text, re.DOTALL) + if code_block_match: + text = code_block_match.group(1).strip() + + # 2. 处理引号包装 '...' 或 "..." + if (text.startswith("'") and text.endswith("'")) or (text.startswith('"') and text.endswith('"')): + text = text[1:-1] + + # 3. 移除前后的反引号 + text = text.strip('`').strip() + + # 4. 查找JSON部分 - 第一个{到最后一个} + json_match = re.search(r'(\{.*\})', text, re.DOTALL) + if json_match: + text = json_match.group(1) + + # 第一次尝试:直接解析 + try: + parsed = json.loads(text) + repair_attempts.append("direct_parse_success") + except json.JSONDecodeError as e: + repair_attempts.append(f"direct_parse_failed: {str(e)}") + + # 第二次尝试:使用jsonrepair修复后解析 + if HAS_JSONREPAIR: + try: + repaired_text = repair_json(text) + parsed = json.loads(repaired_text) + repair_attempts.append("jsonrepair_success") + except Exception as e: + repair_attempts.append(f"jsonrepair_failed: {str(e)}") + raise # 重新抛出异常 + else: + repair_attempts.append("jsonrepair_not_available") + raise # 重新抛出异常 + + # 检查是否符合预期的结构 + if isinstance(parsed, dict) and all(key in parsed for key in expected_keys): + return { + "is_valid_json": True, + "parsed_json": parsed, + "error_type": None, + "raw_response": response_text, + "repair_attempts": repair_attempts + } + else: + missing_keys = [key for key in expected_keys if key not in parsed] if isinstance(parsed, dict) else expected_keys + return { + "is_valid_json": False, + "parsed_json": parsed, + "error_type": f"missing_keys: expected {expected_keys}, missing {missing_keys}", + "raw_response": response_text, + "repair_attempts": repair_attempts + } + + except json.JSONDecodeError as e: + return { + "is_valid_json": False, + "parsed_json": None, + "error_type": f"json_decode_error: {str(e)}", + "raw_response": response_text, + "repair_attempts": repair_attempts + } + except Exception as e: + return { + "is_valid_json": False, + "parsed_json": None, + "error_type": f"unexpected_error: {str(e)}", + "raw_response": response_text, + "repair_attempts": repair_attempts + } + + +class QAToTextProcessor: + """QA转文本处理器主类""" + + def __init__(self, api_client: APIClient): + self.api_client = api_client + self.validator = ResponseValidator() + + def process_single_qa(self, qa_data: Dict, qa_id: str) -> List[ProcessingResult]: + """处理单个QA的完整流程""" + results = [] + + # 解析输入数据 + input_text = qa_data['input'] + expected_output = qa_data['output'] + + # 提取题目和选项 + question_part = input_text.split('\n选项:')[0] + options_part = input_text.split('\n选项:')[1] if '\n选项:' in input_text else "" + + # 步骤1:COT推理生成 + start_time = time.time() + cot_result = self._generate_cot(question_part, options_part, qa_id) + cot_result.processing_time = time.time() - start_time + results.append(cot_result) + + if cot_result.status != "success": + return results + + # 从第一步结果中提取纯答案(不包含推理过程) + generated_answer = cot_result.parsed_result.get('answer', '') + reasoning = cot_result.parsed_result.get('reasoning', '') + + # 步骤2:答案验证(比较纯答案与标准答案的语义一致性) + start_time = time.time() + verification_result = self._verify_answer(qa_data, generated_answer, qa_id) + verification_result.processing_time = time.time() - start_time + results.append(verification_result) + + if verification_result.status != "success": + return results + + is_consistent = verification_result.parsed_result.get('is_consistent', False) + if not is_consistent: + # 答案不一致,记录但不继续处理 + return results + + # 步骤3:文本转换(使用完整的题目、推理过程和答案) + start_time = time.time() + conversion_result = self._convert_to_text(question_part, reasoning, generated_answer, qa_id) + conversion_result.processing_time = time.time() - start_time + results.append(conversion_result) + + return results + + def _generate_cot(self, question: str, options: str, qa_id: str) -> ProcessingResult: + """生成COT推理""" + prompt = PromptTemplates.get_cot_prompt(question, options) + messages = [{"role": "user", "content": prompt}] + + api_result = self.api_client.call_api(messages) + + if api_result["status"] != "success": + return ProcessingResult( + status="api_error", + task_type=TaskType.COT_GENERATION, + qa_id=qa_id, + input_data={"question": question, "options": options}, + error_details=api_result["error"] + ) + + # 验证响应格式 + validation_result = self.validator.validate_json_response( + api_result["content"], ["reasoning", "answer"] + ) + + if not validation_result["is_valid_json"]: + return ProcessingResult( + status="validation_error", + task_type=TaskType.COT_GENERATION, + qa_id=qa_id, + input_data={"question": question, "options": options}, + response=api_result["content"], + error_details=f"{validation_result['error_type']} | repair_attempts: {validation_result.get('repair_attempts', [])}" + ) + + return ProcessingResult( + status="success", + task_type=TaskType.COT_GENERATION, + qa_id=qa_id, + input_data={"question": question, "options": options}, + response=api_result["content"], + parsed_result=validation_result["parsed_json"] + ) + + def _verify_answer(self, qa_data: Dict, generated_answer: str, qa_id: str) -> ProcessingResult: + """验证LLM生成的纯答案与标准答案的语义一致性""" + prompt = PromptTemplates.get_verification_prompt(qa_data, generated_answer) + messages = [{"role": "user", "content": prompt}] + + api_result = self.api_client.call_api(messages) + + if api_result["status"] != "success": + return ProcessingResult( + status="api_error", + task_type=TaskType.ANSWER_VERIFICATION, + qa_id=qa_id, + input_data={ + "qa_data": qa_data, + "llm_generated_answer": generated_answer + }, + error_details=api_result["error"] + ) + + validation_result = self.validator.validate_json_response( + api_result["content"], ["is_consistent"] + ) + + if not validation_result["is_valid_json"]: + return ProcessingResult( + status="validation_error", + task_type=TaskType.ANSWER_VERIFICATION, + qa_id=qa_id, + input_data={ + "qa_data": qa_data, + "llm_generated_answer": generated_answer + }, + response=api_result["content"], + error_details=f"{validation_result['error_type']} | repair_attempts: {validation_result.get('repair_attempts', [])}" + ) + + return ProcessingResult( + status="success", + task_type=TaskType.ANSWER_VERIFICATION, + qa_id=qa_id, + input_data={ + "qa_data": qa_data, + "llm_generated_answer": generated_answer + }, + response=api_result["content"], + parsed_result=validation_result["parsed_json"] + ) + + def _convert_to_text(self, question: str, reasoning: str, answer: str, qa_id: str) -> ProcessingResult: + """转换为陈述性文本""" + prompt = PromptTemplates.get_text_conversion_prompt(question, reasoning, answer) + messages = [{"role": "user", "content": prompt}] + + api_result = self.api_client.call_api(messages) + + if api_result["status"] != "success": + return ProcessingResult( + status="api_error", + task_type=TaskType.TEXT_CONVERSION, + qa_id=qa_id, + input_data={"question": question, "reasoning": reasoning, "answer": answer}, + error_details=api_result["error"] + ) + + validation_result = self.validator.validate_json_response( + api_result["content"], ["knowledge_text"] + ) + + if not validation_result["is_valid_json"]: + return ProcessingResult( + status="validation_error", + task_type=TaskType.TEXT_CONVERSION, + qa_id=qa_id, + input_data={"question": question, "reasoning": reasoning, "answer": answer}, + response=api_result["content"], + error_details=f"{validation_result['error_type']} | repair_attempts: {validation_result.get('repair_attempts', [])}" + ) + + return ProcessingResult( + status="success", + task_type=TaskType.TEXT_CONVERSION, + qa_id=qa_id, + input_data={"question": question, "reasoning": reasoning, "answer": answer}, + response=api_result["content"], + parsed_result=validation_result["parsed_json"] + ) + + +class BatchProcessor: + """批量处理器""" + + def __init__(self, processor: QAToTextProcessor, output_dir): + self.processor = processor + self.output_dir = output_dir + if not os.path.exists(output_dir): + os.makedirs(output_dir) + + def process_qa_list(self, qa_list: List[Dict], max_workers: int = 20, + batch_size: int = 200, batch_delay: int = 2) -> Dict: + """批量处理QA列表""" + total_qas = len(qa_list) + print(f"开始批量处理 {total_qas} 个QA,批次大小: {batch_size}, 最大并发: {max_workers}") + + all_results = {} + batch_num = 1 + + # 分批处理 + for i in range(0, total_qas, batch_size): + batch_qas = qa_list[i:i + batch_size] + print(f"\n处理批次 {batch_num}: QA {i+1}-{min(i+batch_size, total_qas)} ({len(batch_qas)} 个)") + + batch_start_time = time.time() + batch_results = self._process_batch(batch_qas, max_workers, i) + batch_end_time = time.time() + + # 保存批次结果(只保存验证为true且转换成功的) + self._save_successful_results(batch_results, batch_num, batch_start_time) + + all_results.update(batch_results) + + print(f"批次 {batch_num} 完成,耗时: {batch_end_time - batch_start_time:.2f} 秒") + + batch_num += 1 + + # 批次间休息 + if i + batch_size < total_qas: + print(f"批次间休息 {batch_delay} 秒...") + time.sleep(batch_delay) + + print(f"\n所有批次处理完成!总计处理 {total_qas} 个QA") + return all_results + + def _process_batch(self, batch_qas: List[Dict], max_workers: int, start_index: int) -> Dict: + """处理单个批次""" + batch_results = {} + + with ThreadPoolExecutor(max_workers=max_workers) as executor: + # 提交任务 + future_to_qa = {} + for idx, qa_data in enumerate(batch_qas): + qa_id = f"qa_{start_index + idx:06d}" + future = executor.submit(self.processor.process_single_qa, qa_data, qa_id) + future_to_qa[future] = (qa_id, qa_data) + + # 收集结果 + completed = 0 + for future in as_completed(future_to_qa): + qa_id, qa_data = future_to_qa[future] + try: + results = future.result() + batch_results[qa_id] = { + "original_data": qa_data, + "processing_results": results + } + + # 详细状态显示 + status_info = self._get_processing_status(results) + status_symbol = status_info["symbol"] + + completed += 1 + if completed % 10 == 0 or completed == len(batch_qas): + print(f" 已完成: {completed}/{len(batch_qas)} {status_symbol}") + + except Exception as e: + batch_results[qa_id] = { + "original_data": qa_data, + "processing_results": [], + "exception": str(e) + } + + return batch_results + + def _get_processing_status(self, results: List[ProcessingResult]) -> Dict: + """获取处理状态信息""" + if not results: + return {"symbol": "✗", "status": "no_results"} + + # 检查各步骤状态 + cot_success = any(r.task_type == TaskType.COT_GENERATION and r.status == "success" for r in results) + verification_success = any(r.task_type == TaskType.ANSWER_VERIFICATION and r.status == "success" for r in results) + conversion_success = any(r.task_type == TaskType.TEXT_CONVERSION and r.status == "success" for r in results) + + # 检查答案是否一致 + answer_consistent = False + for r in results: + if r.task_type == TaskType.ANSWER_VERIFICATION and r.status == "success": + answer_consistent = r.parsed_result.get('is_consistent', False) + break + + if conversion_success: + return {"symbol": "✓", "status": "full_success"} + elif verification_success and not answer_consistent: + return {"symbol": "⚠", "status": "answer_inconsistent"} + elif verification_success: + return {"symbol": "⏸", "status": "stopped_after_verification"} + elif cot_success: + return {"symbol": "⏸", "status": "stopped_after_cot"} + else: + return {"symbol": "✗", "status": "failed"} + + def _save_successful_results(self, batch_results: Dict, batch_num: int, start_time: float): + """只保存验证为true且转换成功的结果,包含完整input/output""" + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + filename = f"qa_to_text_successful_batch_{batch_num:03d}_{timestamp}.pkl" + filepath = os.path.join(self.output_dir, filename) + + # 筛选成功的QA(验证为true且转换成功) + successful_qas = {} + total_qas = len(batch_results) + successful_count = 0 + verification_true_count = 0 + + for qa_id, qa_result in batch_results.items(): + results = qa_result.get("processing_results", []) + original_data = qa_result.get("original_data", {}) + + if len(results) >= 3: # 必须完成所有3步 + cot_result = results[0] if results[0].task_type == TaskType.COT_GENERATION else None + verification_result = results[1] if results[1].task_type == TaskType.ANSWER_VERIFICATION else None + conversion_result = results[2] if results[2].task_type == TaskType.TEXT_CONVERSION else None + + # 检查验证结果是否为true + if verification_result and verification_result.status == "success": + is_consistent = verification_result.parsed_result.get('is_consistent', False) + if is_consistent: + verification_true_count += 1 + + # 检查转换是否成功 + if conversion_result and conversion_result.status == "success": + successful_count += 1 + + # 构建完整的input/output记录 + complete_process = { + "qa_id": qa_id, + "original_input": original_data.get("input", ""), + "original_output": original_data.get("output", ""), + + # 步骤1:COT推理 + "cot_reasoning": cot_result.parsed_result.get("reasoning", "") if cot_result and cot_result.status == "success" else "", + "cot_answer": cot_result.parsed_result.get("answer", "") if cot_result and cot_result.status == "success" else "", + + # 步骤2:验证结果 + "verification_result": True, # 因为已经筛选过了 + + # 步骤3:最终知识文本 + "knowledge_text": conversion_result.parsed_result.get("knowledge_text", ""), + + # 处理时间统计 + "total_processing_time": sum(r.processing_time or 0 for r in results), + "step_processing_times": { + "cot_time": cot_result.processing_time or 0 if cot_result else 0, + "verification_time": verification_result.processing_time or 0, + "conversion_time": conversion_result.processing_time or 0 + } + } + + successful_qas[qa_id] = complete_process + + # 保存数据 + save_data = { + "metadata": { + "batch_num": batch_num, + "timestamp": timestamp, + "start_time": start_time, + "total_qas_in_batch": total_qas, + "verification_true_count": verification_true_count, + "successful_conversions": successful_count, + "task_type": "qa_to_text_successful_only" + }, + "successful_results": successful_qas + } + + with open(filepath, 'wb') as f: + pickle.dump(save_data, f) + + print(f" 成功结果已保存: {filename}") + print(f" 验证为true: {verification_true_count}/{total_qas}, 完整成功: {successful_count}/{total_qas}") + return filepath + + +# ==================== 调试和单例测试工具 ==================== + +def test_single_qa(qa_data: Dict, verbose: bool = True): + """测试单个QA的处理过程,用于调试""" + print("=" * 80) + print("单个QA处理测试") + print("=" * 80) + + # 初始化API客户端 + api_client = APIClient( + api_url="http://123.129.219.111:3000/v1/chat/completions", + api_key="sk-ZXk4KtKH99yelVZKPrpGB2t8OrhUOoVV0hhGi26zgjkN58Ye", + model_name="gpt-4o-mini" + ) + + processor = QAToTextProcessor(api_client) + + print("原始数据:") + print(f"输入: {qa_data['input'][:200]}...") + print(f"预期输出: {qa_data['output']}") + print() + + # 处理QA + results = processor.process_single_qa(qa_data, "test_qa") + + # 显示每步结果 + all_success = True + final_knowledge_text = None + cot_reasoning = None + cot_answer = None + verification_result = None + + for i, result in enumerate(results, 1): + print(f"步骤 {i}: {result.task_type.value}") + print(f"状态: {result.status}") + + if result.status == "success" and result.parsed_result: + if result.task_type == TaskType.COT_GENERATION: + cot_answer = result.parsed_result.get('answer', 'N/A') + cot_reasoning = result.parsed_result.get('reasoning', 'N/A') + print(f"生成的答案: {cot_answer}") + if verbose: + print(f"推理过程: {cot_reasoning[:300]}...") + + elif result.task_type == TaskType.ANSWER_VERIFICATION: + verification_result = result.parsed_result.get('is_consistent', False) + print(f"答案一致性: {verification_result}") + if not verification_result: + all_success = False + + elif result.task_type == TaskType.TEXT_CONVERSION: + final_knowledge_text = result.parsed_result.get('knowledge_text', 'N/A') + print(f"知识文本: {final_knowledge_text[:300]}...") + + elif result.status != "success": + print(f"错误详情: {result.error_details}") + if result.response: + print(f"原始API返回前300字符: {result.response[:300]}...") + + # 如果有repair_attempts信息,显示修复尝试过程 + if "repair_attempts:" in str(result.error_details): + print("JSON修复尝试过程:") + try: + attempts_str = str(result.error_details).split("repair_attempts: ")[1] + attempts = eval(attempts_str) if attempts_str.startswith('[') else [] + for i, attempt in enumerate(attempts, 1): + print(f" {i}. {attempt}") + except: + pass + + all_success = False + + print(f"处理耗时: {result.processing_time:.2f}秒" if result.processing_time else "处理耗时: N/A") + print("-" * 40) + + # 如果所有步骤都成功,显示并返回最终输出(要保存的数据格式) + if all_success and final_knowledge_text: + print("🎉 所有步骤成功完成!") + print("=" * 80) + print("最终要保存的数据:") + print("=" * 80) + + # 构建完整的数据结构(这就是最终要保存的格式) + final_output = { + "qa_id": "test_qa", + "original_input": qa_data['input'], + "original_output": qa_data['output'], + "cot_reasoning": cot_reasoning, + "cot_answer": cot_answer, + "verification_result": verification_result, + "knowledge_text": final_knowledge_text, + "total_processing_time": sum(r.processing_time or 0 for r in results), + "step_processing_times": { + "cot_time": results[0].processing_time or 0 if len(results) > 0 else 0, + "verification_time": results[1].processing_time or 0 if len(results) > 1 else 0, + "conversion_time": results[2].processing_time or 0 if len(results) > 2 else 0 + } + } + + # 美化输出 + print(json.dumps(final_output, ensure_ascii=False, indent=2)) + print("=" * 80) + + return { + "success": True, + "final_output": final_output, + "results": results + } + else: + print("❌ 处理过程中出现错误或答案不一致") + return { + "success": False, + "final_output": None, + "results": results + } + + +def debug_answer_comparison(qa_data: Dict): + """专门调试答案比较步骤""" + print("=" * 80) + print("答案比较调试") + print("=" * 80) + + # 初始化API客户端 + api_client = APIClient( + api_url="http://123.129.219.111:3000/v1/chat/completions", + api_key="sk-ZXk4KtKH99yelVZKPrpGB2t8OrhUOoVV0hhGi26zgjkN58Ye", + model_name="gpt-4o-mini" + ) + + processor = QAToTextProcessor(api_client) + + # 先生成COT + input_text = qa_data['input'] + question_part = input_text.split('\n选项:')[0] + options_part = input_text.split('\n选项:')[1] if '\n选项:' in input_text else "" + + print("第一步: COT推理生成") + cot_result = processor._generate_cot(question_part, options_part, "debug_qa") + + if cot_result.status == "success": + generated_answer = cot_result.parsed_result.get('answer', '') + print(f"LLM生成的答案: '{generated_answer}'") + print(f"题目标准答案: '{qa_data['output']}'") + print() + else: + print(f"COT生成失败: {cot_result.error_details}") + print("\n原始API返回内容:") + print("-" * 40) + print(cot_result.response) + print("-" * 40) + return + + print("第二步: 答案一致性验证") + verification_result = processor._verify_answer(qa_data, generated_answer, "debug_qa") + + if verification_result.status == "success": + is_consistent = verification_result.parsed_result.get('is_consistent', False) + + print(f"一致性判断: {is_consistent}") + + # 显示验证提示词 + print("\n验证提示词:") + print("-" * 40) + verification_prompt = PromptTemplates.get_verification_prompt(qa_data, generated_answer) + print(verification_prompt) + print("-" * 40) + + # 显示原始返回内容 + print("\n原始API返回:") + print("-" * 40) + print(verification_result.response) + print("-" * 40) + else: + print(f"验证失败: {verification_result.error_details}") + + +# ==================== 结果分析工具 ==================== + +class ResultAnalyzer: + """结果分析器""" + + @staticmethod + def load_batch_results(filepath: str) -> Dict: + """加载批次结果""" + with open(filepath, 'rb') as f: + return pickle.load(f) + + @staticmethod + def analyze_successful_results(results_dir: str = "med/qa"): + """分析成功结果文件""" + successful_files = [f for f in os.listdir(results_dir) + if f.startswith('qa_to_text_successful_batch_') and f.endswith('.pkl')] + successful_files.sort() + + if not successful_files: + print("未找到成功结果文件") + return + + total_qas_processed = 0 + total_verification_true = 0 + total_successful = 0 + all_successful_data = [] + + print("成功结果文件分析:") + print("=" * 100) + + for file in successful_files: + filepath = os.path.join(results_dir, file) + data = ResultAnalyzer.load_batch_results(filepath) + metadata = data['metadata'] + successful_results = data.get('successful_results', {}) + + total_qas_processed += metadata['total_qas_in_batch'] + total_verification_true += metadata['verification_true_count'] + total_successful += metadata['successful_conversions'] + + print(f"批次 {metadata['batch_num']:3d}: " + f"总QA {metadata['total_qas_in_batch']:3d}, " + f"验证true {metadata['verification_true_count']:3d}, " + f"完整成功 {metadata['successful_conversions']:3d}") + + # 收集成功的数据 + for qa_id, qa_data in successful_results.items(): + all_successful_data.append(qa_data) + + print("=" * 100) + print(f"总计: 处理QA {total_qas_processed}, 验证true {total_verification_true}, 完整成功 {total_successful}") + if total_qas_processed > 0: + print(f"验证true率: {total_verification_true/total_qas_processed*100:.1f}%") + print(f"完整成功率: {total_successful/total_qas_processed*100:.1f}%") + + return all_successful_data + + @staticmethod + def export_successful_knowledge_texts(output_file: str = "successful_knowledge_texts.json", + results_dir: str = "med/qa"): + """导出所有成功的知识文本""" + successful_data = ResultAnalyzer.analyze_successful_results(results_dir) + + if not successful_data: + print("没有找到成功的知识文本") + return [] + + # 保存到文件 + with open(output_file, 'w', encoding='utf-8') as f: + json.dump(successful_data, f, ensure_ascii=False, indent=2) + + print(f"已导出 {len(successful_data)} 个成功的知识文本到: {output_file}") + return successful_data + + +# ==================== 使用示例 ==================== + +def process_sampled_data(sampled_data: List[Dict], start_index: int = 0, + max_count: Optional[int] = None): + """处理sampled_data的便捷函数""" + # 确定处理范围 + if max_count is not None: + end_index = min(start_index + max_count, len(sampled_data)) + else: + end_index = len(sampled_data) + + data_to_process = sampled_data[start_index:end_index] + + print(f"准备处理sampled_data[{start_index}:{end_index}],共 {len(data_to_process)} 个QA") + + # 初始化API客户端 + api_client = APIClient( + api_url="http://123.129.219.111:3000/v1/chat/completions", + api_key="sk-ZXk4KtKH99yelVZKPrpGB2t8OrhUOoVV0hhGi26zgjkN58Ye", + model_name="gpt-4o" + ) + + # 初始化处理器 + processor = QAToTextProcessor(api_client) + batch_processor = BatchProcessor(processor, output_dir='med/qa') + + # 批量处理(并行20个问题,每200个保存一次) + results = batch_processor.process_qa_list( + qa_list=data_to_process, + max_workers=50, + batch_size=500, + batch_delay=0.1 + ) + + return results + + +def analyze_results(results_dir): + """分析成功结果的便捷函数""" + return ResultAnalyzer.analyze_successful_results(results_dir) + + +def export_successful_texts(output_file): + """导出成功转换的文本""" + return ResultAnalyzer.export_successful_knowledge_texts(output_file) + + +if __name__ == "__main__": + # 显示JSON修复功能状态 + print("=" * 80) + print("QA转文本处理系统") + print("=" * 80) + if HAS_JSONREPAIR: + print("✓ 高级JSON修复功能已启用 (jsonrepair)") + else: + print("⚠ 使用基础JSON修复功能 (建议安装: pip install jsonrepair)") + print() + + # 示例使用 + + # 测试单个QA的处理过程(调试用) + sample_qa = { + 'input': "An outbreak of diphtheria has occurred for the third time in a decade in a small village in South Africa. Diphtheria is endemic to the area with many healthy villagers colonized with different bacterial strains. Vaccine distribution in this area is difficult due to treacherous terrain. A team of doctors is sent to the region to conduct a health campaign. Toxigenic strains of C. diphtheria are isolated from symptomatic patients. Which of the following best explains the initial emergence of a pathogenic strain causing such outbreaks?\n\n选项:\nA: {'key': 'A', 'value': 'Presence of naked DNA in the environment'}\nB: {'key': 'B', 'value': 'Lysogenic conversion'}\nC: {'key': 'C', 'value': 'Suppression of lysogenic cycle'}\nD: {'key': 'D', 'value': 'Conjugation between the toxigenic and non-toxigenic strains of C. diphtheriae'}", + 'output': 'Lysogenic conversion' + } + + # 1. 测试单个QA处理 + #test_results = test_single_qa(sample_qa, verbose=True) + + # 2. 专门调试答案比较 + #debug_answer_comparison(sample_qa) + + # 3. 如果你有sampled_data,可以这样调用: + # results = process_sampled_data(sampled_data, start_index=0, max_count=100) + + # 4. 分析结果 + # analyze_results() + + # 5. 导出成功的文本 + # export_successful_texts() + + print("QA转文本处理系统已就绪。") + print("使用方法:") + print("1. test_single_qa(qa_data) - 测试单个QA") + print("2. debug_answer_comparison(qa_data) - 调试答案比较") + print("3. process_sampled_data(sampled_data) - 批量处理") + print("4. analyze_results() - 分析结果") + print("5. export_successful_texts() - 导出文本") \ No newline at end of file