ni.agentkit 0.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. agentkit/__init__.py +57 -0
  2. agentkit/_cli.py +72 -0
  3. agentkit/agents/__init__.py +0 -0
  4. agentkit/agents/agent.py +364 -0
  5. agentkit/agents/base_agent.py +59 -0
  6. agentkit/agents/orchestrators.py +62 -0
  7. agentkit/docs/Architecture.md +536 -0
  8. agentkit/docs/QuickStart.md +806 -0
  9. agentkit/docs/README.md +119 -0
  10. agentkit/docs/Reference.md +576 -0
  11. agentkit/docs/TestReport.md +80 -0
  12. agentkit/examples/__init__.py +0 -0
  13. agentkit/examples/ollama/01_basic_chat.py +34 -0
  14. agentkit/examples/ollama/02_tool_calling.py +70 -0
  15. agentkit/examples/ollama/03_skill_usage.py +86 -0
  16. agentkit/examples/ollama/04_multi_agent.py +84 -0
  17. agentkit/examples/ollama/05_guardrail.py +101 -0
  18. agentkit/examples/ollama/06_orchestration.py +123 -0
  19. agentkit/examples/ollama/07_sync_async_stream.py +180 -0
  20. agentkit/examples/ollama/08_memory.py +201 -0
  21. agentkit/examples/ollama/README.md +51 -0
  22. agentkit/examples/ollama/__init__.py +0 -0
  23. agentkit/examples/quickstart.py +204 -0
  24. agentkit/examples/standard/01_basic_chat.py +33 -0
  25. agentkit/examples/standard/02_tool_calling.py +70 -0
  26. agentkit/examples/standard/03_skill_usage.py +89 -0
  27. agentkit/examples/standard/04_multi_agent.py +87 -0
  28. agentkit/examples/standard/05_guardrail.py +104 -0
  29. agentkit/examples/standard/06_orchestration.py +122 -0
  30. agentkit/examples/standard/07_sync_async_stream.py +171 -0
  31. agentkit/examples/standard/08_memory.py +140 -0
  32. agentkit/examples/standard/README.md +31 -0
  33. agentkit/examples/standard/__init__.py +0 -0
  34. agentkit/examples/test_ollama.py +272 -0
  35. agentkit/llm/__init__.py +0 -0
  36. agentkit/llm/adapters/__init__.py +0 -0
  37. agentkit/llm/adapters/anthropic_adapter.py +192 -0
  38. agentkit/llm/adapters/google_adapter.py +184 -0
  39. agentkit/llm/adapters/ollama_adapter.py +250 -0
  40. agentkit/llm/adapters/openai_adapter.py +183 -0
  41. agentkit/llm/adapters/openai_compatible.py +35 -0
  42. agentkit/llm/base.py +66 -0
  43. agentkit/llm/cache.py +121 -0
  44. agentkit/llm/middleware.py +133 -0
  45. agentkit/llm/registry.py +138 -0
  46. agentkit/llm/types.py +191 -0
  47. agentkit/memory/__init__.py +0 -0
  48. agentkit/memory/base.py +47 -0
  49. agentkit/memory/mem0_provider.py +48 -0
  50. agentkit/runner/__init__.py +0 -0
  51. agentkit/runner/context.py +47 -0
  52. agentkit/runner/events.py +36 -0
  53. agentkit/runner/runner.py +105 -0
  54. agentkit/safety/__init__.py +0 -0
  55. agentkit/safety/guardrails.py +55 -0
  56. agentkit/safety/permissions.py +41 -0
  57. agentkit/skills/__init__.py +0 -0
  58. agentkit/skills/loader.py +90 -0
  59. agentkit/skills/models.py +106 -0
  60. agentkit/skills/registry.py +48 -0
  61. agentkit/tools/__init__.py +0 -0
  62. agentkit/tools/base_tool.py +44 -0
  63. agentkit/tools/function_tool.py +118 -0
  64. agentkit/tools/skill_toolset.py +199 -0
  65. agentkit/utils/__init__.py +0 -0
  66. agentkit/utils/schema.py +83 -0
  67. ni_agentkit-0.3.1.dist-info/METADATA +157 -0
  68. ni_agentkit-0.3.1.dist-info/RECORD +72 -0
  69. ni_agentkit-0.3.1.dist-info/WHEEL +5 -0
  70. ni_agentkit-0.3.1.dist-info/entry_points.txt +2 -0
  71. ni_agentkit-0.3.1.dist-info/licenses/LICENSE +21 -0
  72. ni_agentkit-0.3.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,180 @@
