diff --git a/app/config/ai_configs.py b/app/config/ai_configs.py index 6bba938..2db2600 100644 --- a/app/config/ai_configs.py +++ b/app/config/ai_configs.py @@ -2,11 +2,6 @@ from app.config.env import env ai_configs = { # /*---------------------------------------local-------------------------------------------*/ - "local": { - "model": "deepseek-r1-distill-qwen-7b", - "url": "http://127.0.0.1:1234/v1/chat/completions", - "key": env.llm_key_local - }, "local_glm": { "model": "glm-4-9b-0414", "url": "http://127.0.0.1:1234/v1/chat/completions", @@ -17,38 +12,12 @@ ai_configs = { "url": "http://127.0.0.1:1234/v1/embeddings", "key": env.llm_key_local }, - # /*---------------------------------------deepseek-------------------------------------------*/ - 'deepseek-v3': { - 'model': 'deepseek-chat', - 'url': 'https://api.deepseek.com/chat/completions', - 'key': env.llm_key_deepseek, - }, - 'deepseek-r1': { - 'model': 'deepseek-reasoner', - 'url': 'https://api.deepseek.com/chat/completions', - 'key': env.llm_key_deepseek, - }, # /*---------------------------------------huoshan-------------------------------------------*/ - 'huoshan-deepseek-v3': { - 'model': 'deepseek-v3-250324', - 'url': 'https://ark.cn-beijing.volces.com/api/v3/chat/completions', - 'key': env.llm_key_huoshan, - }, - 'huoshan-deepseek-r1': { - 'model': 'deepseek-r1-distill-qwen-7b-250120', - 'url': 'https://ark.cn-beijing.volces.com/api/v3/chat/completions', - 'key': env.llm_key_huoshan, - }, 'huoshan-doubao': { 'model': 'doubao-1-5-lite-32k-250115', 'url': 'https://ark.cn-beijing.volces.com/api/v3/chat/completions', 'key': env.llm_key_huoshan, }, - 'huoshan-think-pro': { - 'model': 'doubao-1-5-thinking-pro-250415', - 'url': 'https://ark.cn-beijing.volces.com/api/v3/chat/completions', - 'key': env.llm_key_huoshan, - }, 'huoshan-doubao-seed': { 'model': 'doubao-seed-1-6-250615', 'url': 'https://ark.cn-beijing.volces.com/api/v3/chat/completions', @@ -59,12 +28,6 @@ ai_configs = { 'url': 'https://ark.cn-beijing.volces.com/api/v3/chat/completions', 'key': env.llm_key_huoshan, }, - - 'huoshan-embedding-240715': { - "model": 'doubao-embedding-text-240715', - "url": 'https://ark.cn-beijing.volces.com/api/v3/embeddings', - 'key': env.llm_key_huoshan, - }, # /*---------------------------------------bailian-------------------------------------------*/ 'bailian-qwen-turbo': { 'model': 'qwen-turbo', @@ -76,6 +39,11 @@ ai_configs = { 'url': 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions', 'key': env.llm_key_bailian, }, + 'bailian-qwen3.6-plus': { + 'model': 'qwen3.6-plus', + 'url': 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions', + 'key': env.llm_key_bailian, + }, 'bailian-embedding': { 'model': 'text-embedding-v4', 'url': 'https://dashscope.aliyuncs.com/compatible-mode/v1/embeddings', diff --git a/app/routes.py b/app/routes.py index 3a0c41c..85cccc1 100644 --- a/app/routes.py +++ b/app/routes.py @@ -6,6 +6,7 @@ from app.controller.add_graph_proxy_route import add_graph_proxy_route from app.controller.add_test_route import add_test_route from app.model.LlmDemoMdel import LlmDemoModel from app.model.ResumeTemplateModel import ResumeTemplateModel +from app.utils.add_llm_routes import add_llm_routes from app.utils.add_model_routes import add_model_routes from app.utils.next_id import add_next_id_route @@ -19,6 +20,10 @@ routes = [ add_next_id_route, # 生成ID接口 add_file_route, # 文件上传接口 + lambda app: add_llm_routes(app, 'huoshan-doubao'), + lambda app: add_llm_routes(app, 'doubao-vision-lite'), + lambda app: add_llm_routes(app, 'bailian-qwen3.6-plus'), + lambda app: add_model_routes(app,LlmDemoModel,'/llm_demo'), # LlmDemo 测试用户模块 lambda app: add_model_routes(app,ResumeTemplateModel,'/llm_resume_template'), # 简历模板 ] diff --git a/app/utils/add_llm_routes.py b/app/utils/add_llm_routes.py new file mode 100644 index 0000000..dac66ed --- /dev/null +++ b/app/utils/add_llm_routes.py @@ -0,0 +1,61 @@ +import httpx +from fastapi import APIRouter, Request, HTTPException, FastAPI +from fastapi.responses import StreamingResponse + +from app.config.ai_configs import ai_configs + + +async def proxy_openai_request(request: Request, config_key: str): + """ + 通用代理函数:将请求转发至指定的上游模型服务 + """ + if config_key not in ai_configs: + raise HTTPException(status_code=404, detail=f"Config {config_key} not found") + + config = ai_configs[config_key] + target_url = config["url"] + api_key = config["key"] + real_model_name = config["model"] + + # 1. 获取原始请求体并修改模型名称 + body = await request.json() + body["model"] = real_model_name # 强制替换为上游真正识别的模型名 + + # 2. 准备请求头 + headers = { + "Authorization": f"Bearer {api_key}", + "Content-Type": "application/json" + } + + client = httpx.AsyncClient() + + # 3. 处理流式响应 (OpenAI 协议的关键) + if body.get("stream", False): + async def stream_generator(): + async with client.stream("POST", target_url, json=body, headers=headers, timeout=60.0) as response: + async for chunk in response.aiter_bytes(): + yield chunk + await client.aclose() + + return StreamingResponse(stream_generator(), media_type="text/event-stream") + + # 4. 处理非流式响应 + else: + response = await client.post(target_url, json=body, headers=headers, timeout=60.0) + await client.aclose() + return response.json() + + +def add_llm_routes(app: FastAPI, config_name: str): + """ + 动态生成路由的辅助函数 + """ + # 自动根据配置判断是 chat 还是 embeddings 路径 + is_embedding = "embedding" in config_name or "embeddings" in ai_configs[config_name]["url"] + path = "/v1/embeddings" if is_embedding else "/v1/chat/completions" + + @app.post(f"/{config_name}{path}") + async def dynamic_proxy(request: Request): + return await proxy_openai_request(request, config_name) + + print(f"🚀 Proxy LLM route: /{config_name}{path}")