heysho commited on
Commit
5949f3d
1 Parent(s): 1c2e898

Upload 2 files

Browse files
Files changed (2) hide show
  1. tools/fetch_page.py +88 -0
  2. tools/search_ddg.py +41 -0
tools/fetch_page.py ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import html2text
3
+ from readability import Document
4
+ from langchain_core.tools import tool
5
+ from langchain_core.pydantic_v1 import (BaseModel, Field)
6
+ from langchain_text_splitters import RecursiveCharacterTextSplitter
7
+
8
+
9
+ class FetchPageInput(BaseModel):
10
+ url: str = Field()
11
+ page_num: int = Field(0, ge=0)
12
+
13
+
14
+ @tool(args_schema=FetchPageInput)
15
+ def fetch_page(url, page_num=0, timeout_sec=10):
16
+ """
17
+ 指定されたURLから(とページ番号から)ウェブページのコンテンツを取得するツール。
18
+
19
+ `status` と `page_content`(`title`、`content`、`has_next`インジケーター)を返します。
20
+ statusが200でない場合は、ページの取得時にエラーが発生しています。(他のページの取得を試みてください)
21
+
22
+ デフォルトでは、最大2,000トークンのコンテンツのみが取得されます。
23
+ ページにさらにコンテンツがある場合、`has_next`の値はTrueになります。
24
+ 続きを読むには、同じURLで`page_num`パラメータをインクリメントして、再度入力してください。
25
+ (ページングは0から始まるので、次のページは1です)
26
+
27
+ 1ページが長すぎる場合は、**3回以上取得しないでください**(メモリの負荷がかかるため)。
28
+
29
+ Returns
30
+ -------
31
+ Dict[str, Any]:
32
+ - status: str
33
+ - page_content
34
+ - title: str
35
+ - content: str
36
+ - has_next: bool
37
+ """
38
+ try:
39
+ response = requests.get(url, timeout=timeout_sec)
40
+ response.encoding = 'utf-8'
41
+ except requests.exceptions.Timeout:
42
+ return {
43
+ "status": 500,
44
+ "page_content": {'error_message': 'Could not download page due to Timeout Error. Please try to fetch other pages.'}
45
+ }
46
+
47
+ if response.status_code != 200:
48
+ return {
49
+ "status": response.status_code,
50
+ "page_content": {'error_message': 'Could not download page. Please try to fetch other pages.'}
51
+ }
52
+
53
+ try:
54
+ doc = Document(response.text)
55
+ title = doc.title()
56
+ html_content = doc.summary()
57
+ content = html2text.html2text(html_content)
58
+ except:
59
+ return {
60
+ "status": 500,
61
+ "page_content": {'error_message': 'Could not parse page. Please try to fetch other pages.'}
62
+ }
63
+
64
+ text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
65
+ model_name='gpt-4o-mini',
66
+ chunk_size=1000,
67
+ chunk_overlap=0,
68
+ )
69
+ chunks = text_splitter.split_text(content)
70
+ if page_num >= len(chunks):
71
+ return {
72
+ "status": 500,
73
+ "page_content": {'error_message': 'page_num parameter looks invalid. Please try to fetch other pages.'}
74
+ }
75
+ elif page_num >= 3:
76
+ return {
77
+ "status": 503,
78
+ "page_content": {'error_message': "Reading more of the page_num's content will overload your memory. Please provide your response based on the information you currently have."}
79
+ }
80
+ else:
81
+ return {
82
+ "status": 200,
83
+ "page_content": {
84
+ "title": title,
85
+ "content": chunks[page_num],
86
+ "has_next": page_num < len(chunks) - 1
87
+ }
88
+ }
tools/search_ddg.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from itertools import islice
2
+ from duckduckgo_search import DDGS
3
+ from langchain_core.tools import tool
4
+ from langchain_core.pydantic_v1 import (BaseModel, Field)
5
+
6
+
7
+ class SearchDDGInput(BaseModel):
8
+ query: str = Field(description="検索したいキーワードを入力してください")
9
+
10
+
11
+ @tool(args_schema=SearchDDGInput)
12
+ def search_ddg(query, max_result_num=5):
13
+ """
14
+ DuckDuckGo検索を実行するためのツールです。
15
+ 検索したいキーワードを入力して使用してください。
16
+ 検索結果の各ページのタイトル、スニペット(説明文)、URLが返されます。
17
+ このツールから得られる情報は非常に簡素化されており、時には古い情報の場合もあります。
18
+
19
+ 必要な情報が見つからない場合は、必ず `WEB Page Fetcher` ツールを使用して各ページの内容を確認してください。
20
+ 文脈に応じて最も適切な言語を使用してください(ユーザーの言語と同じである必要はありません)。
21
+ 例えば、プログラミング関連の質問では、英語で検索するのが最適です。
22
+
23
+ Returns
24
+ -------
25
+ List[Dict[str, str]]:
26
+ - title
27
+ - snippet
28
+ - url
29
+ """
30
+ res = DDGS().text(query + " latest", region='JP', safesearch='off', backend="lite")
31
+ return [
32
+ {
33
+ "title": r.get('title', ""),
34
+ "snippet": r.get('body', ""),
35
+ "url": r.get('href', "")
36
+ }
37
+ for r in islice(res, max_result_num)
38
+ ]
39
+
40
+
41
+