1. 项目概述:智能电影推荐助手的架构设计
这个智能电影推荐助手项目展示了一个典型的三层AI应用架构,从底层的提示词工程到中层的上下文管理,再到表层的Agent框架编排。作为一个完整的示例项目,它完美诠释了如何将现代AI技术栈应用于实际场景。
项目的核心价值在于:
- 演示了如何通过分层设计解耦复杂AI系统
- 提供了可复用的工程实践模板
- 展示了从原始用户输入到结构化输出的完整处理流程
- 实现了基于反馈的持续优化机制
技术栈选择上,项目采用Python作为开发语言,支持DeepSeek和OpenAI两种大模型API接入,通过模块化设计保持扩展性。整个代码库不足500行,却完整覆盖了一个AI应用的核心要素。
2. 环境准备与项目配置
2.1 基础环境搭建
首先需要准备Python 3.8+环境,推荐使用conda创建虚拟环境:
bash复制conda create -n movie_recommender python=3.8
conda activate movie_recommender
项目依赖非常简单,主要包含三个核心库:
bash复制pip install openai==1.30.0 python-dotenv==1.0.0 pydantic==2.5.0
提示:实际部署时建议固定依赖版本,避免因库更新导致的兼容性问题。可以使用
pip freeze > requirements.txt生成精确的依赖清单。
2.2 API密钥配置
项目支持DeepSeek和OpenAI双后端,配置方式如下:
- 在项目根目录创建
.env文件 - 根据使用的服务商填写对应配置:
ini复制# DeepSeek配置
DEEPSEEK_API_KEY=sk-your-key-here
DEEPSEEK_BASE_URL=https://api.deepseek.com
# 或OpenAI配置
# OPENAI_API_KEY=sk-your-key-here
安全提示:永远不要将API密钥提交到版本控制系统。建议将
.env添加到.gitignore,并使用环境变量管理敏感信息。
2.3 模型参数调优
在src/config.py中,可以调整关键模型参数:
python复制MODEL_CONFIG = {
"provider": "deepseek", # 可切换为"openai"
"model": "deepseek-chat", # 对应"gpt-3.5-turbo"
"temperature": 0.7, # 控制输出随机性
"max_tokens": 1000 # 限制响应长度
}
温度参数(temperature)的实践经验:
- 推荐场景:0.7-1.0(适度创造性)
- 反馈处理:0.3-0.7(更确定性)
- 严格格式化输出:0.1-0.3(最小随机性)
3. 核心模块实现解析
3.1 提示词工程层设计
提示词工程模块(prompt_engineering.py)展示了三种典型提示设计模式:
基础角色定义提示
python复制SYSTEM_PROMPT_BASIC = """
你是一个专业的电影推荐助手。
你的任务是帮助用户找到他们喜欢的电影。
"""
适用场景:开放式对话,不需要严格格式控制时使用。
结构化输出提示
python复制SYSTEM_PROMPT_WITH_FORMAT = """
你是一个专业的电影推荐助手。
## 输出格式(必须严格遵守)
{
"movies": [{
"title": "电影名称",
"year": 年份,
"genre": "类型",
"reason": "推荐理由"
}]
}
"""
关键设计点:
- 明确指定JSON schema
- 强调"必须遵守"
- 禁止额外文本输出
- 适合程序化处理场景
Few-shot示例提示
python复制FEW_SHOT_EXAMPLES = """
用户:我喜欢科幻片
助手:
{"movies":[{"title":"星际穿越","year":2014,"genre":"科幻"}]}
"""
实践经验:
- 3-5个典型示例效果最佳
- 覆盖主要使用场景
- 示例间保持风格一致
- 可提升格式合规率30%以上
专业技巧:组合使用"角色定义+格式约束+Few-shot"可以同时获得高合规性和灵活性。实际测试中,这种组合使JSON输出合规率从60%提升至95%+。
3.2 上下文工程实现
上下文工程模块(context_engineering.py)负责管理三类关键信息:
1. 语义记忆(用户画像)
python复制self.user_profiles = {
"user_123": {
"preferred_genres": ["科幻", "悬疑"],
"disliked_genres": ["恐怖"],
"favorite_movies": ["盗梦空间", "星际穿越"]
}
}
更新机制:
- 显式反馈(用户直接表达偏好)
- 隐式反馈(分析交互记录)
- 手动设置(开发人员配置)
2. 工作记忆(对话历史)
python复制self.conversation_history = [
{"role": "user", "content": "推荐科幻片"},
{"role": "assistant", "content": "为您推荐《星际穿越》"}
]
压缩策略:
- 保留最近3轮完整对话
- 更早历史生成摘要
- 关键信息提取保存
3. 外部知识(电影数据库)
python复制self.movie_db = {
"科幻": ["星际穿越", "盗梦空间"],
"喜剧": ["三傻大闹宝莱坞"]
}
实际项目中应替换为:
- 向量数据库(FAISS, Chroma)
- 图数据库(Neo4j)
- 专业电影API(TMDB)
上下文注入决策流程:
python复制def build_context(self, user_input: str) -> Dict:
context = {}
# 1. 意图识别
intent = self._classify_intent(user_input)
# 2. 知识检索
if intent == "推荐":
context["retrieved_knowledge"] = self._retrieve_movies()
# 3. 用户画像注入
context["user_profile"] = self.user_profiles.get(user_id)
# 4. 对话历史处理
context["conversation_history"] = self._process_history()
return context
3.3 Agent框架架构
Agent框架采用组合模式,核心类结构如下:
BaseAgent(基类)
python复制class BaseAgent:
def __init__(self, name, role):
self.name = name
self.role = role
self.client = OpenAI() # 初始化API客户端
def call_llm(self, prompt):
# 统一调用接口
return self.client.chat.completions.create(...)
def _safe_parse_json(self, response):
# 四级JSON解析策略
# 1. 直接解析
# 2. 提取```json块
# 3. 提取```块
# 4. 提取第一个{}
RecommendationAgent(推荐代理)
python复制class RecommendationAgent(BaseAgent):
def run(self, user_input):
# 1. 构建上下文
context = self.context_engineer.build_context(user_input)
# 2. 构造提示词
prompt = build_prompt(user_input, context)
# 3. 调用LLM
response = self.call_llm(prompt)
# 4. 解析响应
return self._safe_parse_json(response)
FeedbackAgent(反馈代理)
python复制class FeedbackAgent(BaseAgent):
def run(self, feedback):
# 1. 分析反馈情感
sentiment = self._analyze_sentiment(feedback)
# 2. 提取偏好信息
preferences = self._extract_preferences(feedback)
# 3. 更新用户画像
self._update_profile(preferences)
# 4. 生成响应
return self._generate_response()
MovieAgentFramework(协调器)
python复制class MovieAgentFramework:
def process(self, user_input):
# 1. 意图识别
intent = self._classify_intent(user_input)
# 2. 路由到对应Agent
if intent == "推荐":
return self.recommendation_agent.run(user_input)
else:
return self.feedback_agent.run(user_input)
# 3. 维护对话状态
self._update_conversation(user_input, response)
4. 核心业务流程实现
4.1 推荐流程详解
完整推荐流程包含以下步骤:
-
意图识别
- 关键词匹配:"推荐"、"找"、"看"
- 语义分析(简化版)
-
上下文构建
python复制context = { "intent": "推荐", "user_profile": { "preferred_genres": ["科幻"], "disliked_genres": ["恐怖"] }, "retrieved_knowledge": ["星际穿越", "盗梦空间"] } -
提示词组装
python复制prompt = f""" {SYSTEM_PROMPT_WITH_FORMAT} {FEW_SHOT_EXAMPLES} 当前用户偏好:{context['user_profile']} 可选电影列表:{context['retrieved_knowledge']} 用户输入:{user_input} 助手响应: """ -
大模型调用
python复制response = client.chat.completions.create( model="deepseek-chat", messages=[{"role": "user", "content": prompt}], temperature=0.7 ) -
响应处理
- JSON解析与校验
- 错误处理与重试
- 结果格式化
4.2 反馈处理流程
反馈处理的核心在于偏好提取和画像更新:
-
情感分析
- Positive:"喜欢"、"很棒"、"推荐"
- Negative:"不喜欢"、"讨厌"、"太差"
- Neutral:"看过"、"知道"
-
实体提取
python复制{ "sentiment": "positive", "preferred_genre": "科幻", "mentioned_movie": "星际穿越" } -
画像更新
python复制def update_preference(self, user_id, key, value): if key == "preferred_genre": self.user_profiles[user_id]["preferred_genres"].append(value) elif key == "favorite_movie": self.user_profiles[user_id]["favorite_movies"].append(value) -
响应生成
- 确认反馈接收
- 基于新偏好的即时推荐
- 个性化响应生成
4.3 对话状态管理
完整的对话状态维护包括:
短期状态
python复制self.conversation_history = [
{"role": "user", "content": "推荐科幻片"},
{"role": "assistant", "content": "为您推荐《星际穿越》"},
{"role": "user", "content": "我不喜欢太烧脑的"}
]
长期画像
python复制self.user_profiles = {
"user_123": {
"preferred_genres": ["科幻"],
"disliked_genres": ["烧脑"],
"favorite_movies": ["星际穿越"]
}
}
上下文压缩策略
- 最近3轮完整保存
- 历史对话生成摘要:
python复制{ "role": "summary", "content": "用户主要讨论科幻电影,不喜欢烧脑剧情" }
5. 项目优化与实践建议
5.1 性能优化方案
提示词压缩技巧
- 移除不必要的空白字符
- 使用缩写字段名
- 精简Few-shot示例
缓存策略
python复制from functools import lru_cache
@lru_cache(maxsize=100)
def get_recommendations(genre: str) -> List:
# 缓存常见查询
return query_movies(genre)
异步处理
python复制async def batch_recommend(requests: List):
tasks = [process_request(req) for req in requests]
return await asyncio.gather(*tasks)
5.2 扩展性改进
插件化架构
python复制class Plugin:
def execute(self, context):
pass
class GenreAnalyzer(Plugin):
def execute(self, context):
# 分析类型偏好
pass
配置化流程
yaml复制recommend_flow:
steps:
- intent_classification
- context_building
- prompt_assembly
- llm_invocation
- response_processing
多模型路由
python复制def route_model(intent):
if intent == "推荐":
return "movie-specialist"
elif intent == "闲聊":
return "general-chat"
5.3 生产级改进建议
-
增强健壮性
- 输入验证与消毒
- 重试机制(指数退避)
- 熔断保护(Circuit Breaker)
-
监控指标
python复制stats = { "response_time": 0.45, "success_rate": 0.98, "cache_hit_rate": 0.7 } -
安全加固
- 输入输出过滤
- API密钥轮换
- 访问速率限制
-
测试策略
- 单元测试:核心逻辑
- 集成测试:组件交互
- 压力测试:性能基准
6. 典型问题排查指南
6.1 JSON解析失败
症状
code复制{"error": "解析失败", "raw": "```json\n{\"movies\":...}"}
解决方案
- 检查提示词中的格式要求
- 增加更严格的输出指令
- 实现多级解析策略:
python复制def parse_response(response): # 尝试1:直接解析 try: return json.loads(response) # 尝试2:提取json代码块 match = re.search(r'```json(.*?)```', response) if match: return json.loads(match.group(1)) # 尝试3:...
6.2 推荐质量下降
可能原因
- 上下文信息过时
- 用户画像未更新
- 知识库数据陈旧
优化措施
python复制def refresh_context(user_id):
# 更新用户画像
profile = fetch_latest_profile(user_id)
# 刷新电影数据库
movies = query_fresh_movies()
# 重建上下文
return build_context(profile, movies)
6.3 API调用超时
处理策略
python复制from tenacity import retry, stop_after_attempt
@retry(stop=stop_after_attempt(3))
def call_api_safely(prompt):
try:
return client.chat.completions.create(...)
except TimeoutError:
log.warning("API timeout")
raise
6.4 意图识别错误
增强方案
python复制def classify_intent(text):
# 规则引擎
if contains_keywords(text, ["推荐", "找"]):
return "recommend"
# 机器学习模型
return intent_model.predict(text)
7. 项目演进路线
7.1 短期优化
-
增强推荐逻辑
- 结合用户观看历史
- 考虑时间上下文(季节/节假日)
- 融入社交推荐(好友喜欢)
-
改进反馈处理
- 更细粒度情感分析
- 隐式反馈捕获(停留时间等)
- 主动澄清机制
7.2 中期规划
-
知识图谱集成
python复制class KnowledgeGraph: def get_related_movies(self, movie): # 查询导演、演员、类型关联 return related -
多模态扩展
- 海报图像分析
- 预告片理解
- 语音交互支持
-
个性化排序
python复制def personalize_ranking(movies, user): # 应用个性化排序模型 return sorted(movies, key=lambda x: score(x, user))
7.3 长期愿景
-
自主进化系统
- 自动提示词优化
- 上下文策略学习
- Agent协作模式进化
-
跨平台整合
- 流媒体平台对接
- 社交媒体集成
- 智能家居联动
-
生态建设
- 开发者API开放
- 插件市场
- 社区贡献机制
在实际开发这类AI应用时,最关键的是保持模块化设计,确保各层(提示词、上下文、Agent)能够独立演进。这个电影推荐项目提供了一个很好的起点,开发者可以基于此架构不断扩展功能,同时保持代码的可维护性。