From 59ff67595c7829af34afd893568a243df1e3e861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B3=A2=E6=BE=9C=E5=A3=AE=E9=98=94?= <263303411@qq.com> Date: Wed, 2 Apr 2025 21:37:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=B8=93=E4=B8=9A=E7=BA=A7?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E8=AF=8D=E7=94=9F=E6=88=90=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__pycache__/models.cpython-312.pyc | Bin 8296 -> 8296 bytes .../__pycache__/routes.cpython-312.pyc | Bin 27468 -> 46048 bytes flask_prompt_master/app.py | 239 +++ .../docs/api_documentation.txt | 1439 +++++++++++++++++ flask_prompt_master/routes.py | 483 ++++++ flask_prompt_master/static/css/style.css | 18 + requirements-test.txt | 3 + requirements.txt | 2 + tests/conftest.py | 24 + tests/test_api.py | 173 ++ 10 files changed, 2381 insertions(+) create mode 100644 flask_prompt_master/app.py create mode 100644 flask_prompt_master/docs/api_documentation.txt create mode 100644 flask_prompt_master/static/css/style.css create mode 100644 requirements-test.txt create mode 100644 requirements.txt create mode 100644 tests/conftest.py create mode 100644 tests/test_api.py diff --git a/flask_prompt_master/__pycache__/models.cpython-312.pyc b/flask_prompt_master/__pycache__/models.cpython-312.pyc index 9e898630deaa52ea543f57175737991df2082dea..071a4d245d7214a14e34e9998702772fe8d5d4ee 100644 GIT binary patch delta 30 kcmaFi@WO%nG%qg~0}uqBc(sw+gM%e8v!r-)IESDF0Gdt-N&o-= delta 30 kcmaFi@WO%nG%qg~0}%AD*s+n@gM+1{I5~N9IESDF0GXl*G5`Po diff --git a/flask_prompt_master/__pycache__/routes.cpython-312.pyc b/flask_prompt_master/__pycache__/routes.cpython-312.pyc index 6d67d36483aa3758aba36db226adb0bfa4b63603..0cccaf4d2b7eefa976d09b58a77c3c153fc10e7d 100644 GIT binary patch delta 17679 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', methods=['GET']) +@require_auth +def get_template(template_id): + template = next((t for t in MOCK_TEMPLATES if t['id'] == template_id), None) + if not template: + return jsonify({'error': 'Template not found'}), 404 + + return jsonify({ + 'code': 200, + 'data': template + }) + +# 创建模板接口 +@app.route('/api/v1/templates', methods=['POST']) +@require_auth +def create_template(): + data = request.get_json() + + # 验证必要字段 + required_fields = ['name', 'description', 'category', 'industry', 'profession'] + for field in required_fields: + if field not in data: + return jsonify({'error': f'Missing required field: {field}'}), 400 + + # 创建新模板 + new_template = { + 'id': str(len(MOCK_TEMPLATES) + 1), + **data, + 'created_at': datetime.now().isoformat() + } + MOCK_TEMPLATES.append(new_template) + + return jsonify({ + 'code': 200, + 'data': { + 'id': new_template['id'], + 'message': 'Template created successfully' + } + }) + +# 更新模板接口 +@app.route('/api/v1/templates/', methods=['PUT']) +@require_auth +def update_template(template_id): + template = next((t for t in MOCK_TEMPLATES if t['id'] == template_id), None) + if not template: + return jsonify({'error': 'Template not found'}), 404 + + data = request.get_json() + template.update(data) + + return jsonify({ + 'code': 200, + 'data': { + 'message': 'Template updated successfully' + } + }) + +# 删除模板接口 +@app.route('/api/v1/templates/', methods=['DELETE']) +@require_auth +def delete_template(template_id): + template_index = next((i for i, t in enumerate(MOCK_TEMPLATES) if t['id'] == template_id), None) + if template_index is None: + return jsonify({'error': 'Template not found'}), 404 + + MOCK_TEMPLATES.pop(template_index) + + return jsonify({ + 'code': 200, + 'data': { + 'message': 'Template deleted successfully' + } + }) + +# 模糊搜索提示词模板接口 +@app.route('/api/v1/templates/search', methods=['GET']) +@require_auth +def search_templates(): + """模糊搜索提示词模板""" + # 获取搜索参数 + keyword = request.args.get('keyword', '').strip() + page = int(request.args.get('page', 1)) + size = int(request.args.get('size', 10)) + + # 如果没有关键词,返回空结果 + if not keyword: + return jsonify({ + 'code': 200, + 'data': { + 'total': 0, + 'pages': 0, + 'current_page': page, + 'templates': [] + } + }) + + # 执行模糊搜索 + # 搜索范围:名称、描述、分类、行业、职业、子分类、系统提示词 + search_results = [] + for template in MOCK_TEMPLATES: + # 在各个字段中搜索关键词 + if any(keyword.lower() in str(value).lower() for value in [ + template.get('name', ''), + template.get('description', ''), + template.get('category', ''), + template.get('industry', ''), + template.get('profession', ''), + template.get('sub_category', ''), + template.get('system_prompt', '') + ]): + # 添加匹配度信息 + match_score = sum( + str(value).lower().count(keyword.lower()) + for value in [ + template.get('name', ''), + template.get('description', ''), + template.get('category', ''), + template.get('industry', ''), + template.get('profession', ''), + template.get('sub_category', ''), + template.get('system_prompt', '') + ] + ) + search_results.append({ + **template, + '_match_score': match_score + }) + + # 按匹配度排序 + search_results.sort(key=lambda x: x['_match_score'], reverse=True) + + # 移除匹配度信息 + search_results = [{k: v for k, v in t.items() if k != '_match_score'} + for t in search_results] + + # 计算分页 + total = len(search_results) + total_pages = (total + size - 1) // size + start = (page - 1) * size + end = start + size + paginated_results = search_results[start:end] + + # 返回结果 + return jsonify({ + 'code': 200, + 'data': { + 'total': total, + 'pages': total_pages, + 'current_page': page, + 'keyword': keyword, + 'templates': paginated_results + } + }) + +if __name__ == '__main__': + app.run(debug=True, port=5000) \ No newline at end of file diff --git a/flask_prompt_master/docs/api_documentation.txt b/flask_prompt_master/docs/api_documentation.txt new file mode 100644 index 0000000..a36961f --- /dev/null +++ b/flask_prompt_master/docs/api_documentation.txt @@ -0,0 +1,1439 @@ +# 提示词大师API文档 + +## 目录 +- [微信小程序接口](#微信小程序接口) + - [专家提示词生成](#专家提示词生成) + - [用户登录](#用户登录) + - [更新用户信息](#更新用户信息) + - [生成提示词](#生成提示词) + - [获取提示词模板列表](#获取提示词模板列表) + - [获取模板详情](#获取模板详情) + - [搜索历史提示词](#搜索历史提示词) + - [搜索提示词模板](#搜索提示词模板) + - [获取历史提示词](#获取历史提示词) + - [获取提示词详情](#获取提示词详情) + - [获取提示词统计](#获取提示词统计) + - [删除历史提示词](#删除历史提示词) + +## 微信小程序接口 + +### 专家提示词生成 + +#### 接口概述 +- **功能说明**:基于两阶段专家系统生成高质量提示词 +- **应用场景**:需要生成专业、结构化的提示词时使用 +- **接口版本**:v1.0 + +#### 请求信息 +- **请求方法**:POST +- **请求URL**:`/api/wx/generate/expert` +- **请求头**: + ``` + Content-Type: application/json + ``` + +#### 请求参数 +| 参数名 | 位置 | 类型 | 必填 | 说明 | 示例值 | +|--------|------|------|------|------|--------| +| input_text | body | string | 是 | 用户输入文本 | "开发一个电商网站" | +| uid | body | string | 是 | 用户ID | "12345" | + +#### 响应信息 +- **响应状态码**: + - 200:生成成功 + - 400:参数错误 + - 500:服务器错误 + +- **响应体数据结构**: +```json +{ + "code": 200, + "message": "success", + "data": { + "prompt_id": 1, + "intent_analysis": { + "core_intent": "技术", + "domain": "web开发", + "key_requirements": [ + "电商功能", + "用户管理" + ], + "expected_output": "系统设计方案", + "constraints": [ + "性能要求", + "安全标准" + ], + "keywords": [ + "电商", + "网站开发" + ] + }, + "generated_prompt": "作为一位资深的系统架构师...", + "created_at": "2024-03-14 12:34:56" + } +} +``` + +#### 错误码说明 +| 错误码 | 说明 | 解决方案 | +|--------|------|----------| +| 400 | 缺少必要参数 | 确保提供input_text和uid | +| 400 | 请求必须是JSON格式 | 检查Content-Type和请求体格式 | +| 500 | 意图分析结果格式错误 | 请重试请求 | +| 500 | 生成提示词过程出错 | 请重试请求 | + +#### 示例请求 + +1. **技术开发场景**: +```json +{ + "input_text": "使用Vue.js开发一个后台管理系统,包含用户管理、权限控制和数据统计功能", + "uid": "12345" +} +``` + +2. **创意设计场景**: +```json +{ + "input_text": "设计一个科技公司的品牌logo,要求现代简约风格,体现科技感和创新", + "uid": "12345" +} +``` + +3. **数据分析场景**: +```json +{ + "input_text": "分析电商平台近三个月的用户购买行为,找出影响转化率的关键因素", + "uid": "12345" +} +``` + +4. **咨询场景**: +```json +{ + "input_text": "为一家初创公司制定市场营销策略,预算有限,目标是提高品牌知名度", + "uid": "12345" +} +``` + +#### 注意事项 +1. 输入文本应该尽可能具体和清晰 +2. 系统会自动识别意图并选择相应的专家模板 +3. 生成的提示词会被保存到数据库 +4. 返回的prompt_id可用于后续查询或删除操作 +5. intent_analysis包含系统对需求的理解分析 +6. 建议实现请求重试机制 + +### 用户登录 + +#### 接口概述 +- **功能说明**:微信小程序用户登录 +- **应用场景**:用户首次进入小程序或登录失效时使用 +- **接口版本**:v1.0 + +#### 请求信息 +- **请求方法**:POST +- **请求URL**:`/api/wx/login` +- **请求头**: + ``` + Content-Type: application/json + ``` + +#### 请求参数 +| 参数名 | 位置 | 类型 | 必填 | 说明 | 示例值 | +|--------|------|------|------|------|--------| +| code | body | string | 是 | 微信登录code | "023Ak5000bnk1M1Cix300Kk5k83Ak50v" | + +#### 响应信息 +- **响应状态码**: + - 200:登录成功 + - 400:参数错误 + - 500:服务器错误 + +- **响应体数据结构**: +```json +{ + "code": 200, + "message": "success", + "data": { + "token": "md5hashtoken...", + "openid": "wx_openid...", + "uid": 12345, + "user_info": { + "id": 12345, + "nickname": "用户昵称", + "avatar_url": "https://...", + "gender": 1, + "phone": "13800138000" + } + } +} +``` + +### 更新用户信息 + +#### 接口概述 +- **功能说明**:更新微信用户信息 +- **应用场景**:用户授权获取信息后更新用户资料 +- **接口版本**:v1.0 + +#### 请求信息 +- **请求方法**:POST +- **请求URL**:`/api/wx/update_userinfo` +- **请求头**: + ``` + Content-Type: application/json + ``` + +#### 请求参数 +| 参数名 | 位置 | 类型 | 必填 | 说明 | 示例值 | +|--------|------|------|------|------|--------| +| openid | body | string | 是 | 用户openid | "wx_openid..." | +| nickName | body | string | 否 | 用户昵称 | "张三" | +| avatarUrl | body | string | 否 | 头像URL | "https://..." | +| gender | body | integer | 否 | 性别(1:男,2:女) | 1 | +| country | body | string | 否 | 国家 | "China" | +| province | body | string | 否 | 省份 | "Guangdong" | +| city | body | string | 否 | 城市 | "Shenzhen" | +| language | body | string | 否 | 语言 | "zh_CN" | + +### 生成提示词 + +#### 接口概述 +- **功能说明**:生成AI提示词 +- **应用场景**:用户输入文本生成优化后的提示词 +- **接口版本**:v1.0 + +#### 请求信息 +- **请求方法**:POST +- **请求URL**:`/api/wx/generate` +- **请求头**: + ``` + Content-Type: application/json + ``` + +#### 请求参数 +| 参数名 | 位置 | 类型 | 必填 | 说明 | 示例值 | +|--------|------|------|------|------|--------| +| input_text | body | string | 是 | 输入文本 | "写一个登录页面" | +| template_id | body | integer | 否 | 模板ID | 1 | +| uid | body | string | 是 | 用户ID | "12345" | + +#### 响应信息 +- **响应状态码**: + - 200:生成成功 + - 400:参数错误 + - 500:服务器错误 + +- **响应体数据结构**: +```json +{ + "code": 200, + "message": "success", + "data": { + "prompt_id": 1, + "input_text": "写一个登录页面", + "generated_text": "请创建一个现代风格的登录页面...", + "created_at": "2024-03-14 12:34:56" + } +} +``` + +### 获取提示词模板列表 + +#### 接口概述 +- **功能说明**:获取提示词模板列表 +- **应用场景**:用户浏览或选择提示词模板时使用 +- **接口版本**:v1.0 + +#### 请求信息 +- **请求方法**:GET +- **请求URL**:`/api/wx/templates` +- **请求头**: + ``` + Content-Type: application/json + ``` + +#### 请求参数 +| 参数名 | 位置 | 类型 | 必填 | 说明 | 示例值 | +|--------|------|------|------|------|--------| +| industry | query | string | 否 | 行业筛选 | "互联网" | +| profession | query | string | 否 | 职业筛选 | "工程师" | +| category | query | string | 否 | 分类筛选 | "技术" | +| sub_category | query | string | 否 | 子分类筛选 | "前端" | + +### 搜索历史提示词 + +#### 接口概述 +- **功能说明**:搜索用户的历史提示词记录 +- **应用场景**:用户需要查找自己之前生成过的提示词时使用 +- **接口版本**:v1.0 + +#### 请求信息 +- **请求方法**:GET +- **请求URL**:`/api/wx/prompts/search` +- **请求头**: + ``` + Content-Type: application/json + ``` + +#### 请求参数 +| 参数名 | 位置 | 类型 | 必填 | 说明 | 示例值 | +|--------|------|------|------|------|--------| +| uid | query | string | 是 | 用户ID | "12345" | +| keyword | query | string | 否 | 搜索关键词 | "前端开发" | +| page | query | integer | 否 | 页码,默认1 | 1 | +| per_page | query | integer | 否 | 每页记录数,默认10 | 10 | + +#### 响应信息 +- **响应状态码**: + - 200:请求成功 + - 400:参数错误 + - 500:服务器错误 + +- **响应体数据结构**: +```json +{ + "code": 200, + "message": "success", + "data": { + "prompts": [ + { + "id": 1, + "input_text": "写一个前端组件", + "generated_text": "请创建一个响应式的...", + "created_at": "2024-03-14 12:34:56" + } + ], + "pagination": { + "total": 100, + "pages": 10, + "current_page": 1, + "per_page": 10, + "has_next": true, + "has_prev": false + } + } +} +``` + +#### 错误码说明 +| 错误码 | 说明 | 解决方案 | +|--------|------|----------| +| 400 | 缺少用户ID | 确保请求中包含uid参数 | +| 500 | 服务器内部错误 | 请稍后重试或联系技术支持 | + +### 搜索提示词模板 + +#### 接口概述 +- **功能说明**:搜索提示词模板库 +- **应用场景**:用户需要查找特定场景或领域的提示词模板时使用 +- **接口版本**:v1.0 + +#### 请求信息 +- **请求方法**:GET +- **请求URL**:`/api/wx/templates/search` +- **请求头**: + ``` + Content-Type: application/json + ``` + +#### 请求参数 +| 参数名 | 位置 | 类型 | 必填 | 说明 | 示例值 | +|--------|------|------|------|------|--------| +| keyword | query | string | 否 | 搜索关键词 | "前端开发" | +| industry | query | string | 否 | 行业筛选 | "互联网" | +| profession | query | string | 否 | 职业筛选 | "工程师" | +| category | query | string | 否 | 分类筛选 | "技术" | +| page | query | integer | 否 | 页码,默认1 | 1 | +| per_page | query | integer | 否 | 每页记录数,默认10 | 10 | + +#### 响应信息 +- **响应状态码**: + - 200:请求成功 + - 500:服务器错误 + +- **响应体数据结构**: +```json +{ + "code": 200, + "message": "success", + "data": { + "templates": [ + { + "id": 1, + "name": "前端开发工程师", + "description": "专业的前端开发工程师模板", + "system_prompt": "你是一个专业的前端开发工程师...", + "category": "软件开发", + "industry": "互联网", + "profession": "工程师", + "sub_category": "前端开发", + "is_default": true, + "created_at": "2024-03-14 12:34:56" + } + ], + "pagination": { + "total": 100, + "pages": 10, + "current_page": 1, + "per_page": 10, + "has_next": true, + "has_prev": false + } + } +} +``` + +### 获取历史提示词 + +#### 接口概述 +- **功能说明**:获取用户的历史提示词记录 +- **应用场景**:用户需要查看自己的所有历史提示词时使用 +- **接口版本**:v1.0 + +#### 请求信息 +- **请求方法**:GET +- **请求URL**:`/api/wx/prompts` +- **请求头**: + ``` + Content-Type: application/json + ``` + +#### 请求参数 +| 参数名 | 位置 | 类型 | 必填 | 说明 | 示例值 | +|--------|------|------|------|------|--------| +| uid | query | string | 是 | 用户ID | "12345" | +| page | query | integer | 否 | 页码,默认1 | 1 | +| per_page | query | integer | 否 | 每页记录数,默认10 | 10 | + +#### 响应信息 +- **响应状态码**: + - 200:请求成功 + - 400:参数错误 + - 500:服务器错误 + +- **响应体数据结构**: +```json +{ + "code": 200, + "message": "success", + "data": { + "prompts": [ + { + "id": 1, + "input_text": "写一个前端组件", + "generated_text": "请创建一个响应式的...", + "created_at": "2024-03-14 12:34:56" + } + ], + "pagination": { + "total": 100, + "pages": 10, + "current_page": 1, + "per_page": 10, + "has_next": true, + "has_prev": false + } + } +} +``` + +### 获取提示词详情 + +#### 接口概述 +- **功能说明**:获取单条提示词的详细信息 +- **应用场景**:用户需要查看某条提示词的详细信息时使用 +- **接口版本**:v1.0 + +#### 请求信息 +- **请求方法**:GET +- **请求URL**:`/api/wx/prompt/{prompt_id}` +- **请求头**: + ``` + Content-Type: application/json + ``` + +#### 请求参数 +| 参数名 | 位置 | 类型 | 必填 | 说明 | 示例值 | +|--------|------|------|------|------|--------| +| prompt_id | path | integer | 是 | 提示词记录ID | 1 | +| uid | query | string | 是 | 用户ID | "12345" | + +#### 响应信息 +- **响应状态码**: + - 200:请求成功 + - 400:参数错误 + - 403:无权限 + - 404:记录不存在 + - 500:服务器错误 + +- **响应体数据结构**: +```json +{ + "code": 200, + "message": "success", + "data": { + "prompt": { + "id": 1, + "input_text": "写一个前端组件", + "generated_text": "请创建一个响应式的...", + "created_at": "2024-03-14 12:34:56" + } + } +} +``` + +### 获取提示词统计 + +#### 接口概述 +- **功能说明**:获取用户提示词的统计信息 +- **应用场景**:用户需要查看自己的提示词使用情况时使用 +- **接口版本**:v1.0 + +#### 请求信息 +- **请求方法**:GET +- **请求URL**:`/api/wx/prompt_stats` +- **请求头**: + ``` + Content-Type: application/json + ``` + +#### 请求参数 +| 参数名 | 位置 | 类型 | 必填 | 说明 | 示例值 | +|--------|------|------|------|------|--------| +| uid | query | string | 是 | 用户ID | "12345" | + +#### 响应信息 +- **响应状态码**: + - 200:请求成功 + - 400:参数错误 + - 500:服务器错误 + +- **响应体数据结构**: +```json +{ + "code": 200, + "message": "success", + "data": { + "stats": { + "total_prompts": 100, + "used_prompts": 50, + "unused_prompts": 50 + } + } +} +``` + +### 删除历史提示词 + +#### 接口概述 +- **功能说明**:删除用户的历史提示词记录 +- **应用场景**:用户需要删除某条历史提示词时使用 +- **接口版本**:v1.0 + +#### 请求信息 +- **请求方法**:DELETE +- **请求URL**:`/api/wx/prompt/{prompt_id}` +- **请求头**: + ``` + Content-Type: application/json + ``` + +#### 请求参数 +| 参数名 | 位置 | 类型 | 必填 | 说明 | 示例值 | +|--------|------|------|------|------|--------| +| prompt_id | path | integer | 是 | 提示词记录ID | 1 | +| uid | query/body | string | 是 | 用户ID | "12345" | + +#### 响应信息 +- **响应状态码**: + - 200:删除成功 + - 400:参数错误 + - 403:无权限 + - 404:记录不存在 + - 500:服务器错误 + +- **响应体数据结构**: +```json +{ + "code": 200, + "message": "删除成功", + "data": { + "id": 1 + } +} +``` + +#### 错误码说明 +| 错误码 | 说明 | 解决方案 | +|--------|------|----------| +| 400 | 缺少用户ID | 确保请求中包含uid参数 | +| 403 | 无权删除此记录 | 确认是否为用户自己的记录 | +| 404 | 记录不存在 | 确认提示词ID是否正确 | +| 500 | 服务器内部错误 | 请稍后重试或联系技术支持 | + +## 注意事项 +1. 所有接口返回的时间格式均为:`YYYY-MM-DD HH:mm:ss` +2. 分页参数`page`从1开始计数 +3. 搜索关键词支持模糊匹配 +4. 删除操作不可恢复,请谨慎操作 +5. 所有接口都需要处理网络异常情况 +6. 建议实现请求重试机制 +7. 敏感数据传输建议使用HTTPS + +## 版本历史 +| 版本号 | 发布日期 | 更新内容 | +|--------|----------|----------| +| v1.0 | 2024-03-14 | 首次发布基础接口 | +| v1.1 | 2024-03-15 | 添加用户登录和信息更新接口 | +| v1.2 | 2024-03-16 | 添加专家提示词生成接口 | + +## 常用应用场景提示词模板 + +### 技术开发场景 + +#### 1. Web开发模板 +```json +{ + "input_text": "开发一个在线教育平台,需要包含课程管理、用户学习记录追踪和在线支付功能", + "template": { + "core_intent": "技术", + "domain": "web开发", + "key_requirements": [ + "课程管理系统", + "学习进度追踪", + "支付集成" + ], + "expected_output": "系统架构设计和技术选型方案", + "constraints": [ + "性能要求", + "安全标准", + "可扩展性" + ] + } +} +``` + +#### 2. 移动应用开发模板 +```json +{ + "input_text": "开发一个健康饮食追踪APP,包含食物记录、营养分析和健康建议功能", + "template": { + "core_intent": "技术", + "domain": "移动开发", + "key_requirements": [ + "食物数据库", + "营养计算器", + "个性化建议" + ], + "expected_output": "APP功能规划和技术实现方案", + "constraints": [ + "离线使用", + "数据隐私", + "电池优化" + ] + } +} +``` + +### 创意设计场景 + +#### 1. 品牌设计模板 +```json +{ + "input_text": "为一家新开的有机食品超市设计品牌标识和视觉系统", + "template": { + "core_intent": "创意", + "domain": "品牌设计", + "key_requirements": [ + "logo设计", + "色彩系统", + "应用规范" + ], + "expected_output": "品牌视觉识别系统", + "constraints": [ + "体现环保理念", + "现代简约风格", + "多场景适应" + ] + } +} +``` + +#### 2. UI/UX设计模板 +```json +{ + "input_text": "设计一个智能家居控制应用的用户界面,注重直观性和易用性", + "template": { + "core_intent": "创意", + "domain": "UI/UX设计", + "key_requirements": [ + "界面布局", + "交互设计", + "视觉风格" + ], + "expected_output": "UI设计稿和交互原型", + "constraints": [ + "符合人体工程学", + "支持深色模式", + "无障碍设计" + ] + } +} +``` + +### 数据分析场景 + +#### 1. 商业分析模板 +```json +{ + "input_text": "分析电商平台过去一年的销售数据,找出影响销售的关键因素并提供优化建议", + "template": { + "core_intent": "分析", + "domain": "商业分析", + "key_requirements": [ + "销售趋势分析", + "影响因素识别", + "优化建议" + ], + "expected_output": "数据分析报告和优化方案", + "constraints": [ + "数据可靠性", + "季节性因素", + "竞品影响" + ] + } +} +``` + +#### 2. 用户行为分析模板 +```json +{ + "input_text": "分析移动应用的用户使用行为,优化用户留存率", + "template": { + "core_intent": "分析", + "domain": "用户分析", + "key_requirements": [ + "用户路径分析", + "留存率计算", + "流失原因" + ], + "expected_output": "用户行为分析报告", + "constraints": [ + "隐私合规", + "数据完整性", + "实时性要求" + ] + } +} +``` + +### 咨询服务场景 + +#### 1. 市场营销策略模板 +```json +{ + "input_text": "为一家新成立的科技创业公司制定市场营销策略", + "template": { + "core_intent": "咨询", + "domain": "市场营销", + "key_requirements": [ + "目标市场定位", + "营销渠道规划", + "预算分配" + ], + "expected_output": "营销策略方案", + "constraints": [ + "预算限制", + "时间要求", + "资源可用性" + ] + } +} +``` + +#### 2. 企业管理咨询模板 +```json +{ + "input_text": "优化公司的人力资源管理系统,提高员工满意度和工作效率", + "template": { + "core_intent": "咨询", + "domain": "企业管理", + "key_requirements": [ + "流程优化", + "制度完善", + "绩效管理" + ], + "expected_output": "管理优化方案", + "constraints": [ + "企业文化", + "法律合规", + "成本控制" + ] + } +} +``` + +### 教育培训场景 + +#### 1. 课程设计模板 +```json +{ + "input_text": "设计一个Python编程入门课程,面向零基础学习者", + "template": { + "core_intent": "教育", + "domain": "课程设计", + "key_requirements": [ + "知识点规划", + "实践项目", + "学习路径" + ], + "expected_output": "完整的课程大纲和教学计划", + "constraints": [ + "学习难度递进", + "实用性优先", + "互动性要求" + ] + } +} +``` + +#### 2. 教学内容开发模板 +```json +{ + "input_text": "开发一套中学数学微课视频脚本,主题是函数与图像", + "template": { + "core_intent": "教育", + "domain": "内容开发", + "key_requirements": [ + "知识点讲解", + "例题设计", + "课件制作" + ], + "expected_output": "教学视频脚本和课件", + "constraints": [ + "符合教学大纲", + "生动有趣", + "时长控制" + ] + } +} +``` + +### 内容创作场景 + +#### 1. 新媒体内容模板 +```json +{ + "input_text": "策划一个关于人工智能技术应用的短视频系列", + "template": { + "core_intent": "创作", + "domain": "新媒体", + "key_requirements": [ + "主题规划", + "内容框架", + "传播策略" + ], + "expected_output": "内容策划方案和分集大纲", + "constraints": [ + "受众兴趣", + "平台特性", + "传播效果" + ] + } +} +``` + +#### 2. 专业写作模板 +```json +{ + "input_text": "撰写一篇关于可持续发展的研究论文大纲", + "template": { + "core_intent": "创作", + "domain": "学术写作", + "key_requirements": [ + "文献综述", + "研究方法", + "数据分析" + ], + "expected_output": "研究论文框架和写作指南", + "constraints": [ + "学术规范", + "创新性要求", + "引用规则" + ] + } +} +``` + +### 产品运营场景 + +#### 1. 产品规划模板 +```json +{ + "input_text": "规划一个社交电商小程序的产品路线图", + "template": { + "core_intent": "运营", + "domain": "产品规划", + "key_requirements": [ + "功能规划", + "迭代计划", + "数据指标" + ], + "expected_output": "产品路线图和关键里程碑", + "constraints": [ + "市场需求", + "技术可行性", + "资源限制" + ] + } +} +``` + +#### 2. 运营活动模板 +```json +{ + "input_text": "设计一个提升用户活跃度的运营活动方案", + "template": { + "core_intent": "运营", + "domain": "活动策划", + "key_requirements": [ + "活动机制", + "奖励设计", + "传播方案" + ], + "expected_output": "完整的活动执行方案", + "constraints": [ + "预算控制", + "用户体验", + "合规性" + ] + } +} +``` + +### 客户服务场景 + +#### 1. 服务流程模板 +```json +{ + "input_text": "设计一个在线客服智能应答系统的服务流程", + "template": { + "core_intent": "服务", + "domain": "客服系统", + "key_requirements": [ + "场景识别", + "回复模板", + "升级机制" + ], + "expected_output": "客服流程和话术库", + "constraints": [ + "响应速度", + "服务质量", + "用户满意度" + ] + } +} +``` + +#### 2. 投诉处理模板 +```json +{ + "input_text": "制定产品质量投诉处理的标准流程", + "template": { + "core_intent": "服务", + "domain": "投诉处理", + "key_requirements": [ + "问题分类", + "处理流程", + "补偿方案" + ], + "expected_output": "投诉处理手册", + "constraints": [ + "时效性要求", + "成本控制", + "客户满意" + ] + } +} +``` + +### 医疗健康场景 + +#### 1. 健康管理模板 +```json +{ + "input_text": "设计一个个性化的健康饮食和运动计划管理系统", + "template": { + "core_intent": "医疗", + "domain": "健康管理", + "key_requirements": [ + "饮食计划", + "运动建议", + "健康监测" + ], + "expected_output": "个性化健康管理方案", + "constraints": [ + "个体差异性", + "科学依据", + "可执行性" + ] + } +} +``` + +#### 2. 医疗咨询模板 +```json +{ + "input_text": "开发一个智能问诊初筛系统,帮助用户进行基础健康评估", + "template": { + "core_intent": "医疗", + "domain": "智能问诊", + "key_requirements": [ + "症状识别", + "风险评估", + "就医建议" + ], + "expected_output": "健康评估报告", + "constraints": [ + "医学准确性", + "责任提醒", + "隐私保护" + ] + } +} +``` + +### 金融理财场景 + +#### 1. 投资规划模板 +```json +{ + "input_text": "制定一个个人投资理财组合方案,平衡收益和风险", + "template": { + "core_intent": "金融", + "domain": "投资规划", + "key_requirements": [ + "资产配置", + "风险评估", + "收益预测" + ], + "expected_output": "投资组合建议书", + "constraints": [ + "风险控制", + "流动性要求", + "市场波动" + ] + } +} +``` + +#### 2. 财务分析模板 +```json +{ + "input_text": "分析企业财务状况,提供优化建议", + "template": { + "core_intent": "金融", + "domain": "财务分析", + "key_requirements": [ + "财务指标分析", + "现金流评估", + "成本优化" + ], + "expected_output": "财务分析报告", + "constraints": [ + "会计准则", + "行业标准", + "数据真实性" + ] + } +} +``` + +### 智能制造场景 + +#### 1. 生产优化模板 +```json +{ + "input_text": "优化工厂生产线的自动化流程,提高生产效率", + "template": { + "core_intent": "制造", + "domain": "生产优化", + "key_requirements": [ + "流程分析", + "自动化方案", + "质量控制" + ], + "expected_output": "生产优化方案", + "constraints": [ + "设备兼容性", + "安全标准", + "投资回报" + ] + } +} +``` + +#### 2. 质量管理模板 +```json +{ + "input_text": "建立智能制造质量管理和预警系统", + "template": { + "core_intent": "制造", + "domain": "质量管理", + "key_requirements": [ + "质量监控", + "预警机制", + "追溯系统" + ], + "expected_output": "质量管理体系方案", + "constraints": [ + "实时监测", + "准确度要求", + "成本效益" + ] + } +} +``` + +### 环保节能场景 + +#### 1. 能源管理模板 +```json +{ + "input_text": "设计企业能源管理和节能优化方案", + "template": { + "core_intent": "环保", + "domain": "能源管理", + "key_requirements": [ + "能耗分析", + "节能方案", + "监测系统" + ], + "expected_output": "能源优化方案", + "constraints": [ + "投资回收期", + "技术可行性", + "环保标准" + ] + } +} +``` + +#### 2. 环境评估模板 +```json +{ + "input_text": "进行项目环境影响评估并提供改善建议", + "template": { + "core_intent": "环保", + "domain": "环境评估", + "key_requirements": [ + "影响分析", + "风险评估", + "改善措施" + ], + "expected_output": "环评报告", + "constraints": [ + "法规要求", + "社会影响", + "经济可行" + ] + } +} +``` + +### 智慧城市场景 + +#### 1. 交通管理模板 +```json +{ + "input_text": "设计智能交通管理系统,优化城市交通流量", + "template": { + "core_intent": "城市", + "domain": "交通管理", + "key_requirements": [ + "流量监测", + "信号优化", + "事故预警" + ], + "expected_output": "交通管理方案", + "constraints": [ + "实时响应", + "系统稳定性", + "紧急处置" + ] + } +} +``` + +#### 2. 城市规划模板 +```json +{ + "input_text": "制定智慧社区建设规划方案", + "template": { + "core_intent": "城市", + "domain": "社区规划", + "key_requirements": [ + "功能布局", + "服务设施", + "智能系统" + ], + "expected_output": "社区规划方案", + "constraints": [ + "居民需求", + "空间限制", + "投资预算" + ] + } +} +``` + +### 人工智能场景 + +#### 1. 机器学习模型开发模板 +```json +{ + "input_text": "开发一个商品推荐系统,基于用户历史行为数据", + "template": { + "core_intent": "技术", + "domain": "机器学习", + "key_requirements": [ + "数据预处理", + "模型选择", + "特征工程" + ], + "expected_output": "推荐系统设计方案", + "constraints": [ + "实时性要求", + "计算资源", + "冷启动问题" + ] + } +} +``` + +#### 2. 自然语言处理模板 +```json +{ + "input_text": "构建一个多语言客服聊天机器人系统", + "template": { + "core_intent": "技术", + "domain": "NLP", + "key_requirements": [ + "语言理解", + "对话管理", + "情感分析" + ], + "expected_output": "聊天机器人系统方案", + "constraints": [ + "语言准确性", + "响应速度", + "场景覆盖" + ] + } +} +``` + +### 游戏开发场景 + +#### 1. 游戏设计模板 +```json +{ + "input_text": "设计一个休闲类手机游戏的核心玩法", + "template": { + "core_intent": "创意", + "domain": "游戏设计", + "key_requirements": [ + "玩法机制", + "关卡设计", + "奖励系统" + ], + "expected_output": "游戏设计文档", + "constraints": [ + "易上手性", + "付费设计", + "留存机制" + ] + } +} +``` + +#### 2. 游戏运营模板 +```json +{ + "input_text": "制定游戏的用户增长和变现策略", + "template": { + "core_intent": "运营", + "domain": "游戏运营", + "key_requirements": [ + "获客渠道", + "活动规划", + "付费转化" + ], + "expected_output": "运营策略方案", + "constraints": [ + "用户体验", + "数据分析", + "成本控制" + ] + } +} +``` + +### 农业科技场景 + +#### 1. 智慧农业模板 +```json +{ + "input_text": "设计一个智能温室控制系统", + "template": { + "core_intent": "技术", + "domain": "智慧农业", + "key_requirements": [ + "环境监测", + "自动调节", + "生长预测" + ], + "expected_output": "智能控制方案", + "constraints": [ + "能源效率", + "成本效益", + "可靠性" + ] + } +} +``` + +#### 2. 农产品溯源模板 +```json +{ + "input_text": "建立农产品全程追溯系统", + "template": { + "core_intent": "技术", + "domain": "农产品溯源", + "key_requirements": [ + "生产记录", + "物流追踪", + "质量监控" + ], + "expected_output": "追溯系统方案", + "constraints": [ + "数据真实性", + "查询便捷", + "成本可控" + ] + } +} +``` + +### 物联网场景 + +#### 1. 智能家居模板 +```json +{ + "input_text": "开发智能家居设备联动控制系统", + "template": { + "core_intent": "技术", + "domain": "物联网", + "key_requirements": [ + "设备互联", + "场景联动", + "远程控制" + ], + "expected_output": "系统架构方案", + "constraints": [ + "设备兼容性", + "网络安全", + "用户友好" + ] + } +} +``` + +#### 2. 工业物联网模板 +```json +{ + "input_text": "构建工厂设备监控和预测性维护系统", + "template": { + "core_intent": "技术", + "domain": "工业物联网", + "key_requirements": [ + "数据采集", + "故障预测", + "维护计划" + ], + "expected_output": "监控系统方案", + "constraints": [ + "实时监测", + "预警准确性", + "维护成本" + ] + } +} +``` + +### 使用建议 + +1. **选择合适模板** + - 根据项目性质选择对应领域的模板 + - 可以组合多个模板的元素 + - 根据具体需求调整模板参数 + +2. **自定义调整** + - 可以根据实际需求修改key_requirements + - 根据项目特点调整constraints + - 可以添加特定领域的专业要求 + +3. **最佳实践** + - 保持输入文本的具体和清晰 + - 确保约束条件的可执行性 + - 注意专业术语的准确使用 + - 考虑跨领域的整合需求 + +4. **场景组合应用** + - 可以根据项目需求组合多个场景模板 + - 注意调整不同场景间的关联性 + - 确保组合后的提示词保持连贯性 + +5. **模板优化建议** + - 定期根据使用效果更新模板内容 + - 收集用户反馈进行优化 + - 保持模板的时效性和实用性 + +6. **特殊场景处理** + - 对于特殊或复杂场景,可以自定义模板 + - 注意保持专业性和可操作性 + - 适当增加具体的示例说明 + +### 使用建议更新 + +7. **跨领域整合** + - 注意不同领域模板的融合点 + - 保持专业术语的统一性 + - 考虑多维度的约束条件 + +8. **场景扩展** + - 根据具体项目特点扩展模板 + - 增加行业特定的要求 + - 适应新技术发展趋势 + +9. **持续优化** + - 收集实际应用效果反馈 + - 更新行业最新标准和要求 + - 完善模板评估机制 + +10. **技术融合应用** + - 关注新技术的应用场景 + - 注意技术间的协同效应 + - 考虑实施的可行性 + +11. **行业特化** + - 深入理解行业特点 + - 把握专业术语使用 + - 注意行业规范要求 + +12. **创新应用** + - 鼓励创新思维 + - 保持开放性思考 + - 注重实用价值 \ No newline at end of file diff --git a/flask_prompt_master/routes.py b/flask_prompt_master/routes.py index c61cbd8..50f9c1d 100644 --- a/flask_prompt_master/routes.py +++ b/flask_prompt_master/routes.py @@ -686,4 +686,487 @@ def wx_delete_prompt(prompt_id): 'data': None }) +@main_bp.route('/api/wx/prompts/search', methods=['GET']) +def wx_search_prompts(): + """搜索提示词接口""" + try: + # 获取参数 + uid = request.args.get('uid') + keyword = request.args.get('keyword', '').strip() + page = request.args.get('page', 1, type=int) + per_page = request.args.get('per_page', 10, type=int) + + if not uid: + return jsonify({ + 'code': 400, + 'message': '缺少用户ID', + 'data': None + }) + + # 构建查询 + query = Prompt.query.filter_by(wx_user_id=uid) + + # 如果有关键词,添加搜索条件 + if keyword: + search_condition = ( + Prompt.input_text.ilike(f'%{keyword}%') | # 搜索输入文本 + Prompt.generated_text.ilike(f'%{keyword}%') # 搜索生成的提示词 + ) + query = query.filter(search_condition) + + # 按时间倒序排序并分页 + query = query.order_by(Prompt.created_at.desc()) + pagination = query.paginate(page=page, per_page=per_page, error_out=False) + prompts = pagination.items + + return jsonify({ + 'code': 200, + 'message': 'success', + 'data': { + 'prompts': [{ + 'id': p.id, + 'input_text': p.input_text, + 'generated_text': p.generated_text, + 'created_at': p.created_at.strftime('%Y-%m-%d %H:%M:%S') + } for p in prompts], + 'pagination': { + 'total': pagination.total, + 'pages': pagination.pages, + 'current_page': page, + 'per_page': per_page, + 'has_next': pagination.has_next, + 'has_prev': pagination.has_prev + } + } + }) + + except Exception as e: + current_app.logger.error(f"搜索提示词失败: {str(e)}") + return jsonify({ + 'code': 500, + 'message': str(e), + 'data': None + }) + +@main_bp.route('/api/wx/templates/search', methods=['GET']) +def wx_search_templates(): + """搜索提示词模板接口""" + try: + # 获取搜索参数 + keyword = request.args.get('keyword', '').strip() + page = request.args.get('page', 1, type=int) + per_page = request.args.get('per_page', 10, type=int) + + # 构建基础查询 + query = PromptTemplate.query + + # 添加搜索条件 + if keyword: + search_condition = ( + PromptTemplate.name.ilike(f'%{keyword}%') | # 搜索模板名称 + PromptTemplate.description.ilike(f'%{keyword}%') | # 搜索模板描述 + PromptTemplate.category.ilike(f'%{keyword}%') | # 搜索分类 + PromptTemplate.industry.ilike(f'%{keyword}%') | # 搜索行业 + PromptTemplate.profession.ilike(f'%{keyword}%') | # 搜索职业 + PromptTemplate.system_prompt.ilike(f'%{keyword}%') # 搜索系统提示词 + ) + query = query.filter(search_condition) + + # 获取筛选参数(可选) + industry = request.args.get('industry') + profession = request.args.get('profession') + category = request.args.get('category') + + # 添加筛选条件 + if industry: + query = query.filter_by(industry=industry) + if profession: + query = query.filter_by(profession=profession) + if category: + query = query.filter_by(category=category) + + # 按是否默认模板和创建时间排序 + query = query.order_by(PromptTemplate.is_default.desc(), + PromptTemplate.created_at.desc()) + + # 分页 + pagination = query.paginate(page=page, per_page=per_page, error_out=False) + templates = pagination.items + + return jsonify({ + 'code': 200, + 'message': 'success', + 'data': { + 'templates': [{ + 'id': t.id, + 'name': t.name, + 'description': t.description, + 'system_prompt': t.system_prompt, # 添加system_prompt字段 + 'category': t.category, + 'industry': t.industry, + 'profession': t.profession, + 'sub_category': t.sub_category, + 'is_default': t.is_default, + 'created_at': t.created_at.strftime('%Y-%m-%d %H:%M:%S') if t.created_at else None + } for t in templates], + 'pagination': { + 'total': pagination.total, + 'pages': pagination.pages, + 'current_page': page, + 'per_page': per_page, + 'has_next': pagination.has_next, + 'has_prev': pagination.has_prev + } + } + }) + + except Exception as e: + current_app.logger.error(f"搜索模板失败: {str(e)}") + return jsonify({ + 'code': 500, + 'message': str(e), + 'data': None + }) + +@main_bp.route('/api/wx/templates/intent', methods=['POST']) +def wx_get_template_by_intent(): + """根据意图获取提示词模板""" + try: + # 获取参数 + data = request.get_json() + user_input = data.get('input_text', '').strip() + + # 意图识别系统提示词 + intent_system_prompt = """你是一位出色的意图识别专家。请分析用户输入的意图,并仅返回以下类别之一: +- 新闻获取 +- 生成图片 +- 网站开发 +- 文案创作 +- 代码开发 +- 数据分析 +- 市场营销 +- 产品设计 +- 其它 + +只返回分类名称,不要其他任何内容。""" + + # 调用意图识别 + response = client.chat.completions.create( + model="deepseek-chat", + messages=[ + {"role": "system", "content": intent_system_prompt}, + {"role": "user", "content": user_input} + ], + temperature=0.1 + ) + + intent = response.choices[0].message.content.strip() + + # 根据意图获取对应的模板提示词 + intent_prompts = { + "新闻获取": "你是一位专业的新闻编辑,擅长整理和总结新闻信息。请帮助用户获取和理解新闻内容,注意:\n1. 确保信息的准确性和时效性\n2. 提供客观中立的视角\n3. 突出重要信息要点\n4. 适当添加背景信息解释", + + "生成图片": "你是一位专业的图像生成提示词专家,擅长将文字需求转化为详细的图像生成提示词。请注意:\n1. 详细描述图像的视觉元素\n2. 指定图像的风格和氛围\n3. 添加技术参数说明\n4. 包含构图和视角建议", + + "网站开发": "你是一位专业的网站开发专家,擅长将需求转化为具体的开发方案。请注意:\n1. 明确网站的目标用户和核心功能\n2. 建议合适的技术栈\n3. 考虑性能和安全性要求\n4. 提供响应式设计建议", + + "文案创作": "你是一位专业的文案创作专家,擅长创作各类营销和品牌文案。请注意:\n1. 确定目标受众和传播渠道\n2. 突出产品/服务的核心价值\n3. 使用适当的语言风格\n4. 注意文案的节奏和结构", + + "代码开发": "你是一位专业的软件开发工程师,擅长编写高质量的代码。请注意:\n1. 遵循编码规范和最佳实践\n2. 考虑代码的可维护性和扩展性\n3. 注重性能优化\n4. 添加适当的注释和文档", + + "数据分析": "你是一位专业的数据分析师,擅长数据处理和分析。请注意:\n1. 明确分析目标和范围\n2. 选择合适的分析方法\n3. 关注数据质量和准确性\n4. 提供可操作的洞察建议", + + "市场营销": "你是一位专业的市场营销专家,擅长制定营销策略。请注意:\n1. 分析目标市场和竞争环境\n2. 制定明确的营销目标\n3. 选择合适的营销渠道\n4. 设计有效的营销活动", + + "产品设计": "你是一位专业的产品设计师,擅长用户体验和界面设计。请注意:\n1. 理解用户需求和痛点\n2. 遵循设计原则和规范\n3. 注重交互体验\n4. 考虑可实现性", + + "其它": "你是一位专业的AI助手,擅长理解和解决各类问题。请注意:\n1. 仔细理解用户需求\n2. 提供清晰的解决方案\n3. 使用专业的语言表达\n4. 确保回答的实用性" + } + + template_prompt = intent_prompts.get(intent, intent_prompts["其它"]) + + return jsonify({ + 'code': 200, + 'message': 'success', + 'data': { + 'intent': intent, + 'template_prompt': template_prompt + } + }) + + except Exception as e: + current_app.logger.error(f"获取意图模板失败: {str(e)}") + return jsonify({ + 'code': 500, + 'message': str(e), + 'data': None + }) + +@main_bp.route('/api/wx/generate/expert', methods=['POST']) +def wx_generate_expert_prompt(): + """两阶段专家提示词生成系统""" + try: + # 检查请求数据 + if not request.is_json: + return jsonify({ + 'code': 400, + 'message': '请求必须是JSON格式', + 'data': None + }) + + data = request.get_json() + if not data: + return jsonify({ + 'code': 400, + 'message': '请求数据为空', + 'data': None + }) + + # 验证必要参数 + user_input = data.get('input_text') + uid = data.get('uid') + + if not user_input or not uid: + return jsonify({ + 'code': 400, + 'message': '缺少必要参数:input_text 或 uid', + 'data': None + }) + + user_input = user_input.strip() + + # 修改第一阶段:意图识别专家的提示词,使其更严格 + intent_analyst_prompt = """你是一位资深的意图分析专家,请分析用户输入的意图和需求。 + +你必须严格按照以下JSON格式返回,不要添加任何其他内容: +{ + "core_intent": "技术", // 必须是以下选项之一:技术、创意、分析、咨询 + "domain": "web开发", // 具体的专业领域 + "key_requirements": [ // 2-4个关键需求 + "需求1", + "需求2" + ], + "expected_output": "期望输出的具体形式", // 简短描述 + "constraints": [ // 1-3个主要约束 + "约束1", + "约束2" + ], + "keywords": [ // 2-4个关键词 + "关键词1", + "关键词2" + ] +} + +注意: +1. 严格遵守JSON格式 +2. core_intent必须是四个选项之一 +3. 数组至少包含1个元素 +4. 所有字段都必须存在 +5. 不要包含注释 +6. 不要添加任何额外的文本""" + + try: + # 获取意图分析结果 + intent_response = client.chat.completions.create( + model="deepseek-chat", + messages=[ + {"role": "system", "content": intent_analyst_prompt}, + {"role": "user", "content": user_input} + ], + temperature=0.1 # 降低温度,使输出更确定 + ) + + intent_analysis_text = intent_response.choices[0].message.content.strip() + + # 添加日志记录 + current_app.logger.info(f"AI返回的意图分析结果: {intent_analysis_text}") + + # 尝试清理和解析JSON + try: + # 移除可能的markdown代码块标记 + intent_analysis_text = intent_analysis_text.replace('```json', '').replace('```', '').strip() + intent_analysis = json.loads(intent_analysis_text) + + # 验证必要字段 + required_fields = ['core_intent', 'domain', 'key_requirements', + 'expected_output', 'constraints', 'keywords'] + for field in required_fields: + if field not in intent_analysis: + raise ValueError(f"缺少必要字段: {field}") + + # 验证core_intent是否为有效值 + valid_intents = ['技术', '创意', '分析', '咨询'] + if intent_analysis['core_intent'] not in valid_intents: + intent_analysis['core_intent'] = '技术' # 默认使用技术 + + # 确保数组字段非空 + array_fields = ['key_requirements', 'constraints', 'keywords'] + for field in array_fields: + if not isinstance(intent_analysis[field], list) or len(intent_analysis[field]) == 0: + intent_analysis[field] = ['未指定'] + + except json.JSONDecodeError as e: + current_app.logger.error(f"JSON解析失败: {str(e)}, 原始文本: {intent_analysis_text}") + return jsonify({ + 'code': 500, + 'message': 'AI返回的格式有误,请重试', + 'data': None + }) + except ValueError as e: + current_app.logger.error(f"数据验证失败: {str(e)}") + return jsonify({ + 'code': 500, + 'message': str(e), + 'data': None + }) + + except Exception as e: + current_app.logger.error(f"意图分析失败: {str(e)}") + return jsonify({ + 'code': 500, + 'message': '意图分析过程出错,请重试', + 'data': None + }) + + # 第二阶段:领域专家提示生成 + domain_expert_templates = { + "技术": """你是一位专业的技术领域提示工程师。基于以下意图分析,生成一个专业的技术任务提示词: + +意图分析: +{analysis} + +请生成的提示词包含: +1. 明确的技术背景和上下文 +2. 具体的技术要求和规范 +3. 性能和质量标准 +4. 技术约束条件 +5. 预期交付成果 +6. 评估标准 + +使用专业技术术语,确保提示词的可执行性和可验证性。""", + + "创意": """你是一位专业的创意领域提示工程师。基于以下意图分析,生成一个创意设计提示词: + +意图分析: +{analysis} + +请生成的提示词包含: +1. 创意方向和灵感来源 +2. 风格和氛围要求 +3. 目标受众定义 +4. 设计元素规范 +5. 创意表现形式 +6. 评估标准 + +使用专业创意术语,确保提示词的创新性和可执行性。""", + + "分析": """你是一位专业的数据分析提示工程师。基于以下意图分析,生成一个数据分析提示词: + +意图分析: +{analysis} + +请生成的提示词包含: +1. 分析目标和范围 +2. 数据要求和规范 +3. 分析方法和工具 +4. 输出格式要求 +5. 关键指标定义 +6. 质量控制标准 + +使用专业分析术语,确保提示词的科学性和可操作性。""", + + "咨询": """你是一位专业的咨询领域提示工程师。基于以下意图分析,生成一个咨询服务提示词: + +意图分析: +{analysis} + +请生成的提示词包含: +1. 咨询问题界定 +2. 背景信息要求 +3. 分析框架设定 +4. 建议输出格式 +5. 实施考虑因素 +6. 效果评估标准 + +使用专业咨询术语,确保提示词的专业性和实用性。""" + } + + # 选择领域专家模板 + expert_prompt = domain_expert_templates.get( + intent_analysis['core_intent'], + """你是一位专业的通用领域提示工程师。基于以下意图分析,生成一个专业的提示词: + +意图分析: +{analysis} + +请生成的提示词包含: +1. 明确的目标定义 +2. 具体要求和规范 +3. 质量标准 +4. 约束条件 +5. 预期输出 +6. 评估标准 + +确保提示词的清晰性和可执行性。""" + ) + + try: + # 生成最终提示词 + final_response = client.chat.completions.create( + model="deepseek-chat", + messages=[ + {"role": "system", "content": expert_prompt.format( + analysis=json.dumps(intent_analysis, ensure_ascii=False, indent=2) + )}, + {"role": "user", "content": user_input} + ], + temperature=0.7 + ) + + generated_prompt = final_response.choices[0].message.content.strip() + + except Exception as e: + current_app.logger.error(f"生成提示词失败: {str(e)}") + return jsonify({ + 'code': 500, + 'message': '生成提示词过程出错', + 'data': None + }) + + try: + # 保存到数据库 + prompt = Prompt( + input_text=user_input, + generated_text=generated_prompt, + wx_user_id=uid, + intent_analysis=json.dumps(intent_analysis, ensure_ascii=False), + created_at=datetime.utcnow() + ) + db.session.add(prompt) + db.session.commit() + + except Exception as e: + current_app.logger.error(f"保存到数据库失败: {str(e)}") + db.session.rollback() + # 即使保存失败,也返回生成的结果 + + return jsonify({ + 'code': 200, + 'message': 'success', + 'data': { + 'prompt_id': prompt.id if 'prompt' in locals() else None, + 'intent_analysis': intent_analysis, + 'generated_prompt': generated_prompt, + 'created_at': prompt.created_at.strftime('%Y-%m-%d %H:%M:%S') if 'prompt' in locals() else None + } + }) + + except Exception as e: + current_app.logger.error(f"生成专家提示词失败: {str(e)}") + return jsonify({ + 'code': 500, + 'message': str(e), + 'data': None + }) + # ... 其他路由保持不变,但要把 @app 改成 @main_bp ... \ No newline at end of file diff --git a/flask_prompt_master/static/css/style.css b/flask_prompt_master/static/css/style.css new file mode 100644 index 0000000..1477de7 --- /dev/null +++ b/flask_prompt_master/static/css/style.css @@ -0,0 +1,18 @@ +.prompt-container { + display: flex; + flex-wrap: wrap; + gap: 16px; + padding: 20px; + max-width: 1200px; + margin: 0 auto; +} + +.prompt-card { + width: calc((100% - 64px) / 5); + min-width: 180px; + margin: 0; + background: #fff; + border-radius: 8px; + padding: 12px; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); +} \ No newline at end of file diff --git a/requirements-test.txt b/requirements-test.txt new file mode 100644 index 0000000..a5ece6a --- /dev/null +++ b/requirements-test.txt @@ -0,0 +1,3 @@ +pytest==7.4.0 +pytest-cov==4.1.0 +requests==2.31.0 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..16a7779 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +flask==2.0.1 +flask-cors==3.0.10 \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..c932854 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,24 @@ +import pytest +import os +import sys + +# 添加项目根目录到Python路径 +sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) + +# 测试数据库配置 +@pytest.fixture(scope="session") +def test_db(): + # 这里可以设置测试数据库的配置 + return { + "host": "localhost", + "database": "test_prompt_template", + "user": "test_user", + "password": "test_password" + } + +# 测试客户端配置 +@pytest.fixture(scope="session") +def test_client(): + from flask_prompt_master import create_app + app = create_app('testing') + return app.test_client() \ No newline at end of file diff --git a/tests/test_api.py b/tests/test_api.py new file mode 100644 index 0000000..59b2d5a --- /dev/null +++ b/tests/test_api.py @@ -0,0 +1,173 @@ +import pytest +import requests +from datetime import datetime +import json + +# 测试配置 +class TestConfig: + BASE_URL = "http://localhost:5000/api/v1" + TEST_TOKEN = "test_token_123" # 测试用token + HEADERS = { + "Authorization": f"Bearer {TEST_TOKEN}", + "Content-Type": "application/json" + } + +# 测试夹具 +@pytest.fixture +def api_client(): + class APIClient: + def __init__(self): + self.base_url = TestConfig.BASE_URL + self.headers = TestConfig.HEADERS + + def get(self, endpoint, params=None): + url = f"{self.base_url}{endpoint}" + return requests.get(url, headers=self.headers, params=params) + + def post(self, endpoint, data): + url = f"{self.base_url}{endpoint}" + return requests.post(url, headers=self.headers, json=data) + + def put(self, endpoint, data): + url = f"{self.base_url}{endpoint}" + return requests.put(url, headers=self.headers, json=data) + + def delete(self, endpoint): + url = f"{self.base_url}{endpoint}" + return requests.delete(url, headers=self.headers) + + return APIClient() + +# 模板管理接口测试 +class TestTemplateAPI: + def test_get_template_list(self, api_client): + """测试获取模板列表""" + response = api_client.get("/templates") + assert response.status_code == 200 + data = response.json() + assert "data" in data + assert "templates" in data["data"] + + def test_get_template_with_filters(self, api_client): + """测试带过滤条件的模板列表""" + params = { + "category": "软件开发", + "industry": "互联网", + "page": 1, + "size": 10 + } + response = api_client.get("/templates", params=params) + assert response.status_code == 200 + data = response.json() + assert "current_page" in data["data"] + assert data["data"]["current_page"] == 1 + + def test_create_template(self, api_client): + """测试创建模板""" + template_data = { + "name": "测试模板", + "description": "这是一个测试模板", + "category": "软件开发", + "industry": "互联网", + "profession": "开发工程师", + "sub_category": "后端开发", + "system_prompt": "你是一个专业的后端开发工程师..." + } + response = api_client.post("/templates", template_data) + assert response.status_code == 200 + data = response.json() + assert "id" in data["data"] + return data["data"]["id"] + + def test_get_template_detail(self, api_client): + """测试获取单个模板详情""" + # 先创建一个模板 + template_id = self.test_create_template(api_client) + response = api_client.get(f"/templates/{template_id}") + assert response.status_code == 200 + data = response.json() + assert data["data"]["name"] == "测试模板" + + def test_update_template(self, api_client): + """测试更新模板""" + # 先创建一个模板 + template_id = self.test_create_template(api_client) + update_data = { + "name": "更新后的模板", + "description": "这是更新后的描述" + } + response = api_client.put(f"/templates/{template_id}", update_data) + assert response.status_code == 200 + + # 验证更新结果 + response = api_client.get(f"/templates/{template_id}") + assert response.json()["data"]["name"] == "更新后的模板" + + def test_delete_template(self, api_client): + """测试删除模板""" + # 先创建一个模板 + template_id = self.test_create_template(api_client) + response = api_client.delete(f"/templates/{template_id}") + assert response.status_code == 200 + + # 验证删除结果 + response = api_client.get(f"/templates/{template_id}") + assert response.status_code == 404 + +# 分类管理接口测试 +class TestCategoryAPI: + def test_get_categories(self, api_client): + """测试获取分类列表""" + response = api_client.get("/categories") + assert response.status_code == 200 + data = response.json() + assert "categories" in data["data"] + + def test_create_category(self, api_client): + """测试创建分类""" + category_data = { + "name": "测试分类", + "icon": "test-icon", + "description": "这是一个测试分类" + } + response = api_client.post("/categories", category_data) + assert response.status_code == 200 + +# 搜索接口测试 +class TestSearchAPI: + def test_search_templates(self, api_client): + """测试搜索模板""" + params = { + "keyword": "开发", + "category": "软件开发" + } + response = api_client.get("/search/templates", params=params) + assert response.status_code == 200 + data = response.json() + assert "results" in data["data"] + +# 统计接口测试 +class TestStatisticsAPI: + def test_get_template_statistics(self, api_client): + """测试获取模板统计信息""" + response = api_client.get("/statistics/templates") + assert response.status_code == 200 + data = response.json() + assert "total_templates" in data["data"] + assert "category_distribution" in data["data"] + +# 错误处理测试 +class TestErrorHandling: + def test_invalid_token(self, api_client): + """测试无效token""" + api_client.headers["Authorization"] = "Bearer invalid_token" + response = api_client.get("/templates") + assert response.status_code == 401 + + def test_invalid_request(self, api_client): + """测试无效请求""" + invalid_data = { + "name": "" # 空名称,应该触发验证错误 + } + response = api_client.post("/templates", invalid_data) + assert response.status_code == 400 \ No newline at end of file