Initial commit: 国土空间规划课程智能体 v1.0
单容器 Docker 架构的国土空间规划课程智能问答系统,集成 FastAPI 后端与 Next.js 前端。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
"""
|
||||
LangChain 1.0 对话链(Normal Mode)
|
||||
"""
|
||||
from typing import List, Dict, Any, Optional
|
||||
from langchain_core.runnables import RunnablePassthrough
|
||||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
from langchain_core.messages import HumanMessage, AIMessage, SystemMessage
|
||||
from langchain_core.output_parsers import StrOutputParser
|
||||
|
||||
from ..llm.siliconflow import get_llm_client
|
||||
|
||||
|
||||
class ConversationChain:
|
||||
"""标准对话链(LangChain 1.0)"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
system_prompt: Optional[str] = None,
|
||||
model: Optional[str] = None
|
||||
):
|
||||
"""初始化对话链
|
||||
|
||||
Args:
|
||||
system_prompt: 系统提示词
|
||||
model: 可选的模型名称,如 deepseek-ai/DeepSeek-V3, Qwen/QwQ-32B
|
||||
"""
|
||||
self.llm = get_llm_client(model=model).llm
|
||||
self.system_prompt = system_prompt or "你是一个专业的国土空间规划知识问答助手。请基于你的知识回答用户的问题。"
|
||||
|
||||
# 创建带历史的Prompt模板
|
||||
self.prompt = ChatPromptTemplate.from_messages([
|
||||
SystemMessage(content=self.system_prompt),
|
||||
MessagesPlaceholder(variable_name="chat_history"),
|
||||
("human", "{question}")
|
||||
])
|
||||
|
||||
# 创建对话链
|
||||
self.chain = self._create_chain()
|
||||
|
||||
def _create_chain(self):
|
||||
"""创建对话链"""
|
||||
return (
|
||||
self.prompt
|
||||
| self.llm
|
||||
| StrOutputParser()
|
||||
)
|
||||
|
||||
def invoke(self, question: str, chat_history: List[Dict] = None) -> Dict[str, Any]:
|
||||
"""同步调用"""
|
||||
history_messages = self._format_history(chat_history or [])
|
||||
answer = self.chain.invoke({
|
||||
"question": question,
|
||||
"chat_history": history_messages
|
||||
})
|
||||
|
||||
return {
|
||||
"answer": answer,
|
||||
"sources": [],
|
||||
"metadata": {
|
||||
"mode": "normal",
|
||||
"has_history": bool(chat_history)
|
||||
}
|
||||
}
|
||||
|
||||
async def ainvoke(self, question: str, chat_history: List[Dict] = None) -> Dict[str, Any]:
|
||||
"""异步调用"""
|
||||
history_messages = self._format_history(chat_history or [])
|
||||
answer = await self.chain.ainvoke({
|
||||
"question": question,
|
||||
"chat_history": history_messages
|
||||
})
|
||||
|
||||
return {
|
||||
"answer": answer,
|
||||
"sources": [],
|
||||
"metadata": {
|
||||
"mode": "normal",
|
||||
"has_history": bool(chat_history)
|
||||
}
|
||||
}
|
||||
|
||||
async def astream_with_thinking(self, question: str, chat_history: List[Dict] = None):
|
||||
"""流式调用(包含思考过程)"""
|
||||
import time
|
||||
|
||||
# 思考阶段
|
||||
start_time = time.time()
|
||||
yield {"type": "thinking", "stage": "understanding", "message": "正在理解问题..."}
|
||||
|
||||
# 准备历史
|
||||
history_messages = self._format_history(chat_history or [])
|
||||
|
||||
yield {"type": "thinking", "stage": "generating", "message": "正在生成回答..."}
|
||||
|
||||
# 流式生成
|
||||
async for chunk in self.chain.astream({
|
||||
"question": question,
|
||||
"chat_history": history_messages
|
||||
}):
|
||||
yield {"type": "chunk", "content": chunk}
|
||||
|
||||
# 完成
|
||||
total_time = time.time() - start_time
|
||||
yield {
|
||||
"type": "complete",
|
||||
"metadata": {
|
||||
"total_time": round(total_time, 2)
|
||||
}
|
||||
}
|
||||
|
||||
def _format_history(self, chat_history: List[Dict]) -> List:
|
||||
"""格式化聊天历史为LangChain消息格式"""
|
||||
messages = []
|
||||
for msg in chat_history:
|
||||
if msg["role"] == "user":
|
||||
messages.append(HumanMessage(content=msg["content"]))
|
||||
elif msg["role"] == "assistant":
|
||||
messages.append(AIMessage(content=msg["content"]))
|
||||
return messages
|
||||
|
||||
|
||||
def create_conversation_chain(system_prompt: Optional[str] = None, model: Optional[str] = None) -> ConversationChain:
|
||||
"""创建对话链实例
|
||||
|
||||
Args:
|
||||
system_prompt: 系统提示词
|
||||
model: 可选的模型名称,如 deepseek-ai/DeepSeek-V3, Qwen/QwQ-32B
|
||||
"""
|
||||
return ConversationChain(system_prompt=system_prompt, model=model)
|
||||
Reference in New Issue
Block a user