jack před 3 měsíci
rodič
revize
e14723aa2d
5 změnil soubory, kde provedl 153 přidání a 49 odebrání
  1. 14 41
      app/providers/r2r.py
  2. 12 5
      app/services/file/impl/r2r_file.py
  3. 5 3
      main.py
  4. 46 0
      test.txt
  5. 76 0
      testopenassistant.py

+ 14 - 41
app/providers/r2r.py

@@ -1,6 +1,4 @@
 from typing import Optional, Any
-import pytest
-
 from r2r import R2RClient
 
 from app.libs.util import verify_jwt_expiration
@@ -15,16 +13,20 @@ nest_asyncio.apply()
 class R2R:
     client: R2RClient
 
-    def init(self):
-        # self.client = R2RClient(tool_settings.R2R_BASE_URL)
+    def __init__(self):
         self.auth_enabled = tool_settings.R2R_USERNAME and tool_settings.R2R_PASSWORD
         self.client = None
-        loop = asyncio.get_event_loop()
-        if loop.is_running():
-            return loop.create_task(self._login())  # 在现有事件循环中运行异步任务
-        else:
-            return asyncio.run(self._login())  # 如果没有事件循环则创建一个新的
-        # loop.create_task(self._login())
+
+    def init(self):
+        if not self.auth_enabled:
+            return
+        if not self.client:
+            self.client = R2RClient(tool_settings.R2R_BASE_URL)
+            asyncio.run(
+                self.client.users.login(
+                    tool_settings.R2R_USERNAME, tool_settings.R2R_PASSWORD
+                )
+            )
 
     def ingest_file(self, file_path: str, metadata: Optional[dict]):
         self._check_login()
@@ -35,52 +37,23 @@ class R2R:
 
     def search(self, query: str, filters: dict[str, Any]):
         self._check_login()
-        print(
-            "aaaaaaacccccccccccccccccccccccccccccccccccccccccvvvvvvvvvvvvvvvvvvvvvvvvvvvvv"
-        )
-        print(filters)
-        print(tool_settings.R2R_SEARCH_LIMIT)
         search_response = self.client.retrieval.search(
             query=query,
             search_settings={
                 "filters": filters,
                 "limit": tool_settings.R2R_SEARCH_LIMIT,
-                # ,"do_hybrid_search": True,
             },
         )
-        print(search_response)
         return search_response.get("results").get("chunk_search_results")
 
-    # @pytest.fixture(scope="session")
-    async def _login(self):
-        if not self.auth_enabled:
-            return
-        print(
-            "client=>client=>client=>client=>client=>client=>client=>client=>client=>client=>client=>client=>client=>client=>client=>client=>client=>client=>"
-        )
-        print(self.client)
-        if not self.client:
-            self.client = R2RClient(tool_settings.R2R_BASE_URL)
-            result = await self.client.users.login(
-                tool_settings.R2R_USERNAME, tool_settings.R2R_PASSWORD
-            )  # 同步调用异步函数
-        # return self.client
-
     def _check_login(self):
         if not self.auth_enabled:
             return
         if verify_jwt_expiration(self.client.access_token):
             return
         else:
-            loop = asyncio.get_event_loop()
-            if loop.is_running():
-                return loop.create_task(self._login())  # 在现有事件循环中运行异步任务
-            else:
-                return asyncio.run(self._login())  # 如果没有事件循环则创建一个新的
-            # loop.create_task(self._login())
-            # self._login()
+            self.init()
 
 
+# 创建 R2R 实例
 r2r = R2R()
-
-r2r.init()  # 运行异步函数

+ 12 - 5
app/services/file/impl/r2r_file.py

@@ -15,7 +15,9 @@ from app.services.file.impl.oss_file import OSSFileService
 
 class R2RFileService(OSSFileService):
     @staticmethod
-    async def create_file(*, session: AsyncSession, purpose: str, file: UploadFile) -> File:
+    async def create_file(
+        *, session: AsyncSession, purpose: str, file: UploadFile
+    ) -> File:
         # 文件是否存在
         # statement = (
         #     select(File)
@@ -30,19 +32,23 @@ class R2RFileService(OSSFileService):
         #     return ext_file
 
         file_key = f"{uuid.uuid4()}-{file.filename}"
-        with tempfile.NamedTemporaryFile(suffix='_' + file.filename, delete=True) as temp_file:
+        with tempfile.NamedTemporaryFile(
+            suffix="_" + file.filename, delete=True
+        ) as temp_file:
             tmp_file_path = temp_file.name
 
-            async with aiofiles.open(tmp_file_path, 'wb') as f:
+            async with aiofiles.open(tmp_file_path, "wb") as f:
                 while content := await file.read(1024):
                     await f.write(content)
 
             storage.save_from_path(filename=file_key, local_file_path=tmp_file_path)
-
+            r2r.init()
             r2r.ingest_file(file_path=tmp_file_path, metadata={"file_key": file_key})
 
         # 存储
