"""DeepSeek HTTP calls; callers retain their streaming/compression/followup deadlines.""" import json import re import requests from requests.exceptions import RequestException, Timeout from .config import get_setting def post_completion(body, *, timeout, stream=False): return requests.post( get_setting('MODEL_URL'), headers={'Authorization': f"Bearer {get_setting('DEEPSEEK_API_KEY')}", 'Content-Type': 'application/json'}, json=body, stream=stream, timeout=timeout, ) EN_COMPRESS_RULE = '原文是英文,压缩后的结果必须仍然使用英文(English),不得翻译成中文。' def has_chinese(t): return any(('一' <= ch <= '龥' for ch in t)) def compress_answer(text, limit=get_setting('MAX_ANSWER_CHARS')): """回答超长时,让模型压缩到规定字数内;失败则原样返回""" if len(text) <= limit: return text r = None try: body = {'model': get_setting('MODEL_NAME'), 'messages': [{'role': 'system', 'content': (EN_COMPRESS_RULE if has_chinese(text) is False else '') + f'你是文字精简助手。把用户给的内容压缩到 {limit} 字以内(必须严格满足,超出即为不合格),必须保留所有数字、金额、时效和渠道名称,删除重复表述、客套话和次要说明,结构保持不变。'}, {'role': 'user', 'content': text}], 'stream': False, 'max_tokens': 800} r = post_completion(body, timeout=(5, 30)) if r.status_code == 200: short = r.json()['choices'][0]['message']['content'].strip() print(f'[压缩] {len(text)} 字 -> {len(short)} 字') return short print(f'[压缩失败] 状态码 {r.status_code}') except Exception as e: print(f'[压缩异常] {e}') finally: if r is not None: r.close() return text def gen_followups(user_msg, answer_text): """根据本轮问答,生成 3 个客户可能接着问的问题(失败返回空列表,不影响主流程)""" if not get_setting('DEEPSEEK_API_KEY'): return [] r = None try: body = {'model': get_setting('MODEL_NAME'), 'messages': [{'role': 'system', 'content': '你是物流客服助手。根据用户问题和你的回答,生成3个客户最可能接着问的简短问题(每个不超过20字),只输出JSON字符串数组,不要任何解释。'}, {'role': 'user', 'content': f'用户问:{user_msg}\n你的回答:{answer_text[:500]}\n\n请生成3个追问:'}], 'stream': False, 'max_tokens': 200} r = post_completion(body, timeout=(5, 15)) if r.status_code != 200: return [] text = r.json()['choices'][0]['message']['content'].strip() m = re.search('\\[.*\\]', text, re.S) if m: arr = json.loads(m.group(0)) return [str(x).strip() for x in arr if str(x).strip()][:3] except Exception: pass finally: if r is not None: r.close() return []