質問編集履歴
6
migrate_to_chroma.pyを記載し、文字数制限のためindex.htmlを削除
title
CHANGED
|
File without changes
|
body
CHANGED
|
@@ -332,102 +332,89 @@
|
|
|
332
332
|
```
|
|
333
333
|
|
|
334
334
|
```index.html
|
|
335
|
-
<!DOCTYPE html>
|
|
336
|
-
<html>
|
|
337
|
-
<head>
|
|
338
|
-
<meta charset="UTF-8">
|
|
339
|
-
<title>外部案件検索</title>
|
|
340
|
-
|
|
335
|
+
//文字数制限のため省略
|
|
341
336
|
|
|
337
|
+
```
|
|
338
|
+
```migrate_to_chroma.py
|
|
339
|
+
import sqlite3
|
|
340
|
+
import chromadb
|
|
342
|
-
|
|
341
|
+
import requests
|
|
342
|
+
import os
|
|
343
|
+
from dotenv import load_dotenv
|
|
343
344
|
|
|
345
|
+
load_dotenv()
|
|
344
|
-
|
|
346
|
+
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
|
|
345
347
|
|
|
346
|
-
|
|
348
|
+
def get_embedding(text: str):
|
|
347
|
-
|
|
349
|
+
url = f"https://generativelanguage.googleapis.com/v1beta/models/text-embedding-004:embedContent?key={GEMINI_API_KEY}"
|
|
348
|
-
|
|
349
|
-
<p>質問:</p>
|
|
350
|
-
<input type="text" name="question" style="width:400px;" required>
|
|
351
350
|
|
|
351
|
+
payload = {
|
|
352
|
-
|
|
352
|
+
"model": "models/text-embedding-004",
|
|
353
|
-
|
|
353
|
+
"content": {"parts": [{"text": text}]}
|
|
354
|
+
}
|
|
354
355
|
|
|
355
|
-
<br><br>
|
|
356
|
-
|
|
356
|
+
res = requests.post(url, json=payload)
|
|
357
|
-
|
|
357
|
+
res.raise_for_status()
|
|
358
358
|
|
|
359
|
-
|
|
359
|
+
return res.json()["embedding"]["values"]
|
|
360
360
|
|
|
361
|
-
<!-- ===== AI回答 ===== -->
|
|
362
|
-
{% if answer %}
|
|
363
|
-
<h2>AI回答</h2>
|
|
364
|
-
<p>{{ answer }}</p>
|
|
365
|
-
<hr>
|
|
366
|
-
{% endif %}
|
|
367
361
|
|
|
368
|
-
<!-- ===== 根拠表示 ===== -->
|
|
369
|
-
|
|
362
|
+
def migrate():
|
|
370
|
-
<h2>根拠(事例・マニュアル)</h2>
|
|
371
363
|
|
|
364
|
+
conn = sqlite3.connect("db.sqlite")
|
|
372
|
-
|
|
365
|
+
cur = conn.cursor()
|
|
373
|
-
<div style="margin-bottom:30px; border:1px solid #ccc; padding:10px;">
|
|
374
366
|
|
|
367
|
+
cur.execute("""
|
|
375
|
-
|
|
368
|
+
SELECT id, type, question, content, answer, page, image_path
|
|
369
|
+
FROM knowledge
|
|
370
|
+
""")
|
|
376
371
|
|
|
377
|
-
<!-- ===== 事例 ===== -->
|
|
378
|
-
|
|
372
|
+
rows = cur.fetchall()
|
|
379
|
-
|
|
373
|
+
conn.close()
|
|
380
374
|
|
|
381
|
-
{% if r.question %}
|
|
382
|
-
|
|
375
|
+
chroma = chromadb.PersistentClient(path="./chroma_db")
|
|
383
|
-
{% endif %}
|
|
384
376
|
|
|
377
|
+
collection = chroma.get_or_create_collection(
|
|
378
|
+
name="knowledge",
|
|
385
|
-
|
|
379
|
+
metadata={"hnsw:space": "cosine"}
|
|
380
|
+
)
|
|
386
381
|
|
|
387
|
-
|
|
382
|
+
for row in rows:
|
|
388
|
-
|
|
383
|
+
id_, type_, question, content, answer, page, image = row
|
|
389
|
-
{% else %}
|
|
390
|
-
<p>画像なし</p>
|
|
391
|
-
{% endif %}
|
|
392
|
-
{% endif %}
|
|
393
384
|
|
|
394
|
-
|
|
385
|
+
# ★ embedding対象(ここ重要)
|
|
395
|
-
{% if r.type == "manual" %}
|
|
396
|
-
|
|
386
|
+
text = f"{question or ''} {content or ''} {answer or ''}".strip()
|
|
397
387
|
|
|
398
|
-
|
|
388
|
+
if not text:
|
|
399
|
-
<p><b>内容:</b><br>{{ r.content }}</p>
|
|
400
|
-
|
|
389
|
+
continue
|
|
401
390
|
|
|
402
|
-
|
|
391
|
+
print("Embedding:", text[:50])
|
|
403
392
|
|
|
404
|
-
|
|
393
|
+
embedding = get_embedding(text)
|
|
405
|
-
<p><b>ページ:</b> {{ r.page }}</p>
|
|
406
|
-
{% endif %}
|
|
407
394
|
|
|
408
|
-
|
|
395
|
+
collection.add(
|
|
396
|
+
ids=[str(id_)],
|
|
409
|
-
|
|
397
|
+
embeddings=[embedding],
|
|
410
|
-
|
|
398
|
+
documents=[text],
|
|
399
|
+
metadatas=[{
|
|
411
|
-
|
|
400
|
+
"type": type_ or "",
|
|
401
|
+
"question": question or "",
|
|
402
|
+
"content": content or "",
|
|
403
|
+
"answer": answer or "",
|
|
404
|
+
"page": str(page) if page else "",
|
|
412
|
-
|
|
405
|
+
"image": image or ""
|
|
413
|
-
|
|
406
|
+
}]
|
|
407
|
+
)
|
|
414
408
|
|
|
415
|
-
|
|
409
|
+
print("✅ 移行完了")
|
|
416
410
|
|
|
417
|
-
<hr>
|
|
418
|
-
{% endfor %}
|
|
419
411
|
|
|
412
|
+
if __name__ == "__main__":
|
|
420
|
-
|
|
413
|
+
migrate()
|
|
421
414
|
|
|
422
|
-
</body>
|
|
423
|
-
</html>
|
|
424
|
-
```
|
|
425
|
-
```migrate_to_chroma.py
|
|
426
|
-
文字数制限で全部貼れないため省略
|
|
427
415
|
|
|
428
416
|
|
|
429
417
|
|
|
430
|
-
|
|
431
418
|
```
|
|
432
419
|
|
|
433
420
|
### 試したこと・調べたこと
|
5
migrate_to_chroma.pyについて漏れていたため修正
title
CHANGED
|
File without changes
|
body
CHANGED
|
@@ -422,7 +422,14 @@
|
|
|
422
422
|
</body>
|
|
423
423
|
</html>
|
|
424
424
|
```
|
|
425
|
+
```migrate_to_chroma.py
|
|
426
|
+
文字数制限で全部貼れないため省略
|
|
425
427
|
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
```
|
|
432
|
+
|
|
426
433
|
### 試したこと・調べたこと
|
|
427
434
|
- [ ] teratailやGoogle等で検索した
|
|
428
435
|
- [x] ソースコードを自分なりに変更した
|
4
文法の修正
title
CHANGED
|
File without changes
|
body
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
```ここに言語を入力
|
|
2
|
-
コード
|
|
3
|
-
|
|
1
|
+
### 実現したいこと
|
|
4
2
|
完全無料かつクレジットカード登録なしで、業務用チャットボットを構築したいと考えています。
|
|
5
3
|
|
|
6
4
|
対象は外部案件で、業務マニュアルやQ&Aが存在します。
|
3
一部修正
title
CHANGED
|
File without changes
|
body
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
```ここに言語を入力
|
|
2
|
+
コード
|
|
1
|
-
### 実現したいこと
|
|
3
|
+
```### 実現したいこと
|
|
2
4
|
完全無料かつクレジットカード登録なしで、業務用チャットボットを構築したいと考えています。
|
|
3
5
|
|
|
4
6
|
対象は外部案件で、業務マニュアルやQ&Aが存在します。
|
|
@@ -266,9 +268,9 @@
|
|
|
266
268
|
# ===== マニュアル =====外部案件のためマニュアルや事例の内容はダミーにしてあります
|
|
267
269
|
manual_data = [
|
|
268
270
|
{
|
|
269
|
-
"content": "
|
|
271
|
+
"content": "赤線や青線がない場合の処理",
|
|
270
|
-
"keywords": "
|
|
272
|
+
"keywords": "赤線,青線,
|
|
271
|
-
"answer": "
|
|
273
|
+
"answer": "赤線や青線がなければそのままSaveする。",
|
|
272
274
|
"image_path": "3.png",
|
|
273
275
|
"page": 3,
|
|
274
276
|
"section":"(1) 処理手順"
|
2
一部修正
title
CHANGED
|
File without changes
|
body
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
を知りたいです。
|
|
17
17
|
|
|
18
18
|
### 発生している問題・分からないこと
|
|
19
|
-
この案件では
|
|
19
|
+
この案件では伝票画像などの画像情報が非常に重要で、
|
|
20
20
|
回答は「質問文」ではなく「画像の内容」を基準に判断する必要があります。
|
|
21
21
|
ただし、OCRでは読み取り精度に限界があり、正確にテキスト化できないケースも多いため画像フォルダにマニュアル画像を入れてAPIに渡しています。
|
|
22
22
|
|
1
マニュアルの画像の渡し方について訂正
title
CHANGED
|
File without changes
|
body
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
### 発生している問題・分からないこと
|
|
19
19
|
この案件ではレシート画像などの画像情報が非常に重要で、
|
|
20
20
|
回答は「質問文」ではなく「画像の内容」を基準に判断する必要があります。
|
|
21
|
-
ただし、OCRでは読み取り精度に限界があり、正確にテキスト化できないケースも多い
|
|
21
|
+
ただし、OCRでは読み取り精度に限界があり、正確にテキスト化できないケースも多いため画像フォルダにマニュアル画像を入れてAPIに渡しています。
|
|
22
22
|
|
|
23
23
|
さらに問題として、
|
|
24
24
|
質問者の前提が誤っているケース(例:対象外と書かれていないのに対象外だと思い込んでいる)が多く、
|