-        db_file = File(purpose=purpose, filename=file.filename, bytes=file.size, key=file_key)
+        db_file = File(
+            purpose=purpose, filename=file.filename, bytes=file.size, key=file_key
+        )
         session.add(db_file)
         await session.commit()
         await session.refresh(db_file)
@@ -51,6 +57,7 @@ class R2RFileService(OSSFileService):
     @staticmethod
     def search_in_files(query: str, file_keys: List[str]) -> dict:
         files = {}
+        r2r.init()
         search_results = r2r.search(query, filters={"file_key": {"$in": file_keys}})
         if not search_results:
             return files

+ 5 - 3
main.py

@@ -12,6 +12,7 @@ from app.providers import (
 from config.config import settings
 import uvicorn
 
+
 def create_app() -> FastAPI:
     _app = FastAPI()
 
@@ -38,17 +39,18 @@ def boot(_app, provider):
 
 app = create_app()
 
+
 @app.get("/")
 async def root():
     return "Welcome to Open Assistant Api"
 
 
 if __name__ == "__main__":
-    #app.run(host="0.0.0.0", port=settings.SERVER_PORT)
+    # app.run(host="0.0.0.0", port=settings.SERVER_PORT)
     uvicorn.run(
-        app=app, #"main:app",
+        app=app,  # "main:app",
         host=settings.SERVER_HOST,
         port=settings.SERVER_PORT,
-        workers=1,#settings.SERVER_WORKERS,
+        workers=1,  # settings.SERVER_WORKERS,
         reload=settings.ENV == "local",
     )

+ 46 - 0
test.txt

@@ -0,0 +1,46 @@
+會議資訊
+會議主題:人工智能特工队的視像會議
+會議時間:Dec 18 (Wed) 12:09 - 12:37 (GMT+08)
+參加者:@Tony(辛海洋) @黄丽惠 @刘雁翎 @牛倩楠 
+智能記錄
+智能會議記錄由 AI 建立,可能不精準,請謹慎甄別後使用
+總結
+会议讨论了义务教育课程纲要成果、教材编写困难等,包括报告材料、课题思路与教师活动开展计划。主要内容包括:
+- 关于人工智能与创客教育相关项目的讨论
+  - 义务教育课程纲要成果:去年完成义务教育人工智能课程纲要修订,花费少效果好,走在全国前列。
+  - 教材编写的困难:考虑编写人工智能教材,但面临诸多问题,如可能影响现有 8 家数字化平台。
+  - 报告所需材料:为中国战略发展协会的报告,需提供 8 家公司投标时信息中心的要求和限制等材料。
+  - 课题研究思路:准备以 10 万经费开展关于创客马拉松项目人工智能模型的课题,下周一部门讨论。
+  - 活动开展计划:计划开展四次教师相关活动,分三次进行,分析老师在不同条件下项目的完成度等情况。
+- 关于利用多智能体开展创意作品制作活动的讨论
+  - 活动安排:活动分三次,前两次分别在宝安区和其他区域,第三次面向全市,先到先得。
+  - 面向对象:前两次针对老师,第三次面向全市人员。
+  - 工具使用:限定使用 B 端萌宠款 AI,有利于数据收集。
+  - 时间规划:前两次可同时搞,第三次全市活动通知发在 9 号。
+  - 问卷设计:设计问卷需经得住信效度检查,需要花时间,预计下下周完成。
+  - 任务设置:每次活动给老师两小时任务,学生不学编程语法,以完成小作品为任务。
+  - 讲座反馈:上次讲座 PPT 内容偏难,今后要了解听众需求,以 AIGC 对老师的作用为例,进行有效讲解。
+  - 采购调整:研究将创客马拉松比赛设备采购改为租赁,并考虑收取租赁费用。
+待辦事項
+[] 小伙子提供8家公司在投标时,信息中心要求提供的材料,包括算力等方面的要求和限制
+[] Tony(辛海洋)讨论创意作品制作工作坊活动的问卷设计,以及活动的具体方案@Tony(辛海洋) 
+智能章節
+00:00  义务教育人工智能课程纲要修订及教材编写相关讨论
+本章节提到项目提出者不了解教科院工作,教科院有智慧学习平台且涉及大模型。去年修订义务教育人工智能课程纲要花小钱办大事,走在全国前列。今年有8 - 10万费用可做教材,但做教材存在问题,还提及8家平台、数字化平台运作情况,最后提到中国战略发展协会需要提供资料。
+03:14  关于人工智能报告的开展、相关要求及课题申请的讨论
+本章节围绕做针对性人工智能报告展开。提到要分享机械中心对8家公司投标时的要求限制,如算力方面,这与深圳市教育局对平台门槛和后期服务要求有关。还谈及创客马拉松人工智能转型、经费使用、课题申请,以及下周一要拿出课题相关思路进行部门讨论等内容。
+08:39  借助前沿技术解决教育痛点并打造活动赋能范式的项目阐述
+本章节主要讨论了创客马拉松相关项目。去年中标26万,今年要减5万。剩余10万左右经费用来改变创马拉松的工作流程。同时提到目前存在一些问题,如老师能力素养参差不齐、新技术多学不过来等,希望借助AI给老师、学生、比赛赋能,还探讨了汇报格式及项目认可度的问题。
+14:45  项目相关的PPT制作、经费使用、活动规划及教师参与的研讨安排
+本章节主要围绕项目相关事务展开。Tony(辛海洋)提到5分钟讲10页PPT,还涉及10万项目资金的使用、参考谢丽的用钱方式。关于活动,要做四次,与教研员沟通,教师活动分三次进行且任务要形成闭环,同时提到可与课题结合先做些尝试性工作。
+18:38  关于创意作品制作活动的策划讨论
+本章节主要讨论活动相关事项。提到借助活动由头早点收数据、写文章并出初步稿件。活动第三次面向全市老师报名,前两次分别在不同区域且动静小。还谈及任务选择,如两小时完成类似做小徽章的任务,以及学生编程相关内容,如新课标下教学生的主流方向等。
+22:11  关于使用AI造物及问卷调研相关工作的安排讨论
+本章节主要讨论了工具(如AI)在造物、写论文报告等方面的作用,能提供更多思路。还提到关于问卷相关事务,包括问卷设计要做信效度检查,下下周提供方案比较合适。同时讨论了活动推行时间可能定在元月2号(周四),以及活动在龙华和宝安两个区的开展安排等事。
+25:42  关于考试安排、通知发布时间及对上次讲座PPT难度的讨论
+本章节首先提到9号询问老师是否考试,老师不考。然后确定9号、26号和2号相关的工作安排,9号会发通知。接着辛海洋还对上一次的情况进行反馈,提到柳笑的中评情况,还指出某人PPT内容太难,最后询问胡老师是否会亲自告知此事。
+26:48  AI GC对教师的作用及其他事务商讨
+本章节主要内容为Tony(辛海洋)期望邀请某人给全校老师进行10分钟左右的分享,分享内容为AIGC对老师的作用。还提到对创客马拉松比赛兴趣不大,可撤掉相关内容,谈到设备可租赁及收费问题,也提及中标取决于总体思路以及去年怼财务关于中标公司的事情。
+暂时无法在飞书文档外展示此内容
+會議回顧
+暂时无法在飞书文档外展示此内容

+ 76 - 0
testopenassistant.py

@@ -0,0 +1,76 @@
+import os
+from pathlib import Path
+import time
+import openai
+
+base_url = "https://assistantapi.cocorobo.cn/api/v1"
+api_key = "cocorobo-xjw-admin"
+client = openai.OpenAI(base_url=base_url, api_key=api_key)
+
+if __name__ == "__main__":
+
+    file_path = os.path.join(os.path.dirname(__file__) + "/test.txt")
+    print(file_path)
+    file = client.files.create(file=Path(file_path), purpose="assistants")
+    print(file)
+
+    assistant = client.beta.assistants.create(
+        name="Assistant Demo",
+        instructions="you are a personal assistant, file content could be retrieved to assist the conversation.",
+        model="gpt-4o",
+        tools=[
+            {"type": "file_search"},
+        ],
+        tool_resources={"file_search": {"vector_stores": [{"file_ids": [file.id]}]}},
+    )
+    # assistant = client.beta.assistants.retrieve(assistant_id="67614b38d5f1a0df9dddfba9")
+    print("=====> : %s\n", assistant)
+
+    thread = client.beta.threads.create()
+    print("=====> : %s\n", thread)
+
+    message = client.beta.threads.messages.create(
+        thread_id=thread.id,
+        role="user",
+        content="内容有什么",
+        # attachments=[
+        #     {"file_id": "67614b375e4b953d7f07c27a", "tools": [{"type": "file_search"}]}
+        # ]
+    )
+    print("=====> : %s\n", message)
+
+    run = client.beta.threads.runs.create(
+        thread_id=thread.id,
+        assistant_id=assistant.id,
+    )
+    print("=====> : %s\n", run)
+
+    print("checking assistant status. \n")
+    while True:
+        run = client.beta.threads.runs.retrieve(thread_id=thread.id, run_id=run.id)
+        run_steps = client.beta.threads.runs.steps.list(
+            run_id=run.id, thread_id=thread.id
+        ).data
+        for run_step in run_steps:
+            print("=====> : %s\n", run_step)
+
+        if run.status == "completed":
+            messages = client.beta.threads.messages.list(thread_id=thread.id)
+
+            print("=====> messages:")
+            for message in messages:
+                assert message.content[0].type == "text"
+                print(
+                    "%s",
+                    {"role": message.role, "message": message.content[0].text.value},
+                )
+
+            # delete asst
+            client.beta.assistants.delete(assistant.id)
+            break
+        elif run.status == "failed":
+            print("run failed %s\n", run.last_error)
+            break
+        else:
+            print("in progress...\n")
+            time.sleep(5)