-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStep03_rag_answer_demo.py
More file actions
146 lines (111 loc) · 3.83 KB
/
Copy pathStep03_rag_answer_demo.py
File metadata and controls
146 lines (111 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import os
from typing import List, Dict, Any
from dotenv import load_dotenv
from openai import OpenAI
from rag.Step01_pdf_chunk_demo import chunk_pdf
from rag.Step02_vector_search_demo import SimpleVectorStore
load_dotenv()
client = OpenAI(
api_key=os.environ.get("DEEPSEEK_API_KEY"), base_url="https://api.deepseek.com"
)
def format_evidence(results: List[Dict[str, Any]]) -> str:
"""
Convert retrieved chunks into evidence blocks.
"""
evidence_blocks = []
for i, item in enumerate(results, start=1):
location_parts = []
if item.get("page") is not None:
location_parts.append(f"page: {item['page']}")
if item.get("sheet_name"):
location_parts.append(f"sheet: {item['sheet_name']}")
if item.get("row_index") is not None:
location_parts.append(f"row: {item['row_index']}")
location_str = "\n".join(location_parts)
if location_str:
location_str = "\n" + location_str
block = f"""[{i}]
source: {item["source"]}{location_str}
chunk_id: {item["chunk_id"]}
text:
{item["text"]}
"""
evidence_blocks.append(block)
return "\n".join(evidence_blocks)
def build_prompt(question: str, evidence: str) -> str:
return f"""
You are a careful document QA assistant.
You must answer the user's question using ONLY the evidence provided below.
Rules:
1. Do not use outside knowledge.
2. If the evidence is insufficient, say: "根据现有资料无法确定。"
3. Cite evidence using bracket IDs like [1], [2].
4. Every factual claim should be supported by at least one citation.
5. Keep the answer concise and directly address the question.
Evidence:
{evidence}
Question:
{question}
Answer in Chinese:
""".strip()
def answer_with_llm(question: str, retrieved_chunks: List[Dict[str, Any]]) -> str:
evidence = format_evidence(retrieved_chunks)
prompt = build_prompt(question, evidence)
response = client.chat.completions.create(
model="deepseek-v4-pro",
messages=[
{
"role": "system",
"content": "You are a rigorous retrieval-augmented generation assistant.",
},
{"role": "user", "content": prompt},
],
temperature=0.1,
)
return response.choices[0].message.content
def main():
file_path = "data/project.pdf"
print("Loading and chuck PDF ... ")
chunks = chunk_pdf(file_path)
print(f"Split into {len(chunks)} chunks")
print("Building vector index...")
store = SimpleVectorStore()
store.build(chunks)
while True:
question = input("\nQuestion: ").strip()
if question.lower() in {"exit", "quit", "q"}:
break
print("\nRetrieving evidence...")
retrieved = store.search(question, top_k=5)
print("\nRetrieved evidence:")
print("=" * 80)
for i, item in enumerate(retrieved, start=1):
print(f"[{i}] score={item['score']:.4f}")
print(
f"source={item['source']} page={item['page']} chunk_id={item['chunk_id']}"
)
print(item["text"][:500])
print("-" * 80)
print("\nGenerating answer...")
answer = answer_with_llm(question, retrieved)
print("\nAnswer:")
print("=" * 80)
print(answer)
def main1():
response = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[
{"role": "system", "content": "You are a helpful assistant"},
{
"role": "user",
"content": "Hello, who are you , and what is your training time ?",
},
],
stream=False,
reasoning_effort="high",
extra_body={"thinking": {"type": "enabled"}},
)
print(response.choices[0].message.content)
if __name__ == "__main__":
# main()
main1()