1
+ """
2
+ 示例:三种运行方式对比 — 同步 / 异步 / 流式(Ollama 本地版)
3
+
4
+ 演示 Runner 的三种运行方式在同一个 Agent 上的用法差异。
5
+
6
+ 运行前请确保 Ollama 已启动:
7
+ ollama serve
8
+ ollama pull qwen3.5:cloud
9
+
10
+ 运行:
11
+ python examples/ollama/07_sync_async_stream.py
12
+ """
13
+ import asyncio
14
+ import sys
15
+ import os
16
+ import time
17
+
18
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", ".."))
19
+
20
+ from agentkit import Agent, Runner, function_tool
21
+
22
+
23
+ # ===== 定义一个简单工具 =====
24
+
25
+ @function_tool
26
+ def get_weather(city: str) -> str:
27
+ """获取指定城市的天气信息"""
28
+ return {"北京": "晴,25°C", "上海": "多云,22°C"}.get(city, f"{city}:暂无数据")
29
+
30
+
31
+ # ===== 创建 Agent(三种方式共用同一个) =====
32
+
33
+ agent = Agent(
34
+ name="assistant",
35
+ instructions="你是一个简洁的中文助手。回答尽量简短。",
36
+ model="ollama/qwen3.5:cloud",
37
+ tools=[get_weather],
38
+ )
39
+
40
+
41
+ # ============================================================
42
+ # 方式 1:同步运行 — Runner.run_sync()
43
+ # 最简单,一行搞定。适合脚本和快速测试。
44
+ # ============================================================
45
+
46
+ def demo_sync():
47
+ print("=" * 50)
48
+ print(" 方式 1:同步运行 — Runner.run_sync()")
49
+ print("=" * 50)
50
+
51
+ start = time.time()
52
+ result = Runner.run_sync(agent, input="北京今天天气如何?")
53
+ elapsed = time.time() - start
54
+
55
+ if result.success:
56
+ print(f" ✅ 回复: {result.final_output}")
57
+ else:
58
+ print(f" ❌ 错误: {result.error}")
59
+ print(f" ⏱️ 耗时: {elapsed:.1f}s")
60
+
61
+
62
+ # ============================================================
63
+ # 方式 2:异步运行 — await Runner.run()
64
+ # 推荐用于 Web 服务、并发任务等生产场景。
65
+ # ============================================================
66
+
67
+ async def demo_async():
68
+ print(f"\n{'=' * 50}")
69
+ print(" 方式 2:异步运行 — await Runner.run()")
70
+ print("=" * 50)
71
+
72
+ start = time.time()
73
+ result = await Runner.run(agent, input="上海今天天气如何?")
74
+ elapsed = time.time() - start
75
+
76
+ if result.success:
77
+ print(f" ✅ 回复: {result.final_output}")
78
+ else:
79
+ print(f" ❌ 错误: {result.error}")
80
+ print(f" ⏱️ 耗时: {elapsed:.1f}s")
81
+
82
+
83
+ # ============================================================
84
+ # 方式 2b:异步并发 — 同时运行多个 Agent
85
+ # 这是异步的核心优势:多个 LLM 调用可以并发执行。
86
+ # ============================================================
87
+
88
+ async def demo_async_concurrent():
89
+ print(f"\n{'=' * 50}")
90
+ print(" 方式 2b:异步并发 — 同时运行多个请求")
91
+ print("=" * 50)
92
+
93
+ queries = [
94
+ "1+1等于几?只回答数字",
95
+ "北京今天天气如何?",
96
+ "用一句话解释什么是 Python",
97
+ ]
98
+
99
+ start = time.time()
100
+
101
+ # asyncio.gather 并发执行 3 个请求
102
+ results = await asyncio.gather(*[
103
+ Runner.run(agent, input=q) for q in queries
104
+ ])
105
+
106
+ elapsed = time.time() - start
107
+
108
+ for q, r in zip(queries, results):
109
+ status = f"✅ {r.final_output}" if r.success else f"❌ {r.error}"
110
+ print(f" [{q[:15]:15s}] → {status}")
111
+
112
+ print(f" ⏱️ 3 个请求并发总耗时: {elapsed:.1f}s(如果串行需要约 3 倍时间)")
113
+
114
+
115
+ # ============================================================
116
+ # 方式 3:流式运行 — async for event in Runner.run_streamed()
117
+ # 实时获取每一个事件,适合聊天界面、进度展示。
118
+ # ============================================================
119
+
120
+ async def demo_stream():
121
+ print(f"\n{'=' * 50}")
122
+ print(" 方式 3:流式运行 — Runner.run_streamed()")
123
+ print("=" * 50)
124
+
125
+ print(" 📡 实时事件流:")
126
+
127
+ start = time.time()
128
+ async for event in Runner.run_streamed(agent, input="北京今天天气如何?"):
129
+ elapsed = time.time() - start
130
+ # 每个事件实时打印
131
+ if event.type == "llm_response":
132
+ has_tools = "有工具调用" if event.data.has_tool_calls else "纯文本"
133
+ print(f" [{elapsed:5.1f}s] 🤖 LLM 响应 ({has_tools})")
134
+ elif event.type == "tool_result":
135
+ tool_name = event.data.get("tool", "?")
136
+ tool_result = event.data.get("result", "")
137
+ print(f" [{elapsed:5.1f}s] 🔧 工具 {tool_name} → {tool_result}")
138
+ elif event.type == "final_output":
139
+ print(f" [{elapsed:5.1f}s] ✅ 最终输出: {event.data}")
140
+ else:
141
+ print(f" [{elapsed:5.1f}s] 📋 {event.type}: {str(event.data)[:60]}")
142
+
143
+
144
+ # ============================================================
145
+ # 主入口
146
+ # ============================================================
147
+
148
+ def run_all():
149
+ """先同步跑一个,再 asyncio.run 跑异步的"""
150
+
151
+ print("🚀 AgentKit — 三种运行方式对比\n")
152
+
153
+ # 方式 1:同步(必须在 asyncio.run 之外调用)
154
+ demo_sync()
155
+
156
+ # 方式 2、2b、3:异步(在同一个事件循环中运行)
157
+ async def async_demos():
158
+ await demo_async()
159
+ await demo_async_concurrent()
160
+ await demo_stream()
161
+
162
+ asyncio.run(async_demos())
163
+
164
+ print(f"\n{'=' * 50}")
165
+ print(" 全部演示完成 🎉")
166
+ print("=" * 50)
167
+ print("""
168
+ 📝 总结:
169
+ run_sync() — 最简单,一行代码,适合脚本和测试
170
+ await run() — 异步核心,可并发执行多个请求
171
+ run_streamed() — 实时事件流,适合聊天 UI 和进度展示
172
+
173
+ ⚠️ 注意:run_sync() 内部调用 asyncio.run(),因此不能在
174
+ 已有事件循环中使用。如果你的代码已经是 async 的,
175
+ 请直接用 await Runner.run()。
176
+ """)
177
+
178
+
179
+ if __name__ == "__main__":
180
+ run_all()
@@ -0,0 +1,201 @@
1
+ """
2
+ 示例 8:记忆系统 — 让 Agent 拥有跨会话长期记忆(Ollama 本地版)
3
+
4
+ 演示三种记忆用法:
5
+ A. 无记忆(默认)— 每次对话互相独立
6
+ B. SimpleMemory(内置)— 轻量内存记忆,无需外部依赖,适合开发测试
7
+ C. Mem0Provider(生产级)— 基于向量数据库的长期记忆(需安装 mem0ai + qdrant)
8
+
9
+ 运行前请确保 Ollama 已启动:
10
+ ollama serve
11
+ ollama pull qwen3.5:cloud
12
+
13
+ 运行:
14
+ python examples/ollama/08_memory.py
15
+ """
16
+ import asyncio
17
+ import sys
18
+ import os
19
+
20
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", ".."))
21
+
22
+ from agentkit import Agent, Runner, BaseMemoryProvider, Memory
23
+
24
+
25
+ MODEL = "ollama/qwen3.5:cloud"
26
+
27
+
28
+ # ============================================================
29
+ # SimpleMemory:轻量内存记忆实现(无需外部依赖)
30
+ #
31
+ # 适合开发和测试。进程退出后记忆丢失。
32
+ # 生产环境请使用 Mem0Provider(见示例 C)。
33
+ # ============================================================
34
+
35
+ class SimpleMemory(BaseMemoryProvider):
36
+ """最简单的内存记忆实现——基于关键词匹配"""
37
+
38
+ def __init__(self):
39
+ self._store: list[Memory] = []
40
+ self._counter = 0
41
+
42
+ async def add(self, content, *, user_id=None, agent_id=None, metadata=None):
43
+ self._counter += 1
44
+ m = Memory(id=str(self._counter), content=content)
45
+ self._store.append(m)
46
+ print(f" 💾 记忆已存储: {content[:60]}...")
47
+ return [m]
48
+
49
+ async def search(self, query, *, user_id=None, agent_id=None, limit=10):
50
+ # 简单的关键词重叠匹配(生产环境应该用向量相似度搜索)
51
+ query_words = set(query)
52
+ scored = []
53
+ for m in self._store:
54
+ overlap = len(query_words & set(m.content))
55
+ if overlap > 0:
56
+ scored.append((overlap, m))
57
+ scored.sort(reverse=True, key=lambda x: x[0])
58
+ results = [m for _, m in scored[:limit]]
59
+ if results:
60
+ print(f" 🔍 检索到 {len(results)} 条相关记忆")
61
+ return results
62
+
63
+ async def get_all(self, *, user_id=None, agent_id=None):
64
+ return list(self._store)
65
+
66
+ async def delete(self, memory_id):
67
+ self._store = [m for m in self._store if m.id != memory_id]
68
+ return True
69
+
70
+
71
+ # ============================================================
72
+ # 演示 A:无记忆(默认)
73
+ # ============================================================
74
+
75
+ async def demo_no_memory():
76
+ print("=" * 55)
77
+ print(" A. 无记忆(默认)— 每次对话独立")
78
+ print("=" * 55)
79
+
80
+ agent = Agent(
81
+ name="forgetful",
82
+ instructions="你是一个简洁的助手。回答尽量简短。",
83
+ model=MODEL,
84
+ )
85
+
86
+ # 第一次告诉它信息
87
+ result = await Runner.run(agent, input="我叫小明,我喜欢喝咖啡")
88
+ print(f" 对话1: {result.final_output}")
89
+
90
+ # 第二次问它——它不会记得
91
+ result = await Runner.run(agent, input="我叫什么名字?我喜欢喝什么?")
92
+ print(f" 对话2: {result.final_output}")
93
+ print(" 📝 无记忆 → Agent 不记得之前的对话\n")
94
+
95
+
96
+ # ============================================================
97
+ # 演示 B:使用 SimpleMemory
98
+ # ============================================================
99
+
100
+ async def demo_simple_memory():
101
+ print("=" * 55)
102
+ print(" B. SimpleMemory — 轻量内存记忆")
103
+ print("=" * 55)
104
+
105
+ memory = SimpleMemory()
106
+
107
+ agent = Agent(
108
+ name="remembering",
109
+ instructions="你是一个贴心的个人助手。根据相关记忆来个性化回答。回答简洁。",
110
+ model=MODEL,
111
+ memory=memory,
112
+ memory_async_write=False, # 多轮串行对话需要即时读取记忆
113
+ )
114
+
115
+ # 第一次对话:告诉它偏好
116
+ print("\n 第1轮对话:")
117
+ result = await Runner.run(agent, input="我叫小明,我喜欢喝咖啡,讨厌喝茶", user_id="user_001")
118
+ print(f" 助手: {result.final_output}")
119
+
120
+ # 第二次对话:它应该记住
121
+ print("\n 第2轮对话:")
122
+ result = await Runner.run(agent, input="帮我推荐一杯饮料吧", user_id="user_001")
123
+ print(f" 助手: {result.final_output}")
124
+
125
+ # 第三次对话:继续积累记忆
126
+ print("\n 第3轮对话:")
127
+ result = await Runner.run(agent, input="对了,我对牛奶过敏", user_id="user_001")
128
+ print(f" 助手: {result.final_output}")
129
+
130
+ # 第四次对话:看看它记住了多少
131
+ print("\n 第4轮对话:")
132
+ result = await Runner.run(agent, input="再给我推荐一杯饮料,要考虑我的情况", user_id="user_001")
133
+ print(f" 助手: {result.final_output}")
134
+
135
+ # 查看存储的所有记忆
136
+ all_memories = await memory.get_all()
137
+ print(f"\n 📋 记忆库中共 {len(all_memories)} 条记忆")
138
+
139
+
140
+ # ============================================================
141
+ # 演示 C:Mem0 说明(仅展示配置方式)
142
+ # ============================================================
143
+
144
+ def demo_mem0_info():
145
+ print(f"\n{'=' * 55}")
146
+ print(" C. Mem0Provider — 生产级长期记忆(配置说明)")
147
+ print("=" * 55)
148
+
149
+ print("""
150
+ Mem0 提供向量数据库驱动的语义记忆,支持跨会话持久化。
151
+
152
+ 安装:
153
+ pip install mem0ai
154
+ docker run -p 6333:6333 qdrant/qdrant # 启动向量数据库
155
+
156
+ 使用:
157
+ from agentkit.memory.mem0_provider import Mem0Provider
158
+
159
+ memory = Mem0Provider({
160
+ "vector_store": {
161
+ "provider": "qdrant",
162
+ "config": {
163
+ "collection_name": "my_agent",
164
+ "host": "localhost",
165
+ "port": 6333,
166
+ }
167
+ }
168
+ })
169
+
170
+ agent = Agent(
171
+ name="assistant",
172
+ memory=memory, # 就这一行
173
+ ...
174
+ )
175
+
176
+ 相比 SimpleMemory 的优势:
177
+ ✅ 语义搜索(不是关键词匹配,而是理解意思)
178
+ ✅ 持久化存储(重启不丢失)
179
+ ✅ 自动记忆提取(从对话中智能抽取关键信息)
180
+ ✅ 支持 user_id / agent_id 多维度隔离
181
+ """)
182
+
183
+
184
+ # ============================================================
185
+ # 主入口
186
+ # ============================================================
187
+
188
+ async def main():
189
+ print("🚀 AgentKit 记忆系统演示\n")
190
+
191
+ await demo_no_memory()
192
+ await demo_simple_memory()
193
+ demo_mem0_info()
194
+
195
+ print("=" * 55)
196
+ print(" 演示完成 🎉")
197
+ print("=" * 55)
198
+
199
+
200
+ if __name__ == "__main__":
201
+ asyncio.run(main())
@@ -0,0 +1,51 @@
1
+ # Ollama 本地示例(无需 API Key)
2
+
3
+ 使用本地 Ollama + qwen3.5:cloud 模型的示例。**无需任何 API Key,完全本地运行。**
4
+
5
+ ## 环境准备
6
+
7
+ ```bash
8
+ # 1. 安装 Ollama: https://ollama.com
9
+ # 2. 拉取模型
10
+ ollama pull qwen3.5:cloud
11
+
12
+ # 3. 确认 Ollama 正在运行
13
+ curl http://localhost:11434/api/tags
14
+
15
+ # 4. 安装 Python 依赖
16
+ pip install pydantic>=2.0 aiohttp>=3.9.0
17
+ ```
18
+
19
+ ## 示例列表
20
+
21
+ | 文件 | 内容 | 对应教程 |
22
+ |------|------|---------|
23
+ | `01_basic_chat.py` | 最简 Agent — 纯对话 | QuickStart 示例 1 |
24
+ | `02_tool_calling.py` | 带工具的 Agent — Function Calling | QuickStart 示例 2 |
25
+ | `03_skill_usage.py` | 带 Skill 的 Agent — 领域知识包 | QuickStart 示例 3 |
26
+ | `04_multi_agent.py` | 多 Agent 协作 — Handoff 与 as_tool | QuickStart 示例 4 |
27
+ | `05_guardrail.py` | 安全护栏 — Guardrail 与权限控制 | QuickStart 示例 5 |
28
+ | `06_orchestration.py` | 编排 Agent — 流水线与循环 | QuickStart 示例 6 |
29
+ | `07_sync_async_stream.py` | 三种运行方式 — 同步/异步/流式 | 同步与异步 |
30
+ | `08_memory.py` | 记忆系统 — 跨会话长期记忆 | 记忆系统 |
31
+
32
+ ## 运行
33
+
34
+ ```bash
35
+ python examples/ollama/01_basic_chat.py
36
+ python examples/ollama/02_tool_calling.py
37
+ # ... 以此类推
38
+ ```
39
+
40
+ ## 更换模型
41
+
42
+ 如果你想使用其他 Ollama 模型,只需修改示例中的 `model` 参数:
43
+
44
+ ```python
45
+ # 使用其他模型
46
+ agent = Agent(model="ollama/llama3:8b", ...)
47
+ agent = Agent(model="ollama/gemma:latest", ...)
48
+ agent = Agent(model="ollama/qwen3-vl:8b", ...)
49
+ ```
50
+
51
+ > 💡 不同模型的 Function Calling 能力不同。qwen3.5:cloud 已经过验证支持完整的工具调用。
File without changes
@@ -0,0 +1,204 @@
1
+ """
2
+ examples/quickstart.py — AgentKit 快速入门示例
3
+
4
+ 展示框架的核心用法:Agent + Tool + Skill + 多模型。
5
+ """
6
+ import asyncio
7
+ import sys
8
+ import os
9
+
10
+ # 将项目根目录加入 path
11
+ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
12
+
13
+ from agentkit import Agent, Runner, function_tool, LLMRegistry, LLMConfig
14
+ from agentkit import Skill, SkillFrontmatter, SkillResources
15
+ from agentkit import SequentialAgent, LoopAgent
16
+ from agentkit import input_guardrail, GuardrailResult, PermissionPolicy
17
+
18
+
19
+ # ============================================================
20
+ # 示例 1:最简 Agent
21
+ # ============================================================
22
+
23
+ def example_basic():
24
+ """最简单的 Agent:一行配置即可运行"""
25
+ agent = Agent(
26
+ name="assistant",
27
+ instructions="你是一个有帮助的中文助手。简洁回答问题。",
28
+ model="gpt-4o",
29
+ )
30
+ result = Runner.run_sync(agent, input="什么是量子计算?请用一句话解释。")
31
+ print(f"[示例1] {result.final_output}")
32
+
33
+
34
+ # ============================================================
35
+ # 示例 2:带工具的 Agent
36
+ # ============================================================
37
+
38
+ @function_tool
39
+ def calculate(expression: str) -> str:
40
+ """计算数学表达式的结果"""
41
+ try:
42
+ return str(eval(expression))
43
+ except Exception as e:
44
+ return f"计算错误: {e}"
45
+
46
+ @function_tool
47
+ def get_current_time() -> str:
48
+ """获取当前时间"""
49
+ from datetime import datetime
50
+ return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
51
+
52
+ def example_with_tools():
53
+ """带工具的 Agent"""
54
+ agent = Agent(
55
+ name="math_assistant",
56
+ instructions="你是一个数学助手。需要计算时请使用 calculate 工具。",
57
+ model="gpt-4o",
58
+ tools=[calculate, get_current_time],
59
+ )
60
+ result = Runner.run_sync(agent, input="请计算 (15 + 27) * 3 的结果")
61
+ print(f"[示例2] {result.final_output}")
62
+
63
+
64
+ # ============================================================
65
+ # 示例 3:带 Skill 的 Agent
66
+ # ============================================================
67
+
68
+ def example_with_skill():
69
+ """带 Skill 的 Agent"""
70
+ # 代码中直接定义一个 Skill
71
+ greeting_skill = Skill(
72
+ frontmatter=SkillFrontmatter(
73
+ name="greeting-skill",
74
+ description="一个友好的问候技能,根据时间段生成个性化问候语",
75
+ ),
76
+ instructions="""## 使用步骤
77
+ 1. 使用 get_current_time 工具获取当前时间
78
+ 2. 根据时间段(早上/下午/晚上)选择合适的问候语
79
+ 3. 返回个性化的中文问候""",
80
+ )
81
+
82
+ agent = Agent(
83
+ name="greeter",
84
+ instructions="你是一个友好的助手,可以使用 Skill 来完成任务。",
85
+ model="gpt-4o",
86
+ skills=[greeting_skill],
87
+ tools=[get_current_time],
88
+ )
89
+ result = Runner.run_sync(agent, input="请跟我打个招呼")
90
+ print(f"[示例3] {result.final_output}")
91
+
92
+
93
+ # ============================================================
94
+ # 示例 4:多 Agent 协作(as_tool 模式)
95
+ # ============================================================
96
+
97
+ def example_multi_agent():
98
+ """Agent 当工具用——委派模式"""
99
+ researcher = Agent(
100
+ name="researcher",
101
+ instructions="你是一个研究助手。收到问题后,给出简短的研究结论。",
102
+ model="gpt-4o",
103
+ )
104
+
105
+ manager = Agent(
106
+ name="manager",
107
+ instructions="你是一个项目经理。需要研究信息时调用 research 工具。",
108
+ model="gpt-4o",
109
+ tools=[
110
+ researcher.as_tool("research", "调用研究助手获取信息"),
111
+ ],
112
+ )
113
+ result = Runner.run_sync(manager, input="帮我调研一下 Python 异步编程的最佳实践")
114
+ print(f"[示例4] {result.final_output}")
115
+
116
+
117
+ # ============================================================
118
+ # 示例 5:国内模型(DeepSeek)
119
+ # ============================================================
120
+
121
+ def example_domestic_model():
122
+ """使用国内模型"""
123
+ agent = Agent(
124
+ name="deepseek_assistant",
125
+ instructions="你是一个中文编程助手。",
126
+ model="deepseek/deepseek-chat", # 自动路由到 OpenAICompatibleAdapter
127
+ )
128
+ result = Runner.run_sync(agent, input="用 Python 写一个快速排序")
129
+ print(f"[示例5] {result.final_output}")
130
+
131
+
132
+ # ============================================================
133
+ # 示例 6:带安全护栏
134
+ # ============================================================
135
+
136
+ @input_guardrail
137
+ async def block_sensitive(ctx):
138
+ """检查是否包含敏感词"""
139
+ sensitive_words = ["密码", "身份证", "银行卡"]
140
+ for word in sensitive_words:
141
+ if word in ctx.input:
142
+ return GuardrailResult(triggered=True, reason=f"检测到敏感词: {word}")
143
+ return GuardrailResult(triggered=False)
144
+
145
+ def example_with_guardrail():
146
+ """带安全护栏的 Agent"""
147
+ agent = Agent(
148
+ name="safe_assistant",
149
+ instructions="你是一个安全的助手。",
150
+ model="gpt-4o",
151
+ input_guardrails=[block_sensitive],
152
+ permission_policy=PermissionPolicy(
153
+ mode="ask",
154
+ allowed_tools={"calculate", "get_current_time"},
155
+ ),
156
+ )
157
+ # 这个请求会被护栏拦截
158
+ result = Runner.run_sync(agent, input="告诉我你的密码")
159
+ print(f"[示例6] 被拦截: {result.error}")
160
+
161
+ # 这个请求正常通过
162
+ result = Runner.run_sync(agent, input="你好,今天天气如何?")
163
+ print(f"[示例6] 正常: {result.final_output}")
164
+
165
+
166
+ # ============================================================
167
+ # 主入口
168
+ # ============================================================
169
+
170
+ if __name__ == "__main__":
171
+ print("=" * 60)
172
+ print("AgentKit 框架快速入门示例")
173
+ print("=" * 60)
174
+ print()
175
+ print("注意:运行示例需要配置对应的 LLM API Key。")
176
+ print(" - OpenAI: export OPENAI_API_KEY=sk-...")
177
+ print(" - DeepSeek: export DEEPSEEK_API_KEY=sk-...")
178
+ print()
179
+
180
+ # 可以选择运行某个示例
181
+ if len(sys.argv) > 1:
182
+ example_num = sys.argv[1]
183
+ examples = {
184
+ "1": example_basic,
185
+ "2": example_with_tools,
186
+ "3": example_with_skill,
187
+ "4": example_multi_agent,
188
+ "5": example_domestic_model,
189
+ "6": example_with_guardrail,
190
+ }
191
+ if example_num in examples:
192
+ examples[example_num]()
193
+ else:
194
+ print(f"未知示例编号: {example_num}")
195
+ else:
196
+ print("用法: python examples/quickstart.py [1-6]")
197
+ print()
198
+ print("可用示例:")
199
+ print(" 1 - 最简 Agent")
200
+ print(" 2 - 带工具的 Agent")
201
+ print(" 3 - 带 Skill 的 Agent")
202
+ print(" 4 - 多 Agent 协作")
203
+ print(" 5 - 国内模型 (DeepSeek)")
204
+ print(" 6 - 安全护栏")
@@ -0,0 +1,33 @@
1
+ """
2
+ 示例 1:最简 Agent — 纯对话
3
+
4
+ 运行前请设置环境变量:
5
+ export OPENAI_API_KEY="sk-..."
6
+
7
+ 运行:
8
+ python examples/standard/01_basic_chat.py
9
+ """
10
+ import sys, os
11
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "..", ".."))
12
+
13
+ from agentkit import Agent, Runner
14
+
15
+ # 创建最简 Agent —— 只需 3 个参数
16
+ agent = Agent(
17
+ name="assistant",
18
+ instructions="你是一个有帮助的中文助手。回答尽量简洁。",
19
+ model="gpt-4o",
20
+ )
21
+
22
+ # 同步运行
23
+ result = Runner.run_sync(agent, input="什么是量子计算?请用一句话解释。")
24
+
25
+ if result.success:
26
+ print(f"✅ 回复: {result.final_output}")
27
+ else:
28
+ print(f"❌ 错误: {result.error}")
29
+
30
+ # 查看事件流
31
+ print("\n📋 事件流:")
32
+ for event in result.events:
33
+ print(f" [{event.type}] {str(event.data)[:80]}")