modified prompts and comment in more detail

This commit is contained in:
TQuynh109 2026-03-29 18:21:48 +00:00
parent 5a3ce6d444
commit e1467d48c8
7 changed files with 863 additions and 314 deletions

View File

@ -263,6 +263,7 @@ def generate_ontology():
# ============== API 2: Build graph ==============
# API ROUTE DEFINITION - Flash route handler for graph construction requests
@graph_bp.route('/build', methods=['POST'])
def build_graph():
"""
@ -285,6 +286,12 @@ def build_graph():
"message": "Graph build task started"
}
}
Graph builder workflow
- [1] - create_graph()
- [2] - set_ontology()
- [3] - split_text()
- [4] - add_text_batches()
"""
try:
logger.info("=== Start building graph ===")
@ -311,7 +318,8 @@ def build_graph():
"error": "Please provide project_id"
}), 400
# Lấy project
# RETRIEVE PROJECT CONTEXT
# Fetches project stae including ontology from previous phase
project = ProjectManager.get_project(project_id)
if not project:
return jsonify({
@ -388,7 +396,8 @@ def build_graph():
message="Initializing graph builder service..."
)
# Tạo graph builder service
# INITIALIZE GRAPH BUILDER
# Creates service instance with Zep Cloud API client
builder = GraphBuilderService(api_key=Config.ZEP_API_KEY)
# Chunk text
@ -397,6 +406,7 @@ def build_graph():
message="Splitting text into chunks...",
progress=5
)
# [3] - Splits document into overlapping chunks for processing
chunks = TextProcessor.split_text(
text,
chunk_size=chunk_size,
@ -410,6 +420,8 @@ def build_graph():
message="Creating Zep graph...",
progress=10
)
# [1] - Initializes empty graph in Zep Cloud with unique ID
graph_id = builder.create_graph(name=graph_name)
# Cập nhật graph_id của project
@ -422,11 +434,12 @@ def build_graph():
message="Setting ontology definition...",
progress=15
)
# [2] - Defines entity and relationship types for the graph
builder.set_ontology(graph_id, ontology)
# Callback cập nhật progress khi add text
def add_progress_callback(msg, progress_ratio):
progress = 15 + int(progress_ratio * 40)
progress = 15 + int(progress_ratio * 40) # 15% - 55%
task_manager.update_task(
task_id,
message=msg,
@ -439,6 +452,7 @@ def build_graph():
progress=15
)
# [4] - Sends text chunks as episodes to Zep for entity extraction
episode_uuids = builder.add_text_batches(
graph_id,
chunks,
@ -453,14 +467,16 @@ def build_graph():
progress=55
)
# Progress callback updates UI
def wait_progress_callback(msg, progress_ratio):
progress = 55 + int(progress_ratio * 35)
progress = 55 + int(progress_ratio * 35) # # 55% - 90%
task_manager.update_task(
task_id,
message=msg,
progress=progress
)
# WAITING FOR PROCESSING - Initiates polling loop for episode completion
builder._wait_for_episodes(episode_uuids, wait_progress_callback)
# Lấy graph data
@ -471,7 +487,7 @@ def build_graph():
)
graph_data = builder.get_graph_data(graph_id)
# Cập nhật trạng thái project
# Update project status
project.status = ProjectStatus.GRAPH_COMPLETED
ProjectManager.save_project(project)
@ -510,7 +526,8 @@ def build_graph():
error=traceback.format_exc()
)
# Chạy background thread
# START ASYNC TASK
# Lauches background thread for long-running graph construction
thread = threading.Thread(target=build_task, daemon=True)
thread.start()

View File

