AI的框架
This commit is contained in:
25
app/ai/services/memory_service.py
Normal file
25
app/ai/services/memory_service.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# services/memory_service.py
|
||||
from langchain_google_genai import GoogleGenerativeAIEmbeddings
|
||||
|
||||
# 假设你使用的是 pgvector
|
||||
async def search_memories(query: str, db_connection):
|
||||
"""
|
||||
1. 将 query 转化为 Embedding
|
||||
2. 在数据库中执行向量相似度搜索
|
||||
3. 返回最相关的 Top-K 条记忆
|
||||
"""
|
||||
# 模拟实现
|
||||
embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
|
||||
query_vector = await embeddings.aembed_query(query)
|
||||
|
||||
# 这里执行 SQL: SELECT content FROM memories ORDER BY embedding <=> query_vector LIMIT 3
|
||||
results = "用户此前提到过他在做 Gemini 相关的 Hackathon,倾向于使用 Python。"
|
||||
return results
|
||||
|
||||
async def save_to_memory(content: str, db_connection):
|
||||
"""
|
||||
这个函数由你的 '保存' 按钮触发。
|
||||
"""
|
||||
# 1. 提取 content 中的关键信息(可选,可以用 LLM 提取)
|
||||
# 2. 生成 Embedding 并存入数据库
|
||||
pass
|
||||
65
app/ai/services/summary_service.py
Normal file
65
app/ai/services/summary_service.py
Normal file
@@ -0,0 +1,65 @@
|
||||
# services/summary_service.py
|
||||
from langchain_google_genai import ChatGoogleGenerativeAI
|
||||
from langchain_core.messages import HumanMessage, SystemMessage
|
||||
|
||||
async def get_rolling_summary(model: ChatGoogleGenerativeAI, existing_summary: str, messages: list):
|
||||
"""
|
||||
将旧的总结与新的对话内容合并生成新的总结
|
||||
"""
|
||||
if not messages:
|
||||
return existing_summary
|
||||
|
||||
msg_content = "\n".join([f"{m.type}: {m.content}" for m in messages])
|
||||
|
||||
prompt = f"""
|
||||
你是一个记忆专家。请根据提供的“现有总结”和“新增对话”,生成一个更全面、精炼的新总结。
|
||||
请保留关键事实(如技术偏好、重要决定、用户背景),删除无意义的寒暄。
|
||||
|
||||
[现有总结]: {existing_summary if existing_summary else "暂无"}
|
||||
[新增对话]: {msg_content}
|
||||
|
||||
请直接输出新的总结文本,保持中文书写。
|
||||
"""
|
||||
|
||||
response = await model.ainvoke([HumanMessage(content=prompt)])
|
||||
return response.content
|
||||
|
||||
# services/memory_service.py
|
||||
|
||||
async def extract_and_save_fact(thread_id: str, messages: list, db_connection):
|
||||
"""
|
||||
由前端按钮触发:从当前对话上下文提取事实并存入向量库
|
||||
"""
|
||||
# 1. 过滤掉无意义的消息,只取最近几条作为提取素材
|
||||
context_text = "\n".join([f"{m.type}: {m.content}" for m in messages[-10:]])
|
||||
|
||||
# 2. 调用小模型 (Flash) 进行原子化事实提取
|
||||
extraction_prompt = f"""
|
||||
从以下对话中提取用户提到的、具有长期保存价值的“个人事实”或“技术偏好”。
|
||||
要求:
|
||||
- 每一条事实必须是独立的、完整的句子。
|
||||
- 不要包含寒暄或临时性的讨论。
|
||||
- 如果没有值得记录的事实,请返回 "NONE"。
|
||||
|
||||
对话内容:
|
||||
{context_text}
|
||||
|
||||
输出格式示例:
|
||||
- 用户正在使用 Python 3.12 进行开发。
|
||||
- 用户计划参加 2026 年的 Gemini Hackathon。
|
||||
"""
|
||||
|
||||
# 这里假设你已经初始化了 model_flash
|
||||
response = await model_flash.ainvoke(extraction_prompt)
|
||||
facts_text = response.content.strip()
|
||||
|
||||
if facts_text == "NONE":
|
||||
return "没有发现值得记录的新事实。"
|
||||
|
||||
# 3. 将提取到的事实转化为向量并存入 pgvector
|
||||
# facts = facts_text.split('\n')
|
||||
# for fact in facts:
|
||||
# embedding = await get_embedding(fact)
|
||||
# await db_connection.execute("INSERT INTO memories ...", embedding, fact, thread_id)
|
||||
|
||||
return f"已成功记录以下记忆:\n{facts_text}"
|
||||
Reference in New Issue
Block a user