Skip to content

Commit 13bb251

Browse files
committed
examples/fast_dev_demo.py: 修复导入错误,使用 create_storage 和 ZhipuChat。
examples/zhipu_agent.py: 修复导入错误,使用 ZhipuChat。 examples/full_tool_test.py: (可选) 同样需要更新模型实例化方式。 examples/knowledge_rag_demo.py (新增): 专门用于验证 RAG 工具链和 Pydantic 修复。 examples/compose/workflow_next_resume_demo.py: 更新存储初始化方式以验证工厂注册修复。
1 parent 19f2b68 commit 13bb251

File tree

5 files changed

+150
-54
lines changed

5 files changed

+150
-54
lines changed

examples/compose/workflow_next_resume_demo.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
from gecko.compose.workflow import Workflow, WorkflowContext, CheckpointStrategy
1818
from gecko.compose.nodes import step, Next
19-
from gecko.plugins.storage.backends.sqlite import SQLiteStorage
19+
# [Fix] 使用 create_storage 替代直接实例化,验证 Bug #7 的注册装饰器修复
20+
from gecko.plugins.storage.factory import create_storage
2021
from gecko.core.logging import setup_logging
2122
from gecko.core.exceptions import WorkflowError
2223

@@ -50,18 +51,20 @@ async def next_node(context: WorkflowContext):
5051
return f"Processed({inp})"
5152

5253
async def main():
53-
db_file = "next_resume.db"
54+
# [Fix] 使用 explicit relative path (./) to avoid writing to root
55+
db_file = "./next_resume.db"
5456
db_url = f"sqlite:///{db_file}"
5557

5658
if os.path.exists(db_file):
5759
os.remove(db_file)
5860

59-
storage = SQLiteStorage(db_url)
60-
await storage.initialize()
61+
# [Verification] Bug #7: 如果 SQLiteStorage 没加 @register_storage,这里会报错
62+
storage = await create_storage(db_url)
6163

6264
wf = Workflow(
6365
name="NextResumeFlow",
64-
storage=storage,
66+
storage=storage, # type: ignore
67+
# [Key] 必须为 ALWAYS,确保 Next 指令产生时立即持久化,以便验证 Resume
6568
checkpoint_strategy=CheckpointStrategy.ALWAYS
6669
)
6770

@@ -101,7 +104,13 @@ async def main():
101104

102105
await storage.shutdown()
103106
if os.path.exists(db_file):
104-
os.remove(db_file)
107+
try:
108+
os.remove(db_file)
109+
if os.path.exists(db_file + ".lock"): os.remove(db_file + ".lock")
110+
if os.path.exists(db_file + "-wal"): os.remove(db_file + "-wal")
111+
if os.path.exists(db_file + "-shm"): os.remove(db_file + "-shm")
112+
except:
113+
pass
105114

106115
if __name__ == "__main__":
107116
asyncio.run(main())

