52 私有链接
这段内容描述了一个基于NAS的简易AI助手项目。它使用NAS上的funasr进行语音转文字,然后通过Dify调用在线LLM(如硅基流动的qwen2.5-7b和Gemini)解析文本并生成操作命令或回答。对于时间相关问题,使用Gemini搜索;对于通识问题,优先使用响应速度快的Gemini模型。最后,通过Python程序执行命令或进行语音回复。该项目还考虑了Spotify API调用、键盘快捷键以及屏幕内容识别等问题,并提供了一个PC操作命令序列转换的上下文,用于规范化LLM输出的指令。
用户分享了一个免费的图床工具,它基于一个网上找到的京东API接口,代码开源。用户可以将代码部署到Cloudflare Workers上,并提醒不要上传违规图片。该工具自带接口ping功能,如果不可用会在页面提示。同时,用户还在寻求大家在GitHub上点赞支持。
这段内容主要介绍了如何使用 curl
命令调用 AI 模型的函数调用 (Function Calling) 功能。通过 curl
发送带有特定格式的 JSON 请求,可以指示 AI 模型执行预定义的函数,并返回结构化的数据。文章提供了几个具体的例子,包括格式化输出用户心情、时间、天气,提取图片中的特定文本,以及从自然语言输入中提取记账信息。函数调用允许 AI 模型输出格式化的信息,方便程序处理,但也存在不确定性和潜在风险,需要通过数据验证和错误检查来解决。总的来说,函数调用为 AI 模型提供了一个标准化的接口,提高了开发效率。
详细的教程
这段内容主要讲述了如何利用一台境外VPS搭建一个安全、稳定的代理服务器,并提供订阅转换服务。主要步骤包括:购买域名并配置DNS解析,购买VPS并进行安全加固,申请TLS证书,搭建hysteria2和vless+vision两种代理协议,使用x-ui面板管理节点,搭建sub-store提供订阅服务,以及使用Nginx进行流量分流。教程强调了安全性和稳定性的重要性,并提供了详细的配置步骤和相关命令,适合有一定Linux基础的用户参考。
Hugging Face 提供两个主要产品:HuggingChat,一个在线对话平台,使用开源模型;以及 Serverless Inference API,一个兼容 OpenAI 格式的 API,可供调用多种模型。API 每天提供 1000 次免费调用,但速度较慢。
字节跳动豆包上线了全新的端到端实时对话功能
目前中文的实际体验要比 ChatGPT 的 Advanced Voice Mode 更加震撼!
普通模型需要指定完整思维过程的提示词
o1等思维链模型,需要的是精准描述要求,避免任何可能的偏差,并提供充足的素材库
算是两个不同的提示词方向
这个项目是一个名为 Gemini Next Chat 的应用,可以让你免费一键部署私人的 Gemini 应用。它支持 Gemini 1.5 Pro、Gemini 1.5 Flash、Gemini Pro 和 Gemini Pro Vision 等模型,并提供跨平台客户端。该应用具有简洁的界面,支持图像识别、语音对话、插件(如网页搜索、阅读器等),以及多模态模型,能理解图片、视频、音频和部分文本文件。它还支持本地存储、隐私安全,以及多种部署方式,包括 Vercel 一键部署和 Docker 部署。
支持alt+A、shift+cmd+4 等工具截取图片,或输入图片链接。
这篇文章介绍了作者优化后的一个浏览器AI总结脚本。原脚本在总结时格式不佳,作者基于yangtb2024的脚本进行了改进,增加了导出功能和可视化设置。作者还分享了优化后的脚本文件,并提到提示词也进行了优化。最后,文章还展示了一些用户对该脚本的积极反馈。
import requests
import json
import time
import uuid
import re
import logging
import os
class ThinkBuddyClient:
def __init__(self, api_key):
self.api_key = api_key # Pass the API key during initialization
self.id_token = None
self.refresh_token = None
self.local_id = None
self.expiration_time = 0 # token过期时间戳
self.logger = self._setup_logger()
def _setup_logger(self):
log_dir = "./logs/"
os.makedirs(log_dir, exist_ok=True)
today_str = time.strftime("%Y-%m-%d")
log_file = os.path.join(log_dir, f"thinkbuddy_{today_str}.log")
logger = logging.getLogger("thinkbuddy_api")
logger.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler = logging.FileHandler(log_file, mode="a", encoding="utf-8")
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
return logger
def _generate_device_id(self):
return str(uuid.uuid4())
def _get_headers(self):
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0',
'Accept': '*/*',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate, br, zstd',
'X-Client-Version': 'Firefox/JsCore/10.14.1/FirebaseCore-web',
'X-Firebase-gmpid': '1:123807869619:web:43b278a622ed6322789ec6',
'X-Firebase-Client': 'eyJ2ZXJzaW9uIjoyLCJoZWFydGJlYXRzIjpbeyJhZ2VudCI6ImZpcmUtY29yZS8wLjEwLjEzIGZpcmUtY29yZS1lc20yMDE3LzAuMTAuMTMgZmlyZS1qcy8gZmlyZS1mc3QvNC43LjMgZmlyZS1mc3QtZXNtMjAxNy80LjcuMyBmaXJlLWF1dGgvMS43LjkgZmlyZS1hdXRoLWVzbTIwMTcvMS43LjkgZmlyZS1qcy1hbGwtYXBwLzEwLjE0LjEiLCJkYXRlcyI6WyIyMDI1LTAxLTE2Il19XX0',
'Content-Type': 'application/json',
'Origin': 'https://thinkbuddy.ai',
'DNT': '1',
'Sec-GPC': '1',
'Connection': 'keep-alive',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'cross-site',
'Priority': 'u=6',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'TE': 'trailers',
}
return headers
def _check_token(self):
if time.time() > self.expiration_time:
self._register_user()
def _register_user(self):
url = f'https://sour-goat-10.deno.dev/v1/accounts:signUp?key={self.api_key}'
headers = self._get_headers()
data = {"returnSecureToken": True}
retries = 3
for attempt in range(retries):
try:
response = requests.post(url, headers=headers, json=data)
response.raise_for_status() # 抛出HTTPError错误
res = response.json()
self.id_token = res['idToken']
self.refresh_token = res['refreshToken']
self.local_id = res['localId']
self.expiration_time = time.time() + int(res['expiresIn'])
self.logger.info("User registered and token updated successfully")
return
except requests.exceptions.RequestException as e:
self.logger.error(f"Error registering user (attempt {attempt + 1}): {e}")
if attempt == retries - 1:
raise
time.sleep(1) # Wait before retrying
_model_cache = None
_model_cache_time = 0
def list_models(self):
if self._model_cache and time.time() - self._model_cache_time < 7200:
return self._model_cache
self._check_token()
url = 'https://api.thinkbuddy.ai/v1/chat/models'
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0',
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate, br, zstd',
'Referer': 'https://thinkbuddy.ai/',
'Authorization': f'Bearer {self.id_token}',
'Origin': 'https://thinkbuddy.ai',
'DNT': '1',
'Sec-GPC': '1',
'Connection': 'keep-alive',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-site',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'TE': 'trailers'
}
try:
response = requests.get(url, headers=headers)
response.raise_for_status()
self._model_cache = response.json()
self._model_cache_time = time.time()
return self._model_cache
except requests.exceptions.RequestException as e:
self.logger.error(f"Error fetching models: {e}")
raise
def chat_completions_stream(self, model, messages, temperature=1, top_p=1, max_tokens=8192):
self._check_token()
url = 'https://api.thinkbuddy.ai/v1/chat/completions'
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0',
'Accept': '*/*',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate, br, zstd',
'Referer': 'https://thinkbuddy.ai/',
'Content-Type': 'application/json',
'Authorization': f'Bearer {self.id_token}',
'Origin': 'https://thinkbuddy.ai',
'DNT': '1',
'Sec-GPC': '1',
'Connection': 'keep-alive',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-site',
'Priority': 'u=0',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'TE': 'trailers'
}
data = {
"model": model,
"messages": messages,
"temperature": temperature,
"top_p": top_p,
"max_tokens": max_tokens,
"stream": True
}
try:
response = requests.post(url, headers=headers, json=data, stream=True)
response.raise_for_status()
for line in response.iter_lines():
if line:
yield line
except requests.exceptions.RequestException as e:
self.logger.error(f"Error during chat completion: {e}")
yield f"data: {json.dumps({'error': str(e)})}\n\n".encode('utf-8')
def chat_completions(self, model, messages, temperature=1, top_p=1, max_tokens=8192, stream=False):
if stream:
raise ValueError("Use chat_completions_stream to stream responses")
self._check_token()
url = 'https://api.thinkbuddy.ai/v1/chat/completions'
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:134.0) Gecko/20100101 Firefox/134.0',
'Accept': '*/*',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate, br, zstd',
'Referer': 'https://thinkbuddy.ai/',
'Content-Type': 'application/json',
'Authorization': f'Bearer {self.id_token}',
'Origin': 'https://thinkbuddy.ai',
'DNT': '1',
'Sec-GPC': '1',
'Connection': 'keep-alive',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-site',
'Priority': 'u=0',
'Pragma': 'no-cache',
'Cache-Control': 'no-cache',
'TE': 'trailers'
}
data = {
"model": model,
"messages": messages,
"temperature": temperature,
"top_p": top_p,
"max_tokens": max_tokens,
"stream": stream
}
try:
response = requests.post(url, headers=headers, json=data, stream=False)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
self.logger.error(f"Error during chat completion: {e}")
raise
if __name__ == "__main__":
client = ThinkBuddyClient("AIzaSyDBGhSNlMqApZfTMurRSHS1bh-SKMfWImw")
print(client.chat_completions("claude-3-5-sonnet", [{"role": "user", "content": "hi"}]))
from fastapi import FastAPI, Header, HTTPException, Request, Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import StreamingResponse
from pydantic import BaseModel
from typing import List, Optional
from typing_extensions import Annotated # Import Annotated from typing_extensions
import uuid
import asyncio
import json
from api import ThinkBuddyClient
import time
from datetime import datetime
import logging
import os
app = FastAPI(
title="ThinkBuddy API",
description="ThinkBuddy API 代理服务,支持自动创建会话",
version="1.0.0"
)
# 配置 CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 存储用户会话信息
user_sessions = {}
class Message(BaseModel):
role: str
content: str
class ChatRequest(BaseModel):
messages: List[Message]
model: Optional[str] = "claude-3-5-sonnet"
temperature: Optional[float] = 1.0
stream: Optional[bool] = True
class APIKeyHeader(BaseModel):
api_key: str
async def get_api_key_header(authorization: str = Header(...)) -> APIKeyHeader:
try:
scheme, api_key = authorization.split(" ", 1)
if scheme.lower() != "bearer":
raise HTTPException(status_code=400, detail="Authorization header must be Bearer token")
return APIKeyHeader(api_key=api_key)
except ValueError:
raise HTTPException(status_code=400, detail="Authorization header is missing or malformed")
async def get_or_create_client(session_id: str, api_key: Annotated[APIKeyHeader, Depends(get_api_key_header)]) -> ThinkBuddyClient:
if session_id not in user_sessions:
client = ThinkBuddyClient(api_key=api_key.api_key)
# 确保客户端完成初始化
client._register_user()
user_sessions[session_id] = client
return user_sessions[session_id]
async def stream_response(client: ThinkBuddyClient, model: str, messages: List[Message], temperature: float, logger):
"""Helper function to stream responses from ThinkBuddy API."""
def generate():
try:
for line in client.chat_completions_stream(
model=model,
messages=[{"role": msg.role, "content": msg.content} for msg in messages],
temperature=temperature
):
if line:
if line == b"data: [DONE]":
yield b"data: [DONE]\n\n"
break
try:
json_str = line.decode('utf-8').replace('data: ', '')
json_data = json.loads(json_str)
if 'choices' in json_data:
for choice in json_data['choices']:
if 'delta' in choice and choice['delta']:
delta = choice['delta']
if 'content' in delta:
payload = {"choices": [{"delta": delta, "index": 0, "finish_reason": None}]}
yield f"data: {json.dumps(payload)}\n\n".encode('utf-8')
elif 'finish_reason' in choice:
payload = {"choices": [{"delta": {}, "index": 0, "finish_reason": choice['finish_reason']}]}
yield f"data: {json.dumps(payload)}\n\n".encode('utf-8')
except json.JSONDecodeError as e:
print(f"JSON Decode Error:{e}, line:{line}")
logger.error(f"JSON Decode Error:{e}, line:{line}")
yield f"data: {json.dumps({'error': str(e)})}\n\n".encode('utf-8')
except Exception as e:
logger.error(f"Error in stream_response: {e}")
yield f"data: {json.dumps({'error': str(e)})}\n\n".encode('utf-8')
return StreamingResponse(generate(), media_type="text/event-stream")
@app.middleware("http")
async def log_requests(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
log_dir = "./logs/"
os.makedirs(log_dir, exist_ok=True)
today_str = time.strftime("%Y-%m-%d")
log_file = os.path.join(log_dir, f"thinkbuddy_api_{today_str}.log")
logger = logging.getLogger("request_log")
logger.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler = logging.FileHandler(log_file, mode="a", encoding="utf-8")
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
try:
body = await request.body()
if body:
body = body.decode('utf-8')
else:
body = ""
except Exception as e:
body = f"Failed to parse body: {str(e)}"
if request.url.path == '/v1/chat/completions':
output = "Streaming response"
else:
try:
output = await response.body()
output = output.decode('utf-8')
except Exception as e:
output = f"Failed to parse body: {str(e)}"
log_entry = {
"ip": request.client.host,
"method": request.method,
"url": str(request.url),
"headers": dict(request.headers),
"body": body,
"output": output,
"process_time": f"{process_time:.4f}s"
}
logger.info(json.dumps(log_entry, ensure_ascii=False))
return response
@app.post("/v1/chat/completions")
async def chat_completion(
request: ChatRequest,
api_key: Annotated[APIKeyHeader, Depends(get_api_key_header)],
x_session_id: Optional[str] = Header(None)
):
# 如果没有会话 ID,创建新的会话
session_id = x_session_id or str(uuid.uuid4())
try:
# 获取或创建 ThinkBuddy 客户端
client = await get_or_create_client(session_id, api_key)
# 调用 ThinkBuddy API
if request.stream:
return await stream_response(
client=client,
model=request.model,
messages=request.messages,
temperature=request.temperature,
logger = client.logger
)
else:
response = client.chat_completions(
model=request.model,
messages=[{"role": msg.role, "content": msg.content} for msg in request.messages],
temperature=request.temperature,
stream=False
)
return response
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"Error calling ThinkBuddy API: {str(e)}"
)
@app.get("/v1/models")
async def list_models(
api_key: Annotated[APIKeyHeader, Depends(get_api_key_header)],
x_session_id: Optional[str] = Header(None)
):
"""获取可用的模型列表"""
session_id = x_session_id or str(uuid.uuid4())
try:
client = await get_or_create_client(session_id, api_key)
return client.list_models()
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"Error fetching models: {str(e)}"
)
@app.get("/")
async def root():
return {
"status": "ok",
"message": "ThinkBuddy API 代理服务正在运行"
}
采用 flask 搭建后端api,前台使用 bootstrap5 简单做个单页
用户因为前老板已付费,且Claude Pro额度用完,不再续费。目前主要使用Cursor的Claude,虽然功能稍少但仍好用。为了解决聊天记录导出问题,用户在网上找到一个VS Code插件,但该插件是闭源的,提醒对美国不信任的人慎用。插件链接已给出。
这段内容主要介绍了如何将不支持流式传输的 OpenAI 模型 (o1 和 o1-mini) 转换为流式输出,以便在 OpenWebUI 等客户端中使用。作者通过修改代码,将 system
角色转换为 user
角色,并支持 Markdown 格式。同时,解决了 new-api
测试请求的 JSON 解析错误。为了避免 Cloudflare Workers 超时问题,作者尝试了 Deno 环境,并提供了相应的代码。最后,作者还提供了 Azure OpenAI 的测试端点和 API Key 供大家测试,但强调了速率限制。
这个项目提供了一个本地的、兼容 OpenAI 的文本转语音 (TTS) API,它使用 edge-tts。它模拟 OpenAI 的 TTS 端点,允许用户像使用 OpenAI API 一样,通过各种语音选项和播放速度从文本生成语音。该项目使用 Microsoft Edge 的在线文本转语音服务,完全免费。可以通过 Docker 或 Python 运行,支持多种音频格式和速度调整,并提供了与 Open WebUI 和 AnythingLLM 等工具的集成示例。用户可以使用任何字符串作为 API 密钥。
该API服务提供了聊天补全和模型列表接口,使用 https://cursor.toapis.org
作为基础URL。你可以使用内置的试用账户或自己的Cursor Token进行身份验证。该服务已从nodejs迁移到cloudflare worker部署,可能会有bug,欢迎反馈并合理使用API资源。
论坛中有一个AI机器人助手,可以搜索和阅读公开帖子。为了提高搜索效果,可以使用一个特定的Prompt,该Prompt指导AI助手多步调用搜索和阅读工具,并调整关键词以获得更准确的信息。此外,建议使用Claude 3.5 Sonnet模型,并注意AI的使用限制,如只能搜索公开帖子和每日使用次数有限。
<details> <summary>SYSTEM PROMPT</summary> <p>你是一个论坛搜索助手,通过多步调用工具帮助用户在论坛中获取有价值的信息。</p> <p>务必多步调用搜索工具,多步执行并调整搜索关键词以获得更多信息,然后多步使用阅读工具,以深入研究单个话题。搜索工具和阅读工具可以混合使用。多次调整关键字以适配<与用户相同的语言>的搜索需求。</p> <p>关键词的搜索方式应该先兼顾查全率,逐步考虑差准率。</p> <p>THINK IT ALOUD. 可以在<code>THINKING</code>代码块显式地展示你的计划、思考、验证等过程,亦可以完整展示你调用工具的过程,以便展示你如何尽最大的努力来帮助用户。</p> <p>虽然您可以在回答查询时考虑调用工具,但您的回答必须是自洽的,并完整地回答用户查询。</p> <p>您的回答必须正确、高质量,并以专家使用公正的语气撰写。</p> <p>使用脚注格式引用来源。请忽略无关的搜索结果。</p> <p>脚注格式:</p> <ol> <li><strong>脚注标记</strong>:在正文中使用 <code>[^数字]</code> 的形式紧贴文本以标记脚注,例如<code>水是透明的[^1]。</code></li> <li><strong>脚注内容</strong>:在回复末尾使用 <code>[^数字]: 脚注内容</code> 的形式定义脚注的具体内容,给出完整链接</li> </ol> <p>引用最能回答查询的相关结果。避免引用不相关的结果。每句话不要引用超过三个结果。</p> <p>如果您不知道答案或前提不正确,请解释原因。</p> <p>如果搜索结果为空或无帮助,请尽您所能用现有知识回答查询。</p> <p>在适用时使用 Markdown 格式化段落、表格和引用。</p> <p>在比较事物 (vs) 时,将比较格式化为 Markdown 表格,而不是列表。它更易读。</p> </details> USER QUERY:
一次可以生成50000字
这个内容描述了一个名为Ciallo TTS的在线文本转语音工具的项目。该工具支持多种语言和声音,可以调节语速和语调,并提供实时预览和下载功能。项目代码包括HTML、CSS、JavaScript和JSON文件,并提供了在Cloudflare Pages和Vercel上的部署指南。此外,还介绍了本地开发时需要启动HTTP服务器。
这段内容主要介绍了ASS字幕格式的优点,例如可以设置样式并支持多种样式并存。作者使用荣耀黑体和Helvetica字体分别设置了中英文的字幕样式,并解释了时间轴和字幕层叠的原理。最后,作者还分享了如何使用ffmpeg命令将字幕嵌入视频。此外,文章还讨论了人工智能在各行业的应用,并指出当前AI主要集中在大型科技公司,而小企业难以负担AI开发成本。文章提出,应该让更多人参与到AI的开发中,并介绍了通过提供数据而非编写代码来构建AI系统的新方法,以实现AI的普及。
卡卡字幕助手 (VideoCaptioner) 是一款基于大语言模型的视频字幕处理工具,支持语音识别、智能断句、字幕优化和翻译等全流程处理。它提供在线和本地离线两种语音识别方式,并利用大模型进行字幕的智能处理,可以快速为视频生成高质量字幕。该软件操作简单,支持批量处理,并提供直观的字幕编辑界面。