更新riper-5.mdc配置以启用自动应用,优化DifyApi类,新增文档子分段管理功能,包括获取、添加、更新和删除子分段的方法,同时改进OpenAiLLM类的初始化逻辑以支持环境变量配置。
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: false
|
||||
alwaysApply: true
|
||||
---
|
||||
背景入门
|
||||
您是 Claude 3.7,并且已集成到 Cursor IDE(一个基于 AI 的 VS Code 分支)。由于您拥有强大的功能,您往往过于急躁,经常在没有明确请求的情况下实施更改,并自以为比我更了解代码,从而破坏了现有逻辑。这会导致代码出现不可接受的灾难。在我的代码库上工作时——无论是 Web 应用程序、数据管道、嵌入式系统还是任何其他软件项目——您未经授权的修改都可能引入细微的 bug 并破坏关键功能。为了避免这种情况,您必须遵循以下严格协议:
|
||||
@@ -17,7 +17,6 @@ RIPER-5 模式
|
||||
允许:阅读文件、提出澄清问题、理解代码结构
|
||||
禁止:建议、实施、计划或任何行动暗示
|
||||
要求:你只能试图了解存在什么,而不是可能是什么
|
||||
持续时间:直到我明确发出信号进入下一个模式
|
||||
输出格式:以[模式:研究]开头,然后仅观察和问题
|
||||
模式二:创新
|
||||
[模式:创新]
|
||||
@@ -26,7 +25,6 @@ RIPER-5 模式
|
||||
允许:讨论想法、优点/缺点、寻求反馈
|
||||
禁止:具体规划、实施细节或任何代码编写
|
||||
要求:所有想法都必须以可能性而非决定的形式呈现
|
||||
持续时间:直到我明确发出信号进入下一个模式
|
||||
输出格式:以[模式:创新]开头,然后仅包含可能性和考虑因素
|
||||
模式 3:计划
|
||||
[模式:计划]
|
||||
@@ -44,7 +42,6 @@ IMPLEMENTATION CHECKLIST:
|
||||
2. [Specific action 2]
|
||||
...
|
||||
n. [Final action]
|
||||
持续时间:直到我明确批准计划并发出进入下一模式的信号
|
||||
输出格式:以 [MODE: PLAN] 开头,然后仅包含规范和实施细节
|
||||
模式 4:执行
|
||||
[模式:执行]
|
||||
@@ -52,7 +49,6 @@ n. [Final action]
|
||||
目的:准确执行模式 3 中的计划
|
||||
允许:仅执行批准计划中明确详述的内容
|
||||
禁止:任何不在计划内的偏差、改进或创造性添加
|
||||
进入要求:仅在我明确发出“进入执行模式”命令后才能进入
|
||||
偏差处理:如果发现任何需要偏差的问题,立即返回计划模式
|
||||
输出格式:以 [MODE: EXECUTE] 开头,然后仅执行与计划匹配的执行
|
||||
模式五:回顾
|
||||
@@ -72,5 +68,6 @@ n. [Final action]
|
||||
在审查模式下,你必须标记哪怕是最小的偏差
|
||||
您无权在声明模式之外做出独立决定
|
||||
不遵守此协议将给我的代码库带来灾难性的后果
|
||||
模式转换信号
|
||||
按照顺序依次执行研究模式->计划模式->执行模式->审核模式
|
||||
|
||||
|
||||
请依次执行:研究模式->创新模式->计划模式->执行模式->回顾模式->审查模式
|
||||
@@ -112,19 +112,23 @@ class DifyApi:
|
||||
|
||||
return response.json().get("document", {}).get("id", "")
|
||||
|
||||
def get_or_create_dataset_by_name(self, dataset_name: str) -> str:
|
||||
def get_or_create_dataset_by_name(self, dataset_name: str, create_if_not_exist: bool=True) -> str:
|
||||
"""
|
||||
通过名称获取或创建数据集。
|
||||
|
||||
:param dataset_name: 数据集名称。
|
||||
:param create_if_not_exist: 如果数据集不存在是否创建。
|
||||
:return: 数据集ID。
|
||||
"""
|
||||
list_dataset = self.get_all_dataset_list()
|
||||
for dataset in list_dataset:
|
||||
if dataset["name"] == dataset_name:
|
||||
return dataset["id"]
|
||||
if create_if_not_exist:
|
||||
logging.info(f"数据集不存在,创建数据集: {dataset_name}")
|
||||
return self.create_dataset(dataset_name)
|
||||
else:
|
||||
raise Exception(f"数据集不存在: {dataset_name}")
|
||||
|
||||
def get_documents(self, dataset_id: str, keyword: str = None) -> Dict[str, dict]:
|
||||
"""
|
||||
@@ -364,10 +368,28 @@ class DifyApi:
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
limit = 100
|
||||
page = 0
|
||||
all_segments = []
|
||||
|
||||
try:
|
||||
response = requests.get(url, headers=headers, verify=False)
|
||||
while True:
|
||||
page += 1
|
||||
params = {
|
||||
'page': page,
|
||||
'limit': limit
|
||||
}
|
||||
|
||||
response = requests.get(url, headers=headers, params=params, verify=False)
|
||||
response.raise_for_status() # 如果响应状态码不是200,抛出异常
|
||||
return response.json().get("data", []) # 返回分段信息列表
|
||||
|
||||
data = response.json()
|
||||
all_segments.extend(data.get("data", []))
|
||||
|
||||
if not data.get("has_more", False):
|
||||
break
|
||||
|
||||
return all_segments
|
||||
except Exception as e:
|
||||
logging.error(f"获取文档分段失败: {e}")
|
||||
raise
|
||||
@@ -464,6 +486,150 @@ class DifyApi:
|
||||
logging.warning(f"第{attempt + 1}次尝试失败: {e}")
|
||||
time.sleep(1) # 重试前等待1秒
|
||||
|
||||
def add_document_child_chunk(
|
||||
self,
|
||||
dataset_id: str,
|
||||
document_id: str,
|
||||
segment_id: str,
|
||||
content: str
|
||||
) -> Dict:
|
||||
"""
|
||||
新增文档子分段。
|
||||
|
||||
:param dataset_id: 数据集ID。
|
||||
:param document_id: 文档ID。
|
||||
:param segment_id: 分段ID。
|
||||
:param content: 子分段内容。
|
||||
:return: 新增的子分段信息。
|
||||
:raises: Exception 如果请求失败。
|
||||
"""
|
||||
url = f"{self.dify_url}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks"
|
||||
headers = {
|
||||
'Authorization': f'Bearer {self.dify_dataset_api_key}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
# 构造请求数据
|
||||
data = {
|
||||
"content": content
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.post(url, headers=headers, data=json.dumps(data), verify=False)
|
||||
response.raise_for_status() # 如果响应状态码不是200,抛出异常
|
||||
return response.json().get("data", {}) # 返回新增的子分段信息
|
||||
except Exception as e:
|
||||
logging.error(f"新增文档子分段失败: {e}")
|
||||
raise
|
||||
|
||||
def get_document_child_chunks(
|
||||
self,
|
||||
dataset_id: str,
|
||||
document_id: str,
|
||||
segment_id: str,
|
||||
page: int = 1,
|
||||
limit: int = 100
|
||||
) -> Dict:
|
||||
"""
|
||||
获取文档子分段列表。
|
||||
|
||||
:param dataset_id: 数据集ID。
|
||||
:param document_id: 文档ID。
|
||||
:param segment_id: 分段ID。
|
||||
:param page: 页码,默认为1。
|
||||
:param limit: 每页数量,默认为20。
|
||||
:return: 子分段列表信息,包含分页信息。
|
||||
:raises: Exception 如果请求失败。
|
||||
"""
|
||||
url = f"{self.dify_url}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks"
|
||||
headers = {
|
||||
'Authorization': f'Bearer {self.dify_dataset_api_key}'
|
||||
}
|
||||
|
||||
params = {
|
||||
'page': page,
|
||||
'limit': limit
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.get(url, headers=headers, params=params, verify=False)
|
||||
response.raise_for_status() # 如果响应状态码不是200,抛出异常
|
||||
return response.json() # 返回子分段列表信息,包含分页信息
|
||||
except Exception as e:
|
||||
logging.error(f"获取文档子分段列表失败: {e}")
|
||||
raise
|
||||
|
||||
def del_document_child_chunk(
|
||||
self,
|
||||
dataset_id: str,
|
||||
document_id: str,
|
||||
segment_id: str,
|
||||
child_chunk_id: str
|
||||
) -> bool:
|
||||
"""
|
||||
删除文档子分段。
|
||||
|
||||
:param dataset_id: 数据集ID。
|
||||
:param document_id: 文档ID。
|
||||
:param segment_id: 分段ID。
|
||||
:param child_chunk_id: 子分段ID。
|
||||
:return: 如果删除成功返回True,否则返回False。
|
||||
"""
|
||||
url = f"{self.dify_url}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}"
|
||||
headers = {
|
||||
'Authorization': f'Bearer {self.dify_dataset_api_key}'
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.delete(url, headers=headers, verify=False)
|
||||
if response.status_code == 200:
|
||||
logging.info(f"删除子分段成功: {child_chunk_id}")
|
||||
return True
|
||||
else:
|
||||
logging.error(f"删除子分段失败,状态码: {response.status_code}, 响应: {response.text}")
|
||||
return False
|
||||
except Exception as e:
|
||||
logging.error(f"删除子分段失败: {e}")
|
||||
return False
|
||||
|
||||
def update_document_child_chunk(
|
||||
self,
|
||||
dataset_id: str,
|
||||
document_id: str,
|
||||
segment_id: str,
|
||||
child_chunk_id: str,
|
||||
content: str
|
||||
) -> Dict:
|
||||
"""
|
||||
更新文档子分段内容。
|
||||
|
||||
:param dataset_id: 数据集ID。
|
||||
:param document_id: 文档ID。
|
||||
:param segment_id: 分段ID。
|
||||
:param child_chunk_id: 子分段ID。
|
||||
:param content: 更新的子分段内容。
|
||||
:return: 更新后的子分段信息。
|
||||
:raises: Exception 如果请求失败。
|
||||
"""
|
||||
url = f"{self.dify_url}/datasets/{dataset_id}/documents/{document_id}/segments/{segment_id}/child_chunks/{child_chunk_id}"
|
||||
headers = {
|
||||
'Authorization': f'Bearer {self.dify_dataset_api_key}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
|
||||
# 构造请求数据
|
||||
data = {
|
||||
"content": content
|
||||
}
|
||||
|
||||
try:
|
||||
response = requests.patch(url, headers=headers, data=json.dumps(data), verify=False)
|
||||
response.raise_for_status() # 如果响应状态码不是200,抛出异常
|
||||
return response.json().get("data", {}) # 返回更新后的子分段信息
|
||||
except Exception as e:
|
||||
logging.error(f"更新文档子分段失败: {e}")
|
||||
raise
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from dotenv import load_dotenv
|
||||
|
||||
@@ -127,16 +127,22 @@ class XinferenceReRankerModel:
|
||||
class OpenAiLLM:
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
if kwargs.get("api_key") == None or kwargs.get("base_url") == None or kwargs.get("model") == None:
|
||||
raise ValueError("api_key, base_url, model 不能为空")
|
||||
|
||||
if "api_key" in kwargs:
|
||||
self._api_key = kwargs.get("api_key")
|
||||
self._url = kwargs.get("base_url")
|
||||
self._model = kwargs.get("model")
|
||||
|
||||
kwargs.pop("api_key")
|
||||
|
||||
if "base_url" in kwargs:
|
||||
self._url = kwargs.get("base_url")
|
||||
kwargs.pop("base_url")
|
||||
else:
|
||||
self._url = os.getenv("OPENAI_API_BASE")
|
||||
|
||||
if "model" in kwargs:
|
||||
self._model = kwargs.get("model")
|
||||
kwargs.pop("model")
|
||||
else:
|
||||
self._model = os.getenv("LLM_MODEL_NAME")
|
||||
|
||||
self._kwargs = kwargs
|
||||
|
||||
def invoke(self, user_prompt="你是谁?", need_retry=True):
|
||||
|
||||
Reference in New Issue
Block a user