feat: 添加Redis支持和Celery任务处理
- 新增Redis服务模块用于会话状态存储和缓存 - 集成Celery用于后台任务处理 - 更新Docker Compose配置以支持开发环境 - 优化API以支持异步调用和Redis会话存储 - 更新文档以反映新的开发环境配置和使用方法
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
"""
|
||||
回忆录整理 Agent:基于传记结构,将口语改写为书面语,归类到章节
|
||||
支持异步调用
|
||||
"""
|
||||
import json
|
||||
import logging
|
||||
from typing import List, Dict, Optional
|
||||
|
||||
from services.llm_service import llm_service
|
||||
@@ -14,17 +16,19 @@ from .prompts import (
|
||||
CHAPTER_ORDER
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MemoryAgent:
|
||||
"""回忆录整理 Agent"""
|
||||
"""回忆录整理 Agent(支持异步)"""
|
||||
|
||||
def __init__(self):
|
||||
# 使用 LLM 服务获取 LLM 实例
|
||||
self.llm = llm_service.get_llm()
|
||||
|
||||
def classify_chapter(self, segments_text: str) -> str:
|
||||
async def classify_chapter(self, segments_text: str) -> str:
|
||||
"""
|
||||
分类章节
|
||||
异步分类章节
|
||||
|
||||
Args:
|
||||
segments_text: 对话段落文本
|
||||
@@ -36,28 +40,34 @@ class MemoryAgent:
|
||||
# 如果没有配置 LLM,返回默认类别
|
||||
return "childhood"
|
||||
|
||||
prompt = get_chapter_classification_prompt(segments_text)
|
||||
|
||||
response = self.llm.invoke(prompt)
|
||||
|
||||
# 提取类别
|
||||
category = response.content.strip().lower()
|
||||
|
||||
# 验证类别是否有效
|
||||
if category in CHAPTER_CATEGORIES:
|
||||
return category
|
||||
try:
|
||||
prompt = get_chapter_classification_prompt(segments_text)
|
||||
|
||||
# 异步调用 LLM
|
||||
response = await self.llm.ainvoke(prompt)
|
||||
|
||||
# 提取类别
|
||||
content = response.content if hasattr(response, 'content') else str(response)
|
||||
category = content.strip().lower()
|
||||
|
||||
# 验证类别是否有效
|
||||
if category in CHAPTER_CATEGORIES:
|
||||
return category
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"分类章节失败: {e}")
|
||||
|
||||
# 默认返回 childhood
|
||||
return "childhood"
|
||||
|
||||
def rewrite_to_literary(
|
||||
async def rewrite_to_literary(
|
||||
self,
|
||||
segments_text: str,
|
||||
chapter_category: str,
|
||||
existing_content: Optional[str] = None
|
||||
) -> Dict:
|
||||
"""
|
||||
将口语改写为书面语
|
||||
异步将口语改写为书面语
|
||||
|
||||
Args:
|
||||
segments_text: 对话段落文本
|
||||
@@ -76,14 +86,16 @@ class MemoryAgent:
|
||||
"image_suggestions": []
|
||||
}
|
||||
|
||||
prompt = get_text_rewrite_prompt(segments_text, chapter_category, existing_content or "")
|
||||
|
||||
response = self.llm.invoke(prompt)
|
||||
|
||||
# 尝试解析 JSON
|
||||
try:
|
||||
# 提取 JSON 部分
|
||||
content = response.content.strip()
|
||||
prompt = get_text_rewrite_prompt(segments_text, chapter_category, existing_content or "")
|
||||
|
||||
# 异步调用 LLM
|
||||
response = await self.llm.ainvoke(prompt)
|
||||
|
||||
# 尝试解析 JSON
|
||||
content = response.content if hasattr(response, 'content') else str(response)
|
||||
content = content.strip()
|
||||
|
||||
# 移除可能的 markdown 代码块标记
|
||||
if content.startswith("```json"):
|
||||
content = content[7:]
|
||||
@@ -95,22 +107,31 @@ class MemoryAgent:
|
||||
|
||||
result = json.loads(content)
|
||||
return result
|
||||
|
||||
except json.JSONDecodeError:
|
||||
# 如果解析失败,返回基本结构
|
||||
return {
|
||||
"title": CHAPTER_CATEGORIES.get(chapter_category, "章节"),
|
||||
"content": response.content,
|
||||
"content": response.content if hasattr(response, 'content') else str(response),
|
||||
"summary": "",
|
||||
"image_suggestions": []
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"改写文本失败: {e}")
|
||||
return {
|
||||
"title": CHAPTER_CATEGORIES.get(chapter_category, "章节"),
|
||||
"content": segments_text,
|
||||
"summary": "",
|
||||
"image_suggestions": []
|
||||
}
|
||||
|
||||
def process_segments(
|
||||
async def process_segments(
|
||||
self,
|
||||
segments: List[Dict],
|
||||
existing_chapters: Optional[Dict[str, Dict]] = None
|
||||
) -> Dict[str, Dict]:
|
||||
"""
|
||||
处理对话段落,生成或更新章节
|
||||
异步处理对话段落,生成或更新章节
|
||||
|
||||
Args:
|
||||
segments: 对话段落列表,每个包含 transcript_text
|
||||
@@ -130,8 +151,8 @@ class MemoryAgent:
|
||||
if not text:
|
||||
continue
|
||||
|
||||
# 分类
|
||||
category = self.classify_chapter(text)
|
||||
# 异步分类
|
||||
category = await self.classify_chapter(text)
|
||||
|
||||
if category not in segments_by_category:
|
||||
segments_by_category[category] = []
|
||||
@@ -145,8 +166,8 @@ class MemoryAgent:
|
||||
combined_text = "\n\n".join(texts)
|
||||
existing_content = existing_chapters.get(category, {}).get("content", "")
|
||||
|
||||
# 改写为书面语
|
||||
result = self.rewrite_to_literary(combined_text, category, existing_content)
|
||||
# 异步改写为书面语
|
||||
result = await self.rewrite_to_literary(combined_text, category, existing_content)
|
||||
|
||||
# 更新章节
|
||||
updated_chapters[category] = {
|
||||
|
||||
Reference in New Issue
Block a user