chore: 清理未使用的代码文件和备份
- 删除 backend/main.py (已由 app/main.py 替代) - 删除 backend/api/ 和 backend/core/ (已由 app/api/ 和 app/core/ 替代) - 删除 backend/static 符号链接 - 删除前端测试/调试页面 - 删除未引用的 vendor 子目录 (element-plus/, vue/, axios/) - 删除所有 .bak 备份文件
This commit is contained in:
@@ -1,118 +0,0 @@
|
||||
"""
|
||||
NVIDIA 专用 LLM 客户端(fixed configuration)
|
||||
使用 OpenAI 兼容接口调用 stepfun-ai/step-3.5-flash
|
||||
"""
|
||||
|
||||
import requests
|
||||
import json
|
||||
from typing import Optional
|
||||
|
||||
class LLMError(Exception):
|
||||
pass
|
||||
|
||||
# 固定配置(你的可用 key)
|
||||
CONFIG = {
|
||||
"base_url": "https://integrate.api.nvidia.com/v1",
|
||||
"api_key": "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",
|
||||
"model": "stepfun-ai/step-3.5-flash",
|
||||
}
|
||||
|
||||
def call_llm(
|
||||
prompt: str,
|
||||
system_prompt: str = "你是一个专业的内容创作助手。",
|
||||
temperature: float = 0.7,
|
||||
max_tokens: int = 2000,
|
||||
stream: bool = False,
|
||||
) -> str:
|
||||
"""
|
||||
调用 NVIDIA LLM 生成文本
|
||||
"""
|
||||
endpoint = f"{CONFIG['base_url'].rstrip('/')}/chat/completions"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {CONFIG['api_key']}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
payload = {
|
||||
"model": CONFIG["model"],
|
||||
"messages": [
|
||||
{"role": "system", "content": system_prompt},
|
||||
{"role": "user", "content": prompt}
|
||||
],
|
||||
"temperature": temperature,
|
||||
"max_tokens": max_tokens,
|
||||
"stream": stream,
|
||||
}
|
||||
|
||||
try:
|
||||
resp = requests.post(endpoint, json=payload, headers=headers, timeout=120, stream=stream)
|
||||
if resp.status_code != 200:
|
||||
raise LLMError(f"HTTP {resp.status_code}: {resp.text[:200]}")
|
||||
if stream:
|
||||
full = []
|
||||
for line in resp.iter_lines():
|
||||
if not line:
|
||||
continue
|
||||
if line.startswith(b'data: '):
|
||||
data = line[6:]
|
||||
if data == b'[DONE]':
|
||||
break
|
||||
try:
|
||||
chunk = json.loads(data)
|
||||
delta = chunk['choices'][0]['delta']
|
||||
# 支持 reasoning_content 或 reasoning 字段
|
||||
if 'reasoning_content' in delta and delta['reasoning_content']:
|
||||
full.append(delta['reasoning_content'])
|
||||
if 'content' in delta and delta['content']:
|
||||
full.append(delta['content'])
|
||||
except Exception:
|
||||
continue
|
||||
return "".join(full)
|
||||
else:
|
||||
data = resp.json()
|
||||
msg = data["choices"][0]["message"]
|
||||
content = msg.get('content') or msg.get('reasoning') or msg.get('reasoning_content')
|
||||
return content.strip() if content else ''
|
||||
except requests.RequestException as e:
|
||||
raise LLMError(f"Request failed: {e}")
|
||||
|
||||
def expand_content_with_llm(topic: dict, section_title: str, section_content: str, context: str = "") -> str:
|
||||
"""扩写大纲章节,返回包含 ## 标题的完整 Markdown"""
|
||||
prompt = f"""你是一个专业的内容创作者。请将以下大纲扩展为完整的文章章节。
|
||||
|
||||
# 选题信息
|
||||
- 标题:{topic.get('title')}
|
||||
- 领域:{topic.get('field')}
|
||||
- 核心观点:{topic.get('core_concept', '')}
|
||||
- 受众痛点:{topic.get('audience_pain', '')}
|
||||
- 独特视角:{topic.get('unique_angle', '')}
|
||||
|
||||
# 当前章节
|
||||
## {section_title}
|
||||
{section_content}
|
||||
|
||||
# 要求
|
||||
- 以 `## {section_title}` 作为章节标题开头
|
||||
- 字数:300-500字
|
||||
- 风格:客观、专业、易懂
|
||||
- 使用 Markdown 格式
|
||||
- 包含具体数据或案例(如果有)
|
||||
- 保持与整体文章调性一致
|
||||
|
||||
直接输出完整的 Markdown 章节(包括 ## 标题和正文段落)。"""
|
||||
if context:
|
||||
prompt = f"# 参考资料\n{context}\n\n{prompt}"
|
||||
|
||||
try:
|
||||
result = call_llm(prompt, temperature=0.8, max_tokens=2000)
|
||||
return result.strip()
|
||||
except Exception as e:
|
||||
return f"## {section_title}\n\n(LLM 调用失败:{e},请手动补充)"
|
||||
|
||||
# 测试
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
print(f"[nvidia_client] 使用模型: {CONFIG['model']}")
|
||||
resp = call_llm("你好,请用一句话介绍你自己。", max_tokens=50)
|
||||
print(f"[nvidia_client] 响应: {resp}")
|
||||
except Exception as e:
|
||||
print(f"[nvidia_client] 错误: {e}")
|
||||
Reference in New Issue
Block a user