-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathllm_multi_turn_conversation.py
More file actions
119 lines (90 loc) · 3.55 KB
/
Copy pathllm_multi_turn_conversation.py
File metadata and controls
119 lines (90 loc) · 3.55 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
"""
Multi-turn conversation example with OpenGradient TEE-verified LLM.
Demonstrates how to maintain conversation history across multiple turns,
enabling context-aware responses with full cryptographic verification
of every inference step.
Usage:
export OG_PRIVATE_KEY="your_private_key"
python examples/llm_multi_turn_conversation.py
"""
import asyncio
import os
import opengradient as og
def add_user_message(history: list, content: str) -> list:
"""Append a user message to the conversation history."""
return history + [{"role": "user", "content": content}]
def add_assistant_message(history: list, content: str) -> list:
"""Append an assistant message to the conversation history."""
return history + [{"role": "assistant", "content": content}]
async def chat_turn(
llm: og.LLM,
history: list,
user_input: str,
model: og.TEE_LLM = og.TEE_LLM.GEMINI_2_5_FLASH,
) -> tuple[str, list, str | None]:
"""
Execute a single conversation turn.
Args:
llm: Initialized LLM client.
history: Current conversation history.
user_input: The user's message for this turn.
model: TEE_LLM model to use.
Returns:
Tuple of (assistant_reply, updated_history, data_settlement_transaction_hash).
"""
history = add_user_message(history, user_input)
result = await llm.chat(
model=model,
messages=history,
max_tokens=500,
temperature=0.7,
)
assert isinstance(result, og.TextGenerationOutput)
assert result.chat_output is not None
reply = str(result.chat_output["content"])
history = add_assistant_message(history, reply)
return reply, history, result.data_settlement_transaction_hash
async def main():
private_key = os.environ.get("OG_PRIVATE_KEY")
if not private_key:
raise ValueError("OG_PRIVATE_KEY environment variable is not set.")
llm = og.LLM(private_key=private_key)
llm.ensure_opg_approval(min_allowance=0.5)
model = og.TEE_LLM.GEMINI_2_5_FLASH
print(f"Model : {model.value}")
print(f"Mode : Multi-turn conversation with TEE verification")
print("=" * 60)
# System prompt sets the assistant persona for the whole conversation
history = [
{
"role": "system",
"content": ("You are a concise Python tutor. Give short, clear answers with code examples when helpful."),
}
]
# --- Turn 1 ---
question_1 = "What is a Python decorator?"
print(f"\nUser : {question_1}")
reply_1, history, tx_1 = await chat_turn(llm, history, question_1, model)
print(f"Assistant : {reply_1}")
print(f"[tx: {tx_1}]")
# --- Turn 2 — follow-up referencing Turn 1 ---
question_2 = "Can you show me a real-world example of one?"
print(f"\nUser : {question_2}")
reply_2, history, tx_2 = await chat_turn(llm, history, question_2, model)
print(f"Assistant : {reply_2}")
print(f"[tx: {tx_2}]")
# --- Turn 3 — deeper follow-up ---
question_3 = "How would I stack two decorators on the same function?"
print(f"\nUser : {question_3}")
reply_3, history, tx_3 = await chat_turn(llm, history, question_3, model)
print(f"Assistant : {reply_3}")
print(f"[tx: {tx_3}]")
# Summary
print("\n" + "=" * 60)
print(f"Total turns : {len([m for m in history if m['role'] == 'user'])}")
print(f"Total messages : {len(history)}")
print("Transaction hashes (verifiable on-chain):")
for i, tx in enumerate([tx_1, tx_2, tx_3], 1):
print(f" Turn {i}: {tx}")
if __name__ == "__main__":
asyncio.run(main())