feat: expand graph traversal with cross-article relation search and improve tool routing
Browse files
src/retrieval/finRetrieval.py
CHANGED
|
@@ -74,6 +74,19 @@ OPTIONAL MATCH (article)-[:MENTIONS]->(company:AICompany)
|
|
| 74 |
OPTIONAL MATCH (company)-[:DEVELOPS]->(tech:AITechnology)
|
| 75 |
OPTIONAL MATCH (company)-[:DEVELOPS]->(svc:AIService)
|
| 76 |
OPTIONAL MATCH (article)-[:MENTIONS]->(field:AIField)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
RETURN
|
| 78 |
node.chunk AS chunk,
|
| 79 |
article.title AS article_title,
|
|
@@ -82,7 +95,9 @@ RETURN
|
|
| 82 |
collect(DISTINCT company.name) AS companies,
|
| 83 |
collect(DISTINCT tech.name) AS technologies,
|
| 84 |
collect(DISTINCT svc.name) AS services,
|
| 85 |
-
collect(DISTINCT field.name) AS fields
|
|
|
|
|
|
|
| 86 |
"""
|
| 87 |
|
| 88 |
|
|
@@ -141,6 +156,31 @@ CYPHER QUERY:
|
|
| 141 |
RETURN a.title AS title, a.url AS url, a.published_date AS published_date, c.chunk AS chunk
|
| 142 |
ORDER BY a.published_date DESC
|
| 143 |
LIMIT 3""",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
]
|
| 145 |
|
| 146 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
@@ -205,7 +245,9 @@ _prompt_template = CustomRagTemplate(
|
|
| 205 |
|
| 206 |
- **์ด์ ์ ๊ฐ**: [๊ตฌ์ฒด์ ์ธ ์ด์ ๋ฐ์ ๋ฐฐ๊ฒฝ ๋ฐ ์งํ ๊ฒฝ๊ณผ]
|
| 207 |
|
| 208 |
-
- **๊ธฐ์
๋ํฅ**: [๊ด๋ จ ํต์ฌ ๊ธฐ์
๋ค์ ์ค๋ฌผ ๋น์ฆ๋์ค ์์ง์ ๋ฐ ๋์ ํ๋ณด]
|
|
|
|
|
|
|
| 209 |
|
| 210 |
- **์ธํ๋ผ/์ฌํ์ ์์ธ**: [์ ๋ ฅ๋ง ๋ถ์กฑ, ๋์ค์ ๋ถ์๊ฐ, ํ๋์จ์ด์ ์ ์ฝ ์ฌํญ ๋ฑ ํต์ฌ ์์ธ]
|
| 211 |
|
|
@@ -219,12 +261,13 @@ _prompt_template = CustomRagTemplate(
|
|
| 219 |
- **์ค์ ์์์/๋ฉด์ ํ์ฉ Tip**: [์ง์๋๊ธฐ๋ ์ญ๋ ๊ธฐ์ ์ ์์ฑ ์ ๋ณธ์ธ์ ์ญ๋๊ณผ ์ด๋ป๊ฒ ์ฐ๊ณํ์ฌ ํ์ด๋ผ์ง์ ๋ํ ๋ง์ถค ๊ฐ์ด๋]
|
| 220 |
|
| 221 |
|
| 222 |
-
### ๐ฐ 4. ๊ทผ๊ฑฐ ๋ด์ค ์ถ์ฒ (GraphRAG
|
| 223 |
|
| 224 |
-
>
|
| 225 |
-
>
|
| 226 |
-
>
|
| 227 |
-
>
|
|
|
|
| 228 |
|
| 229 |
---
|
| 230 |
|
|
@@ -276,11 +319,20 @@ class LazyGraphRAG:
|
|
| 276 |
tools=[
|
| 277 |
vector_cypher_retriever.convert_to_tool(
|
| 278 |
name="vector_retriever",
|
| 279 |
-
description=
|
|
|
|
|
|
|
|
|
|
|
|
|
| 280 |
),
|
| 281 |
text2cypher_retriever.convert_to_tool(
|
| 282 |
name="text2cypher_retriever",
|
| 283 |
-
description=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 284 |
),
|
| 285 |
],
|
| 286 |
)
|
|
|
|
| 74 |
OPTIONAL MATCH (company)-[:DEVELOPS]->(tech:AITechnology)
|
| 75 |
OPTIONAL MATCH (company)-[:DEVELOPS]->(svc:AIService)
|
| 76 |
OPTIONAL MATCH (article)-[:MENTIONS]->(field:AIField)
|
| 77 |
+
|
| 78 |
+
// ๋์ผ ๊ธฐ์
/๊ธฐ์ /์๋น์ค๋ฅผ ์ธ๊ธํ๋ ๊ด๋ จ ๊ธฐ์ฌ๊น์ง ํ์ฅ ํ์ (ํก๋จ ๊ฒ์)
|
| 79 |
+
OPTIONAL MATCH (related_article:Article)
|
| 80 |
+
WHERE related_article <> article
|
| 81 |
+
AND (
|
| 82 |
+
EXISTS { (related_article)-[:MENTIONS]->(:AICompany)<-[:MENTIONS]-(article) }
|
| 83 |
+
OR EXISTS { (related_article)-[:MENTIONS]->(:AITechnology)<-[:MENTIONS]-(article) }
|
| 84 |
+
OR EXISTS { (related_article)-[:MENTIONS]->(:AIService)<-[:MENTIONS]-(article) }
|
| 85 |
+
)
|
| 86 |
+
WITH
|
| 87 |
+
node, article, company, tech, svc, field,
|
| 88 |
+
collect(DISTINCT related_article.title)[..3] AS related_titles,
|
| 89 |
+
collect(DISTINCT related_article.url)[..3] AS related_urls
|
| 90 |
RETURN
|
| 91 |
node.chunk AS chunk,
|
| 92 |
article.title AS article_title,
|
|
|
|
| 95 |
collect(DISTINCT company.name) AS companies,
|
| 96 |
collect(DISTINCT tech.name) AS technologies,
|
| 97 |
collect(DISTINCT svc.name) AS services,
|
| 98 |
+
collect(DISTINCT field.name) AS fields,
|
| 99 |
+
related_titles AS related_article_titles,
|
| 100 |
+
related_urls AS related_article_urls
|
| 101 |
"""
|
| 102 |
|
| 103 |
|
|
|
|
| 156 |
RETURN a.title AS title, a.url AS url, a.published_date AS published_date, c.chunk AS chunk
|
| 157 |
ORDER BY a.published_date DESC
|
| 158 |
LIMIT 3""",
|
| 159 |
+
"""USER INPUT: ์ต๊ทผ ๊ฐ์ฅ ๊ด์ฌ์ด ๋์ AI ๊ธฐ์ ์ด ๋ญ์ผ?
|
| 160 |
+
CYPHER QUERY:
|
| 161 |
+
MATCH (a:Article)-[:MENTIONS]->(t:AITechnology)
|
| 162 |
+
OPTIONAL MATCH (c:AICompany)-[:DEVELOPS]->(t)
|
| 163 |
+
WITH t, count(DISTINCT a) AS article_count, collect(DISTINCT c.name)[..3] AS companies, collect(DISTINCT a.title)[..3] AS article_titles, collect(DISTINCT a.url)[..3] AS article_urls
|
| 164 |
+
ORDER BY article_count DESC
|
| 165 |
+
RETURN t.name AS tech_name, t.description AS description, article_count, companies, article_titles, article_urls
|
| 166 |
+
LIMIT 5""",
|
| 167 |
+
"""USER INPUT: AI ๊ธฐ์ ํธ๋ ๋๋ฅผ ๋ถ์ํด์ค
|
| 168 |
+
CYPHER QUERY:
|
| 169 |
+
MATCH (a:Article)-[:MENTIONS]->(t:AITechnology)
|
| 170 |
+
OPTIONAL MATCH (c:AICompany)-[:DEVELOPS]->(t)
|
| 171 |
+
WITH t, count(DISTINCT a) AS article_count, collect(DISTINCT c.name)[..3] AS companies, collect(DISTINCT a.title)[..2] AS article_titles, collect(DISTINCT a.url)[..2] AS article_urls
|
| 172 |
+
ORDER BY article_count DESC
|
| 173 |
+
RETURN t.name AS tech_name, article_count, companies, article_titles, article_urls
|
| 174 |
+
LIMIT 5""",
|
| 175 |
+
"""USER INPUT: ํ๋์ฐจ ๋๋ ๋ก๋ด ๊ด๋ จ AI ๋ด์ค ์๋ ค์ค
|
| 176 |
+
CYPHER QUERY:
|
| 177 |
+
MATCH (a:Article)-[:MENTIONS]->(c:AICompany)
|
| 178 |
+
WHERE c.name CONTAINS 'ํ๋' OR c.name CONTAINS '๋ก๋ด'
|
| 179 |
+
OPTIONAL MATCH (a)-[:MENTIONS]->(t:AITechnology)
|
| 180 |
+
OPTIONAL MATCH (a)-[:MENTIONS]->(s:AIService)
|
| 181 |
+
RETURN a.title AS article_title, a.url AS article_url, a.published_date AS article_date,
|
| 182 |
+
collect(DISTINCT c.name) AS companies, collect(DISTINCT t.name) AS technologies, collect(DISTINCT s.name) AS services
|
| 183 |
+
ORDER BY a.published_date DESC LIMIT 5""",
|
| 184 |
]
|
| 185 |
|
| 186 |
# โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
|
|
| 245 |
|
| 246 |
- **์ด์ ์ ๊ฐ**: [๊ตฌ์ฒด์ ์ธ ์ด์ ๋ฐ์ ๋ฐฐ๊ฒฝ ๋ฐ ์งํ ๊ฒฝ๊ณผ]
|
| 247 |
|
| 248 |
+
- **๊ธฐ์
๋ํฅ**: [๊ด๋ จ ํต์ฌ ๊ธฐ์
๋ค์ ์ค๋ฌผ ๋น์ฆ๋์ค ์์ง์ ๋ฐ ๋์ ํ๋ณด. ์ปจํ
์คํธ์ ์ฌ๋ฌ ๊ธฐ์
/๊ธฐ์ ์ด ์๋ค๋ฉด ๋ชจ๋ ์ธ๊ธ]
|
| 249 |
+
|
| 250 |
+
- **๊ธฐ์ ํธ๋ ๋**: [์ปจํ
์คํธ์ ๋ฑ์ฅํ๋ ํต์ฌ AI ๊ธฐ์ ๋ค์ ๋น๊ต/๋ถ๋ฅํ์ฌ ์ ์ฒด ํธ๋ ๋ ํ๋ฆ ๋ถ์]
|
| 251 |
|
| 252 |
- **์ธํ๋ผ/์ฌํ์ ์์ธ**: [์ ๋ ฅ๋ง ๋ถ์กฑ, ๋์ค์ ๋ถ์๊ฐ, ํ๋์จ์ด์ ์ ์ฝ ์ฌํญ ๋ฑ ํต์ฌ ์์ธ]
|
| 253 |
|
|
|
|
| 261 |
- **์ค์ ์์์/๋ฉด์ ํ์ฉ Tip**: [์ง์๋๊ธฐ๋ ์ญ๋ ๊ธฐ์ ์ ์์ฑ ์ ๋ณธ์ธ์ ์ญ๋๊ณผ ์ด๋ป๊ฒ ์ฐ๊ณํ์ฌ ํ์ด๋ผ์ง์ ๋ํ ๋ง์ถค ๊ฐ์ด๋]
|
| 262 |
|
| 263 |
|
| 264 |
+
### ๐ฐ 4. ๊ทผ๊ฑฐ ๋ด์ค ์ถ์ฒ (GraphRAG ๊ฒ์ ๊ธฐ์ฌ)
|
| 265 |
|
| 266 |
+
> ์ปจํ
์คํธ์ ์ค์ ๋ก ์กด์ฌํ๋ ๊ธฐ์ฌ URL๋ง ๊ธฐ์ฌํ๊ณ , ์กด์ฌํ์ง ์๋ ๊ธฐ์ฌ๋ ์ ๋ ์ง์ด๋ด์ง ๋ง์ธ์.
|
| 267 |
+
> ๊ฒ์๋ ๊ธฐ์ฌ๊ฐ ์๋ ๊ฒฝ์ฐ ์๋ ํ์์ผ๋ก ์ด๊ฑฐํ๊ณ , ์์ผ๋ฉด ์ด ์น์
์ ์๋ตํ์ธ์.
|
| 268 |
+
>
|
| 269 |
+
> ์์:
|
| 270 |
+
> - *[๊ธฐ์ฌ ์ ๋ชฉ](๊ธฐ์ฌ URL)* โ ๋ณด๋์ผ์
|
| 271 |
|
| 272 |
---
|
| 273 |
|
|
|
|
| 319 |
tools=[
|
| 320 |
vector_cypher_retriever.convert_to_tool(
|
| 321 |
name="vector_retriever",
|
| 322 |
+
description=(
|
| 323 |
+
"๋ด์ค ๋ณธ๋ฌธ ์๋ฏธ ์ ์ฌ๋ ๊ธฐ๋ฐ ๊ฒ์ + ์ฐ๊ฒฐ๋ ์ํฐํฐ(๊ธฐ์
ยท๊ธฐ์ ยท์๋น์คยท๋ถ์ผ) ๊ด๊ณ ๊ทธ๋ํ ํ์. "
|
| 324 |
+
"ํน์ ์ฃผ์ /๊ธฐ์
/๊ธฐ์ ์ ๋ํด ๋ด์ค ๊ธฐ์ฌ ๋ฐ ๊ด๋ จ ๊ทธ๋ํ ๊ด๊ณ๋ฅผ ํจ๊ป ๋ถ์ํ ๋ ์ฌ์ฉ. "
|
| 325 |
+
"์: 'ํ๋์ฐจ AI ๋ด์ค', 'ํน์ ๊ธฐ์ ์ ์ ์ฉ ์ฌ๋ก'."
|
| 326 |
+
),
|
| 327 |
),
|
| 328 |
text2cypher_retriever.convert_to_tool(
|
| 329 |
name="text2cypher_retriever",
|
| 330 |
+
description=(
|
| 331 |
+
"์์ฐ์ด๋ฅผ Neo4j Cypher ์ฟผ๋ฆฌ๋ก ๋ณํํ์ฌ ๊ทธ๋ํ ๊ตฌ์กฐ๋ฅผ ์ง๊ณยทํ์. "
|
| 332 |
+
"'๊ฐ์ฅ ๋ง์ด ์ธ๊ธ๋ ๊ธฐ์ ', 'ํธ๋ ๋ ๋ถ์', 'ํน์ ๊ธฐ์
์ ์๋น์ค ๋ชฉ๋ก', "
|
| 333 |
+
"'์ด๋ค ๊ธฐ์
์ด X ๊ธฐ์ ์ ๊ฐ๋ฐํ๋', '์ต๊ทผ ๋ด์ค ์์ฝ' ๋ฑ "
|
| 334 |
+
"์ง๊ณ(COUNT/ORDER BY)๋ ๊ตฌ์กฐ์ ๊ด๊ณ ์ง์์ ๋ฐ๋์ ์ฌ์ฉ."
|
| 335 |
+
),
|
| 336 |
),
|
| 337 |
],
|
| 338 |
)
|