examples/compose/workflow_resume_demo.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# examples/workflow_resume_demo.py
1+
# examples/compose/workflow_resume_demo.py
22
"""
33
Workflow 断点恢复示例 (Resumability Demo)
44
@@ -16,7 +16,8 @@
1616

1717
from gecko.compose.workflow import Workflow, WorkflowContext, CheckpointStrategy
1818
from gecko.compose.nodes import step, Next
19-
from gecko.plugins.storage.backends.sqlite import SQLiteStorage
19+
# [Fix] Use create_storage factory
20+
from gecko.plugins.storage.factory import create_storage
2021
from gecko.core.logging import setup_logging
2122
# [Fix] Import WorkflowError
2223
from gecko.core.exceptions import WorkflowError
@@ -66,7 +67,8 @@ async def step_c(context: WorkflowContext):
6667
# ========================= 主流程 =========================
6768

6869
async def main():
69-
db_file = "resume_demo.db"
70+
# [Fix] Use explicit relative path
71+
db_file = "./resume_demo.db"
7072
db_url = f"sqlite:///{db_file}"
7173

7274
# 清理旧数据确保 Demo 可重复
@@ -79,13 +81,13 @@ async def main():
7981
print(f"🔌 初始化存储: {db_url}")
8082
# 1. 初始化存储
8183
# 断点恢复必须依赖持久化存储
82-
storage = SQLiteStorage(db_url)
83-
await storage.initialize()
84+
# [Fix] Use factory
85+
storage = await create_storage(db_url)
8486

8587
# 2. 定义工作流
8688
wf = Workflow(
8789
name="ResumableFlow",
88-
storage=storage,
90+
storage=storage, # type: ignore
8991
# [Phase 3 Feature] 策略: ALWAYS (每步保存),这是 Resume 的前提
9092
checkpoint_strategy=CheckpointStrategy.ALWAYS
9193
)
@@ -140,6 +142,7 @@ async def main():
140142
try:
141143
os.remove(db_file)
142144
# SQLite WAL 模式可能会产生额外文件
145+
if os.path.exists(db_file + ".lock"): os.remove(db_file + ".lock")
143146
if os.path.exists(db_file + "-wal"): os.remove(db_file + "-wal")
144147
if os.path.exists(db_file + "-shm"): os.remove(db_file + "-shm")
145148
except:

examples/fast_dev_demo.py

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,43 +3,50 @@
33
import os
44
from gecko.core.builder import AgentBuilder
55
from gecko.core.message import Message
6-
# [Fix] Import ZhipuChat
7-
from gecko.plugins.models.presets.zhipu import ZhipuChat
8-
from gecko.plugins.storage.backends.sqlite import SQLiteStorage
6+
# [Fix] 使用标准的类导入,而非旧版 helper 函数
7+
from gecko.plugins.models import ZhipuChat
8+
# [Fix] 使用工厂方法创建存储
9+
from gecko.plugins.storage.factory import create_storage
910

1011
async def main():
1112
api_key = os.getenv("ZHIPU_API_KEY")
12-
13-
# [Fix] 创建 Storage 实例
14-
storage = SQLiteStorage("sqlite://./dev_sessions.db")
15-
await storage.initialize() # 确保存储初始化
13+
if not api_key:
14+
print("Skipping: ZHIPU_API_KEY not set")
15+
return
1616

17-
try:
18-
# [Fix] 创建 Model 实例
19-
model = ZhipuChat(api_key=api_key or "mock_key", model="glm-4-flash")
17+
# [Fix] 使用 factory 创建并初始化存储
18+
# 注意:SQLite URL 相对路径需要 3 个斜杠 (sqlite:///./path)
19+
# 验证 Bug #7 (SQLite 注册) 是否修复,工厂应能正确加载 sqlite
20+
storage = await create_storage("sqlite:///./dev_sessions.db")
2021

21-
agent = (AgentBuilder()
22-
.with_model(model)
23-
.with_session_id("user_123")
24-
.with_storage(storage)
25-
.build())
22+
agent = (AgentBuilder()
23+
# [Fix] 显式实例化模型
24+
.with_model(ZhipuChat(api_key=api_key, model="glm-4-flash", temperature=0.3))
25+
.with_session_id("user_123")
26+
.with_storage(storage) # type: ignore
27+
.build())
2628

27-
# 第一次运行:记住名字
28-
print("--- Round 1 ---")
29-
output1 = await agent.run([Message(role="user", content="我叫张三,以后叫我老张")])
30-
print("AI:", output1.content) # type: ignore
29+
# 第一次运行
30+
print("--- Round 1 ---")
31+
output1 = await agent.run([Message(role="user", content="我叫张三,以后叫我老张")])
32+
print("AI:", output1.content) # type: ignore
3133

32-
# 第二次运行:验证记忆恢复
33-
print("\n--- Round 2 ---")
34-
output2 = await agent.run([Message(role="user", content="我叫什么名字?")])
35-
print("AI:", output2.content) # type: ignore
36-
37-
finally:
38-
await storage.shutdown()
39-
# 清理临时文件
40-
if os.path.exists("dev_sessions.db"):
41-
try: os.remove("dev_sessions.db")
42-
except: pass
34+
# 第二次运行:验证记忆恢复
35+
print("\n--- Round 2 ---")
36+
output2 = await agent.run([Message(role="user", content="我叫什么名字?")])
37+
print("AI:", output2.content) # type: ignore
38+
39+
# 清理
40+
await storage.shutdown()
41+
if os.path.exists("dev_sessions.db"):
42+
try:
43+
os.remove("dev_sessions.db")
44+
# 清理可能存在的锁文件和 WAL 文件
45+
if os.path.exists("dev_sessions.db.lock"): os.remove("dev_sessions.db.lock")
46+
if os.path.exists("dev_sessions.db-wal"): os.remove("dev_sessions.db-wal")
47+
if os.path.exists("dev_sessions.db-shm"): os.remove("dev_sessions.db-shm")
48+
except OSError:
49+
pass
4350

4451
if __name__ == "__main__":
4552
asyncio.run(main())
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# examples/knowledge_rag_demo.py
2+
"""
3+
RAG 知识库演示
4+
5+
验证功能:
6+
1. 文档入库 (IngestionPipeline)
7+
2. 向量检索 (RetrievalTool) -> 验证 Bug #9 修复 (PrivateAttr)
8+
3. 结合 Agent 进行问答
9+
"""
10+
import asyncio
11+
import os
12+
import shutil
13+
from gecko.core.agent import Agent
14+
from gecko.core.builder import AgentBuilder
15+
from gecko.core.message import Message
16+
from gecko.plugins.storage.factory import create_storage
17+
from gecko.plugins.knowledge import IngestionPipeline, Document
18+
from gecko.plugins.knowledge.tool import RetrievalTool
19+
from gecko.plugins.models import ZhipuChat
20+
# 假设我们使用 Zhipu 的 Embedding (通过 LiteLLMEmbedder)
21+
from gecko.plugins.models.presets.zhipu import ZhipuChat # Zhipu SDK 暂无单独 Embedder Preset,需手动配置
22+
from gecko.plugins.models.embedding import LiteLLMEmbedder
23+
from gecko.plugins.models.config import ModelConfig
24+
25+
async def main():
26+
api_key = os.getenv("ZHIPU_API_KEY")
27+
if not api_key:
28+
print("Please set ZHIPU_API_KEY")
29+
return
30+
31+
# 1. 准备向量存储 (Chroma)
32+
persist_path = "./demo_rag_db"
33+
if os.path.exists(persist_path): shutil.rmtree(persist_path)
34+
35+
vector_store = await create_storage(f"chroma://{persist_path}")
36+
37+
# 2. 准备 Embedding 模型
38+
embedder = LiteLLMEmbedder(
39+
config=ModelConfig(model_name="zhipu/embedding-2", api_key=api_key),
40+
dimension=1024
41+
)
42+
43+
# 3. 数据入库
44+
print("🚀 Ingesting documents...")
45+
pipeline = IngestionPipeline(vector_store, embedder)
46+
47+
# 创建临时文件用于测试
48+
with open("gecko_intro.txt", "w") as f:
49+
f.write("Gecko 是一个高性能的 AI Agent 框架,支持异步编排和插件化设计。它由 Python 编写。")
50+
51+
await pipeline.run(["gecko_intro.txt"])
52+
53+
# 4. 初始化检索工具
54+
# [Verification] Bug #9: 如果 RetrievalTool 没有使用 PrivateAttr,这里会抛出 Pydantic ValidationError
55+
print("\n🔧 Initializing RetrievalTool...")
56+
rag_tool = RetrievalTool(
57+
vector_store=vector_store,
58+
embedder=embedder,
59+
top_k=1
60+
)
61+
print("✅ Tool initialized successfully (PrivateAttr fix works).")
62+
63+
# 5. 构建 Agent
64+
model = ZhipuChat(api_key=api_key, model="glm-4-flash")
65+
agent = AgentBuilder()\
66+
.with_model(model)\
67+
.with_tools([rag_tool])\
68+
.build()
69+
70+
# 6. 提问
71+
query = "Gecko 框架是用什么语言编写的?"
72+
print(f"\n👤 User: {query}")
73+
response = await agent.run(query)
74+
print(f"🤖 Agent: {response.content}") # type: ignore
75+
76+
# 清理
77+
await vector_store.shutdown()
78+
if os.path.exists("gecko_intro.txt"): os.remove("gecko_intro.txt")
79+
if os.path.exists(persist_path): shutil.rmtree(persist_path)
80+
81+
if __name__ == "__main__":
82+
asyncio.run(main())

examples/zhipu_agent.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,18 @@
33
import os
44
from gecko.core.builder import AgentBuilder
55
from gecko.core.message import Message
6-
# [Fix] 使用新的 Presets 类
7-
from gecko.plugins.models.presets.zhipu import ZhipuChat
6+
# [Fix] Correct import
7+
from gecko.plugins.models import ZhipuChat
88

99
async def main():
1010
api_key = os.getenv("ZHIPU_API_KEY")
11-
if not api_key:
12-
print("Error: ZHIPU_API_KEY not found.")
13-
return
11+
if not api_key: return
1412

15-
# [Fix] 实例化类
16-
model = ZhipuChat(api_key=api_key, model="glm-4-flash", temperature=0.8)
13+
agent = AgentBuilder()\
14+
.with_model(ZhipuChat(api_key=api_key, model="glm-4-flash"))\
15+
.build()
1716

18-
agent = AgentBuilder().with_model(model).build()
19-
20-
output = await agent.run([
21-
Message(role="user", content="用中文介绍一下 Gecko 框架的插件化设计优势")
22-
])
17+
output = await agent.run("用中文介绍一下 Gecko 框架的优势")
2318
print(output.content) # type: ignore
2419

2520
if __name__ == "__main__":

0 commit comments

Comments
 (0)