From e2f5aef205a91d7f301ca9e08f0b0417b2fbe25d Mon Sep 17 00:00:00 2001 From: aaron <> Date: Tue, 29 Apr 2025 22:52:16 +0800 Subject: [PATCH] update --- cryptoai/agents/crypto_agent.py | 5 +- cryptoai/agents/gold_agent.py | 5 +- .../__pycache__/deepseek_api.cpython-313.pyc | Bin 10985 -> 13287 bytes cryptoai/api/deepseek_api.py | 66 ++++++++++++++++-- cryptoai/routes/{routes.py => agent.py} | 19 ++++- cryptoai/routes/fastapi_app.py | 6 +- cryptoai/utils/token_usage.py | 12 +--- 7 files changed, 85 insertions(+), 28 deletions(-) rename cryptoai/routes/{routes.py => agent.py} (51%) diff --git a/cryptoai/agents/crypto_agent.py b/cryptoai/agents/crypto_agent.py index 1240195..f77c4ca 100644 --- a/cryptoai/agents/crypto_agent.py +++ b/cryptoai/agents/crypto_agent.py @@ -56,10 +56,7 @@ class CryptoAgent: test_mode=self.okx_config['test_mode'] ) - self.deepseek_api = DeepSeekAPI( - api_key=self.deepseek_config['api_key'], - model=self.deepseek_config['model'] - ) + self.deepseek_api = DeepSeekAPI() # 初始化数据处理器 self.data_processor = DataProcessor(storage_path=self.data_config['storage_path']) diff --git a/cryptoai/agents/gold_agent.py b/cryptoai/agents/gold_agent.py index 2dc8fac..1e851a3 100644 --- a/cryptoai/agents/gold_agent.py +++ b/cryptoai/agents/gold_agent.py @@ -52,10 +52,7 @@ class GoldAgent: api_key=self.alltick_config['api_key'] ) - self.deepseek_api = DeepSeekAPI( - api_key=self.deepseek_config['api_key'], - model=self.deepseek_config['model'] - ) + self.deepseek_api = DeepSeekAPI() # 初始化数据处理器 self.data_processor = DataProcessor(storage_path=os.path.join(self.data_config['storage_path'], 'gold')) diff --git a/cryptoai/api/__pycache__/deepseek_api.cpython-313.pyc b/cryptoai/api/__pycache__/deepseek_api.cpython-313.pyc index d2dd4621da9f9f6e4e1e41180901c9eb4ca4943c..25f5b5e633d329467e9fb3a71d9d1fa2b37b58e2 100644 GIT binary patch delta 3959 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 delta 2071 zcma)7O>7fK6y90yu78r)`Lko(7&ajg7H|@iA0VYoBK|~MrIb~GsusrBlf=RCF0*U7 zK`kkl3aRM zOqnTWj~U3Rrjk>~6jMz}OUe>qnwd0%Kn=kchA#qNOD<@(=0av$E}VmXu4PPC!Q$4n zPZ^7v(WaeNGxm(X3c{d_ZrYK}+O{x#-WIbU)!|7+L1!ynHak6f%-m*nL0H}Jp;gU{ zH=VYd3D&Wo87a|nj8faA^zzK_&8X*>inZ@`Wb-E`Y6o*#kn2_8 z5_<(VO1V03iSY6Fi_}JcLZysZ%;;ix*>Y{7`a`WE&Tg7iDsy z@qOwV2}3;=t#Xk%{8;Z>7iRDvEv!(_H>+f*B2b~#W&lpT>@Iq4ycL^9@c^U<%IF>P z1fFjn!YKd;8&!wF(y$OI9!sbAiM|ByNq3SD8++5g%Pq4gj5TF%b6uY#r}=yOPBOz+ z_3Y#s)Kccl)sj#dPJRtkOo`(;_cG5gYBmP|ec^|}f7J(*7y^3(zzG3h95`5-5B8lT zykYfyA@6_Q3tk(=Q3azZ|GlxXF>7dBnx&f`9ypT3x-$&SAf7J=?;aZcbl^4e4ZlBd zuR{ll2+x-*G;bH&MHX({*tMbddi_J{SJj$3pE+a@%wy3im8%Qv0RM8|*!e4HHN-|? z+R`J~&o9-JjUmm8_5TR-%>I7OKPaEuzqUGw+OGnL5R`7-YbwZToid?V(9eFBl~Qfl zX5MjKl-262?1D(hpRGDOjCQ;lMa~u~HF_M|-LJ?LvZfKRHb%rR3qFD@Jb{RD3o_5p zH2VNIO0iI>cx~g?4FBG|f_VT5zLPmferP<%+?5Y${Tzn&Zr(UKoV1rzZm*9zZ z;EB#GTQrlMxRfa_7F_<>NLIr-7@hp#$draX!?yEOc1Qe8T%JWJAuJ(W=d;=LgpNyW zV201A2l#k6Ls0pTr5}}}PnB)z!S%os38t@){)N-iiN<<1P7?a2hS4Ep%keVHCiwjW zyIRJPwGCmCZyz1q;~D=1_d0@iV?syZzob^7ud`b~!%lOGd}UPUpN}4iRRbjPhlJ>9 F{0FOL(}4g0 diff --git a/cryptoai/api/deepseek_api.py b/cryptoai/api/deepseek_api.py index 79caa77..7abe170 100644 --- a/cryptoai/api/deepseek_api.py +++ b/cryptoai/api/deepseek_api.py @@ -6,6 +6,8 @@ import time import logging import datetime +from cryptoai.utils.config_loader import ConfigLoader + # 配置日志 logging.basicConfig( level=logging.INFO, @@ -19,7 +21,7 @@ logging.basicConfig( class DeepSeekAPI: """DeepSeek API交互类,用于进行大语言模型调用""" - def __init__(self, api_key: str, model: str = "deepseek-moe-16b-chat"): + def __init__(self): """ 初始化DeepSeek API @@ -27,12 +29,16 @@ class DeepSeekAPI: api_key: DeepSeek API密钥 model: 使用的模型名称 """ - self.api_key = api_key - self.model = model + + config_loader = ConfigLoader() + self.deepseek_config = config_loader.get_deepseek_config() + + self.api_key = self.deepseek_config['api_key'] + self.model = self.deepseek_config['model'] self.base_url = "https://api.deepseek.com/v1" self.headers = { "Content-Type": "application/json", - "Authorization": f"Bearer {api_key}" + "Authorization": f"Bearer {self.api_key}" } # Token 使用统计 @@ -45,6 +51,58 @@ class DeepSeekAPI: # 创建日志记录器 self.logger = logging.getLogger("DeepSeekAPI") + + def streaming_call(self, user_prompt: str): + """ + 流式调用DeepSeek API + """ + + system_prompt = "你是一个专业的区块链分析高手" + + try: + endpoint = f"{self.base_url}/chat/completions" + payload = { + "model": self.model, + "messages": [{"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt}], + "stream": True + } + + response = requests.post(endpoint, headers=self.headers, json=payload, stream=True) + response.raise_for_status() + + for line in response.iter_lines(): + if line: + # 解码二进制数据为字符串 + line = line.decode('utf-8') + + # 跳过空行和心跳检查行 + if not line or line == "data: [DONE]": + continue + + # 移除 "data: " 前缀 + if line.startswith("data: "): + line = line[6:] + + try: + # 解析JSON数据 + data = json.loads(line) + + # 提取content内容 + if (data.get("choices") and + len(data["choices"]) > 0 and + data["choices"][0].get("delta") and + data["choices"][0]["delta"].get("content")): + + content = data["choices"][0]["delta"]["content"] + yield content + except json.JSONDecodeError as e: + self.logger.error(f"解析JSON时出错: {e}, 原始数据: {line}") + continue + + except Exception as e: + self.logger.error(f"流式调用DeepSeek API时出错: {e}") + raise e + def call_model(self, prompt: str, system_prompt: str = None, task_type: str = "未知任务", symbol: str = "未知", temperature: float = 0.2, max_tokens: int = 2000) -> Tuple[Dict[str, Any], Dict[str, Any]]: """ diff --git a/cryptoai/routes/routes.py b/cryptoai/routes/agent.py similarity index 51% rename from cryptoai/routes/routes.py rename to cryptoai/routes/agent.py index 124a0cb..3caeead 100644 --- a/cryptoai/routes/routes.py +++ b/cryptoai/routes/agent.py @@ -14,6 +14,21 @@ import logging from cryptoai.api.deepseek_api import DeepSeekAPI from cryptoai.utils.config_loader import ConfigLoader - +from fastapi.responses import StreamingResponse # 创建路由 -router = APIRouter(prefix="/api", tags=["加密AI接口"]) \ No newline at end of file +router = APIRouter() + +class ChatRequest(BaseModel): + user_prompt: str + + +@router.post("/chat") +async def chat(request: ChatRequest): + """ + 聊天接口 + """ + + deepseek_api = DeepSeekAPI() + response = deepseek_api.streaming_call(request.user_prompt) + + return StreamingResponse(response, media_type="text/plain") diff --git a/cryptoai/routes/fastapi_app.py b/cryptoai/routes/fastapi_app.py index 62f50ca..879e4f6 100644 --- a/cryptoai/routes/fastapi_app.py +++ b/cryptoai/routes/fastapi_app.py @@ -15,7 +15,7 @@ from fastapi.responses import JSONResponse import time from typing import Dict, Any -from cryptoai.routes.routes import router as api_router +from cryptoai.routes.agent import router as agent_router # 配置日志 logging.basicConfig( @@ -45,7 +45,7 @@ app.add_middleware( ) # 添加API路由 -app.include_router(api_router) +app.include_router(agent_router, prefix="/agent") # 请求计时中间件 @app.middleware("http") @@ -103,7 +103,7 @@ def start(): "cryptoai.routes.fastapi_app:app", host=host, port=port, - reload=False # 生产环境设为False + reload=True # 生产环境设为False ) if __name__ == "__main__": diff --git a/cryptoai/utils/token_usage.py b/cryptoai/utils/token_usage.py index 99dd061..4c096c7 100644 --- a/cryptoai/utils/token_usage.py +++ b/cryptoai/utils/token_usage.py @@ -24,17 +24,7 @@ def get_deepseek_api() -> DeepSeekAPI: """ 获取已配置的DeepSeekAPI实例 """ - config_loader = ConfigLoader() - deepseek_config = config_loader.get_deepseek_config() - - if not deepseek_config or 'api_key' not in deepseek_config: - print("错误: 未找到DeepSeek API配置或API密钥") - sys.exit(1) - - return DeepSeekAPI( - api_key=deepseek_config['api_key'], - model=deepseek_config.get('model', 'deepseek-moe-16b-chat') - ) + return DeepSeekAPI() def show_token_usage_stats():