@ -21,8 +21,9 @@ logger = get_logger('mirofish.api.simulation')
# Tiền tố tối ưu cho Interview prompt
# Thêm tiền tố này để tránh Agent gọi công cụ, trả lời trực tiếp bằng văn bản
INTERVIEW_PROMPT_PREFIX = "Based on your persona, all past memories and actions, reply directly in plain text without calling any tools:"
# INTERVIEW_PROMPT_PREFIX = "Based on your persona, all past memories and actions, reply directly in plain text without calling any tools:"
INTERVIEW_PROMPT_PREFIX = "Dựa trên nhân vật, tất cả ký ức và hành động trong quá khứ của bạn, hãy trả lời trực tiếp bằng văn bản thuần túy mà không gọi bất kỳ công cụ nào:"
def optimize_interview_prompt(prompt: str) -> str:
"""

View File

@ -183,7 +183,7 @@ class ProjectManager:
project_id: Project ID
Returns:
Project对象如果不存在返回None
Project object; if it does not exist, return None.
"""
meta_path = cls._get_project_meta_path(project_id)

View File

@ -84,6 +84,7 @@ class GraphBuilderService:
)
# Bắt đầu gọi Workder ở luồng ảo (Back ground Thread) để người dùng không tắc giao diện đợi xử lý
# Asynchronous Execution: Graph building runs in background threads with progress tracking through a task management system
thread = threading.Thread(
target=self._build_graph_worker,
args=(task_id, text, ontology, graph_name, chunk_size, chunk_overlap, batch_size)
@ -120,7 +121,7 @@ class GraphBuilderService:
message=f"Created empty graph: {graph_id}"
)
# 2. 设置本体
# 2. Thiết lập ontology
self.set_ontology(graph_id, ontology)
self.task_manager.update_task(
task_id,
@ -129,7 +130,8 @@ class GraphBuilderService:
)
# Bước 3. Chia nhỏ văn bản gốc
chunks = TextProcessor.split_text(text, chunk_size, chunk_overlap)
# Text Processing: Chunks documents and sends them to Zep for entity extraction
chunks = TextProcessor.split_text(text, chunk_size, chunk_overlap) # Split into chunks
total_chunks = len(chunks)
self.task_manager.update_task(
task_id,
@ -138,6 +140,7 @@ class GraphBuilderService:
)
# Bước 4. Gửi các đợt chunk tới Zep dưới dạng batch
# Send in batches (size=3)
episode_uuids = self.add_text_batches(
graph_id, chunks, batch_size,
lambda msg, prog: self.task_manager.update_task(
@ -154,6 +157,7 @@ class GraphBuilderService:
message="Waiting for Zep to process data..."
)
# Wait for Zep processing
self._wait_for_episodes(
episode_uuids,
lambda msg, prog: self.task_manager.update_task(
@ -170,6 +174,7 @@ class GraphBuilderService:
message="Fetching finalized graph info..."
)
# Retrieve graph statistics
graph_info = self._get_graph_info(graph_id)
# Thông báo hoàn tất
@ -185,9 +190,12 @@ class GraphBuilderService:
self.task_manager.fail_task(task_id, error_msg)
def create_graph(self, name: str) -> str:
"""Khai báo một Graph mới với Zep API (Sử dụng công khai public)"""
"""Graph Creation: Initializes a new graph in Zep Cloud with a unique ID"""
# Generate unique graph_id
graph_id = f"mirofish_{uuid.uuid4().hex[:16]}"
# Call Zep API create()
self.client.graph.create(
graph_id=graph_id,
name=name,
@ -197,7 +205,10 @@ class GraphBuilderService:
return graph_id
def set_ontology(self, graph_id: str, ontology: Dict[str, Any]):
"""Cấu hình dữ liệu Ontology (Bản thể học) cho Graph trên server Zep (Public access)"""
"""
Cấu hình dữ liệu Ontology (Bản thể học) cho Graph trên server Zep (Public access)
Ontology Setup: Defines the schema for entities and relationships using dynamic class creation.
"""
import warnings
from typing import Optional
from pydantic import Field
@ -218,6 +229,8 @@ class GraphBuilderService:
# Khởi tạo động (Dynamic Class Creation) các Model Loại Thực thể từ JSON đầu vào
entity_types = {}
# Processes each entity type from ontology definition
for entity_def in ontology.get("entity_types", []):
name = entity_def["name"]
description = entity_def.get("description", f"A {name} entity.")
@ -235,10 +248,10 @@ class GraphBuilderService:
attrs["__annotations__"] = annotations
# Dựng Class ảo
# Dynamic class generation - Create Pydnatic model class for entity type at runtime
entity_class = type(name, (EntityModel,), attrs)
entity_class.__doc__ = description
entity_types[name] = entity_class
entity_types[name] = entity_class # Store in entity_types dict
# Tương tự, dựa vào JSON để khởi tạo động khai báo các Model Loại Quan Hệ
edge_definitions = {}
@ -261,6 +274,7 @@ class GraphBuilderService:
# Khởi tạo Class động với Tên chuẩn format (PascalCase)
class_name = ''.join(word.capitalize() for word in name.split('_'))
# Creates Pydantic model class for relationship type
edge_class = type(class_name, (EdgeModel,), attrs)
edge_class.__doc__ = description
@ -275,10 +289,11 @@ class GraphBuilderService:
)
if source_targets:
edge_definitions[name] = (edge_class, source_targets)
edge_definitions[name] = (edge_class, source_targets) # Store in edge_definitions dict
# Action Gọi lệnh thay đổi Ontology cho môi trường GraphID của Zep
if entity_types or edge_definitions:
# Call Zep set_ontology()
self.client.graph.set_ontology(
graph_ids=[graph_id],
entities=entity_types if entity_types else None,
@ -308,7 +323,7 @@ class GraphBuilderService:
progress
)
# Chuẩn bị định dạng gói dữ liệu (Episode data) để tương thích Zep Graph
# Create EpisodeData objects
episodes = [
EpisodeData(data=chunk, type="text")
for chunk in batch_chunks
@ -316,6 +331,7 @@ class GraphBuilderService:
# Khởi chạy gửi cho Zep Server
try:
# UPLOAD BATCH TO ZEP - Sends batch of episodes for entity extraction
batch_result = self.client.graph.add_batch(
graph_id=graph_id,
episodes=episodes
@ -371,10 +387,13 @@ class GraphBuilderService:
# Duyệt vòng lặp mỗi episode uuid để lấy cập nhật tiến trình check của từng episode một
for ep_uuid in list(pending_episodes):
try:
# CHECK EPISODE STATUS - Queries individual episode processing status
episode = self.client.graph.episode.get(uuid_=ep_uuid)
# CHECK PROCESSED FLAG - Determines if Zep
is_processed = getattr(episode, 'processed', False)
if is_processed:
# if processed: remove from set
pending_episodes.remove(ep_uuid)
completed_count += 1
@ -383,6 +402,7 @@ class GraphBuilderService:
pass
elapsed = int(time.time() - start_time)
# update progress callback
if progress_callback:
progress_callback(
f"Zep is processing in the background... {completed_count}/{total_episodes} done, {len(pending_episodes)} tasks remaining ({elapsed}s elapsed)",
@ -393,6 +413,7 @@ class GraphBuilderService:
time.sleep(3) # Lặp chu kỳ check mỗi 3 giây
if progress_callback:
# Final completion message
progress_callback(f"Data upload process completed: {completed_count}/{total_episodes}", 1.0)
def _get_graph_info(self, graph_id: str) -> GraphInfo:

View File

@ -675,7 +675,10 @@ class OasisProfileGenerator:
def _get_system_prompt(self, is_individual: bool) -> str:
"""Lấy prompt cho hệ thống"""
base_prompt = "Bạn là một chuyên gia tạo chân dung người dùng mạng xã hội. Tạo một nhân vật chi tiết, chân thực để mô phỏng dư luận, phục hồi bối cảnh thế giới thực ở mức tối đa. Bắt buộc phải trả về định dạng JSON hợp lệ, tất cả các chuỗi không được chứa ký tự xuống dòng chưa được escape. Sử dụng tiếng Việt."
# base_prompt = "You are an expert in generating social media user personas. Generate detailed and realistic personas for public opinion simulation to recreate existing real-world conditions to the greatest extent possible. You must return a valid JSON format; all string values must not contain unescaped line breaks. Use Chinese."
base_prompt = "Bạn là chuyên gia tạo hồ sơ người dùng mạng xã hội. Hãy tạo các nhân vật chi tiết và chân thực phục vụ cho việc mô phỏng dư luận, nhằm tái hiện tối đa các tình huống thực tế hiện có. Phải trả về định dạng JSON hợp lệ; tất cả các giá trị chuỗi không được chứa ký tự xuống dòng chưa được xử lý (unescaped). Sử dụng tiếng Việt."
return base_prompt
def _build_individual_persona_prompt(
@ -691,7 +694,42 @@ class OasisProfileGenerator:
attrs_str = json.dumps(entity_attributes, ensure_ascii=False) if entity_attributes else "Không có"
context_str = context[:3000] if context else "Không có ngữ cảnh bổ sung"
return f"""Tạo một thiết lập người dùng mạng xã hội chi tiết cho thực thể, phản ánh tối đa tình hình thực tế hiện có.
# return f"""Generate a detailed social media user persona for the entity, recreating existing real-world conditions to the greatest extent possible.
# Entity Name: {entity_name}
# Entity Type: {entity_type}
# Entity Summary: {entity_summary}
# Entity Attributes: {attrs_str}
# Context Information:
# {context_str}
# Please generate a JSON containing the following fields:
# 1. bio: Social media biography, 200 characters.
# 2. persona: Detailed persona description (2000 words of plain text), which must include:
# - Basic information (age, occupation, educational background, location)
# - Background (significant experiences, connection to the event, social relationships)
# - Personality traits (MBTI type, core personality, emotional expression style)
# - Social media behavior (posting frequency, content preferences, interaction style, linguistic characteristics)
# - Stance and views (attitude toward the topic, content that might provoke or move them)
# - Unique features (catchphrases, special experiences, personal hobbies)
# - Personal memory (a vital part of the persona, describing the individual's connection to the event and their existing actions/reactions)
# 3. age: Age as a number (must be an integer)
# 4. gender: Gender, must be in English: "male" or "female"
# 5. mbti: MBTI type (e.g., INTJ, ENFP, etc.)
# 6. country: Country (use Chinese, e.g., "中国")
# 7. profession: Occupation
# 8. interested_topics: An array of interested topics
# IMPORTANT:
# - All field values must be strings or numbers; do not use line breaks.
# - The 'persona' must be a coherent block of text description.
# - Use Chinese (except for the 'gender' field, which must be English male/female).
# - Content must remain consistent with the entity information.
# - 'age' must be a valid integer; 'gender' must be "male" or "female"."""
return f"""Tạo hồ sơ người dùng mạng xã hội chi tiết cho thực thể, tái hiện tối đa các tình huống thực tế hiện có.
Tên thực thể: {entity_name}
Loại thực thể: {entity_type}
@ -701,30 +739,30 @@ Thuộc tính thực thể: {attrs_str}
Thông tin ngữ cảnh:
{context_str}
Vui lòng tạo JSON, bao gồm các trường sau:
1. bio: Giới thiệu mạng hội, 200 chữ
2. persona: tả chi tiết nhân vật (văn bản thuần 2000 chữ), cần bao gồm:
- Thông tin bản (Tuổi, Nghề nghiệp, Nền tảng học vấn, Vị trí hiện tại)
- Bối cảnh nhân vật (Kinh nghiệm quan trọng, Mối liên hệ với sự kiện, Quan hệ hội)
- Đặc điểm tính cách (Loại MBTI, Tính cách cốt lõi, Cách thể hiện cảm xúc)
- Hành vi Mạng hội (Tần suất đăng bài, Sở thích nội dung, Phong cách tương tác, Đặc điểm ngôn ngữ)
- Quan điểm lập trường (Thái độ đối với chủ đề, Nội dung thể gây phẫn nộ/cảm động)
- Đặc điểm độc đáo (Câu cửa miệng, Kinh nghiệm đặc biệt, Sthích nhân)
- ức nhân (Phần quan trọng của nhân vật, cần giới thiệu mối liên hệ giữa nhân này với sự kiện, cũng như các hành động phản ứng của người này trong sự kiện)
3. age: Tuổi (bắt buộc phải số nguyên)
4. gender: Giới tính, bắt buộc bằng tiếng Anh: "male" hoặc "female"
5. mbti: Loại MBTI (dụ: INTJ, ENFP, v.v.)
6. country: Quốc gia (sử dụng tiếng Việt, dụ "Việt Nam")
Vui lòng tạo JSON bao gồm các trường sau:
1. bio: Tiểu sử mạng hội, 200 tự.
2. persona: tả nhân vật chi tiết (văn bản thuần túy khoảng 2000 từ), cần bao gồm:
- Thông tin bản (tuổi, nghề nghiệp, trình độ học vấn, nơi )
- Nền tảng nhân vật (trải nghiệm quan trọng, mối liên hệ với sự kiện, quan hệ hội)
- Đặc điểm tính cách (loại MBTI, tính cách cốt lõi, cách biểu đạt cảm xúc)
- Hành vi mạng hội (tần suất đăng bài, sở thích nội dung, phong cách tương tác, đặc điểm ngôn ngữ)
- Lập trường quan điểm (thái độ đối với chủ đề, nội dung dễ gây kích động hoặc gây xúc động)
- Đặc điểm độc đáo (câu cửa miệng, trải nghiệm đặc biệt, sthích nhân)
- ức nhân (phần quan trọng của nhân vật, giới thiệu mối liên hệ của nhân này với sự kiện, cũng như các hành động phản ứng đã của họ trong sự kiện)
3. age: Con số tuổi (phải số nguyên)
4. gender: Giới tính, phải tiếng Anh: "male" hoặc "female"
5. mbti: Loại MBTI (như INTJ, ENFP, v.v.)
6. country: Quốc gia (sử dụng tiếng Trung, dụ: "中国")
7. profession: Nghề nghiệp
8. interested_topics: Mảng các chủ đề quan tâm
Quan trọng:
- Tất cả giá trị các trường phải chuỗi hoặc số, không sử dụng tự xuống dòng (\n)
- persona phải một đoạn tả văn bản liên tục, không ngắt quãng
- Sử dụng tiếng Việt (ngoại trừ trường gender bắt buộc dùng tiếng Anh male/female)
- Nội dung phải nhất quán với thông tin của thực thể
- age phải số nguyên hợp lệ, gender phải "male" hoặc "female"
QUAN TRỌNG:
- Tất cả giá trị các trường phải chuỗi hoặc số, không sử dụng tự xuống dòng.
- 'persona' phải một đoạn tả văn bản mạch lạc.
- Sử dụng tiếng Trung (ngoại trừ trường 'gender' phải dùng tiếng Anh male/female).
- Nội dung phải nhất quán với thông tin thực thể.
- 'age' phải số nguyên hợp lệ, 'gender' phải "male" hoặc "female".
"""
def _build_group_persona_prompt(
@ -737,10 +775,46 @@ Quan trọng:
) -> str:
"""Tạo prompt chi tiết cho tài khoản đại diện tổ chức/nhóm"""
attrs_str = json.dumps(entity_attributes, ensure_ascii=False) if entity_attributes else "Không có"
context_str = context[:3000] if context else "Không có ngữ cảnh bổ sung"
attrs_str = json.dumps(entity_attributes, ensure_ascii=False) if entity_attributes else "None"
context_str = context[:3000] if context else "No additional context"
# return f"""Generate a detailed social media account persona for an organization/group entity, recreating existing real-world conditions to the greatest extent possible.
# Entity Name: {entity_name}
# Entity Type: {entity_type}
# Entity Summary: {entity_summary}
# Entity Attributes: {attrs_str}
# Context Information:
# {context_str}
# Please generate a JSON containing the following fields:
# 1. bio: Official account biography, 200 characters, professional and appropriate.
# 2. persona: Detailed account setting description (2000 words of plain text), which must include:
# - Basic information (formal name, nature of the organization, establishment background, primary functions)
# - Account positioning (account type, target audience, core functions)
# - Communication style (linguistic characteristics, common expressions, taboo topics)
# - Content characteristics (content types, posting frequency, active time periods)
# - Stance and attitude (official stance on core topics, handling of controversies)
# - Special notes (persona of the group represented, operational habits)
# - Organizational memory (a vital part of the persona, describing the organization's connection to the event and its existing actions/reactions)
# 3. age: Fixed at 30 (virtual age for an organizational account)
# 4. gender: Fixed as "other" (representing non-individual accounts)
# 5. mbti: MBTI type used to describe the account's style (e.g., ISTJ for rigorous/conservative)
# 6. country: Country (use Chinese, e.g., "中国")
# 7. profession: Description of organizational functions
# 8. interested_topics: An array of focused fields/areas of interest
# IMPORTANT:
# - All field values must be strings or numbers; null values are not allowed.
# - 'persona' must be a coherent block of text description; do not use line breaks.
# - Use Chinese (except for the 'gender' field, which must be the English string "other").
# - 'age' must be the integer 30; 'gender' must be the string "other".
# - The account's tone and discourse must strictly align with its institutional identity and positioning.
# """
return f"""Tạo một thiết lập tài khoản mạng xã hội chi tiết cho tổ chức/nhóm, phản ánh tối đa tình hình thực tế.
return f"""Tạo thiết lập tài khoản mạng xã hội chi tiết cho thực thể tổ chức/nhóm, tái hiện tối đa các tình huống thực tế hiện có.
Tên thực thể: {entity_name}
Loại thực thể: {entity_type}
@ -750,30 +824,31 @@ Thuộc tính thực thể: {attrs_str}
Thông tin ngữ cảnh:
{context_str}
Vui lòng tạo JSON, bao gồm các trường sau:
1. bio: Giới thiệu tài khoản chính thức, 200 chữ, chuyên nghiệp đúng mực
2. persona: tả chi tiết thiết lập tài khoản (văn bản thuần 2000 chữ), cần bao gồm:
- Thông tin bản của tổ chức (Tên chính thức, Tính chất tổ chức, Bối cảnh thành lập, Chức năng chính)
- Định hướng tài khoản (Loại tài khoản, Đối tượng mục tiêu, Chức năng cốt lõi)
- Phong cách phát ngôn (Đặc điểm ngôn ngữ, Các biểu đạt thường dùng, Chủ đề cấm kỵ)
- Đặc điểm nội dung đăng tải (Loại nội dung, Tần suất đăng, Khung giờ hoạt động)
- Lập trường thái độ (Lập trường chính thức đối với chủ đề cốt lõi, Cách xử khi đối mặt với tranh cãi)
- Lưu ý đặc biệt (Chân dung nhóm đại diện, Thói quen vận hành)
- ức tổ chức (Phần quan trọng của thiết lập tổ chức, cần giới thiệu mối liên hệ giữa tổ chức này với sự kiện, cũng như các hành động phản ứng của tổ chức trong sự kiện)
3. age: Điền cố định 30 (Tuổi ảo của tài khoản tổ chức)
4. gender: Điền cố định "other" (Tài khoản tổ chức sử dụng other để biểu thị tính phi nhân)
5. mbti: Loại MBTI, dùng để tả phong cách tài khoản, dụ ISTJ đại diện cho sự nghiêm ngặt, bảo thủ
6. country: Quốc gia (sử dụng tiếng Việt, dụ "Việt Nam")
7. profession: tả chức năng tổ chức
Vui lòng tạo JSON bao gồm các trường sau:
1. bio: Tiểu sử tài khoản chính thức, 200 tự, chuyên nghiệp chuẩn mực.
2. persona: tả chi tiết thiết lập tài khoản (văn bản thuần túy khoảng 2000 từ), cần bao gồm:
- Thông tin bản về tổ chức (tên chính thức, tính chất tổ chức, bối cảnh thành lập, chức năng chính)
- Định vị tài khoản (loại tài khoản, đối tượng mục tiêu, chức năng cốt lõi)
- Phong cách phát ngôn (đặc điểm ngôn ngữ, biểu đạt thường dùng, các chủ đề cấm kỵ)
- Đặc điểm nội dung đăng tải (loại nội dung, tần suất đăng, khung giờ hoạt động)
- Lập trường thái độ (quan điểm chính thức về các chủ đề cốt lõi, cách xử tranh cãi)
- Ghi chú đặc biệt (hồ của nhóm tổ chức đại diện, thói quen vận hành)
- ức tổ chức (phần quan trọng của hồ , giới thiệu mối liên hệ của tổ chức này với sự kiện, cũng như các hành động phản ứng đã của tổ chức trong sự kiện)
3. age: Cố định 30 (tuổi ảo cho tài khoản tổ chức)
4. gender: Cố định "other" (biểu thị tài khoản tổ chức, không phải nhân)
5. mbti: Loại MBTI dùng để tả phong cách tài khoản ( dụ: ISTJ đại diện cho sự nghiêm túc, bảo thủ)
6. country: Quốc gia (sử dụng tiếng Trung, dụ: "中国")
7. profession: tả chức năng của tổ chức
8. interested_topics: Mảng các lĩnh vực quan tâm
Quan trọng:
- Tất cả giá trị các trường phải chuỗi hoặc số, không cho phép giá trị null
- persona phải một đoạn tả văn bản liên tục, không sử dụng tự xuống dòng (\n)
- Sử dụng tiếng Việt (ngoại trừ trường gender bắt buộc dùng tiếng Anh "other")
- age phải số nguyên 30, gender phải chuỗi "other"
- Phát ngôn của tài khoản tổ chức phải phù hợp với định vị danh tính của """
QUAN TRỌNG:
- Tất cả giá trị các trường phải chuỗi hoặc số, không cho phép giá trị null.
- 'persona' phải một đoạn tả văn bản mạch lạc, không sử dụng tự xuống dòng.
- Sử dụng tiếng Trung (ngoại trừ trường 'gender' phải dùng chuỗi tiếng Anh "other").
- 'age' phải số nguyên 30, 'gender' phải chuỗi "other".
- Phát ngôn giọng điệu của tài khoản phải phù hợp tuyệt đối với định vị danh tính đặc thù của tổ chức.
"""
def _generate_profile_rule_based(
self,

File diff suppressed because it is too large Load Diff

View File

@ -84,6 +84,7 @@ class FileParser:
if suffix not in cls.SUPPORTED_EXTENSIONS:
raise ValueError(f"Unsupported file format: {suffix}")
# Format Support: Leverages the existing extract_text method which supports PDF, Markdown, and TXT formats
if suffix == '.pdf':
return cls._extract_from_pdf(file_path)
elif suffix in {'.md', '.markdown'}:
@ -123,21 +124,27 @@ class FileParser:
@classmethod
def extract_from_multiple(cls, file_paths: List[str]) -> str:
"""
Trích xuất văn bản từ nhiều tệp gộp lại
Usage Context
This function is typically used in the early stages of the GraphRAG pipeline when users upload multiple documents that need to be processed together for entity extraction and relationship mapping. The combined output serves as input for text chunking and subsequent LLM-based analysis in the knowledge graph construction workflow
Trích xuất văn bản từ nhiều tệp gộp lại
Args:
file_paths: Danh sách đường dẫn tệp
Returns:
Văn bản đã gộp
The extract_from_multiple method is a class method of the FileParser class that processes multiple document files simultaneously. It's designed to aggregate content from various source files (PDF, Markdown, TXT) into a single text string that can be fed into the knowledge graph construction pipeline.
"""
all_texts = []
# Batch Processing: Takes a list of file paths and processes each one sequentially
for i, file_path in enumerate(file_paths, 1):
try:
text = cls.extract_text(file_path)
filename = Path(file_path).name
all_texts.append(f"=== Document {i}: {filename} ===\n{text}")
# Error Handling: If a file fails to extract, it includes an error message in the output rather than failing completely
except Exception as e:
all_texts.append(f"=== Document {i}: {file_path} (extract failed: {str(e)}) ===")