Download agentframe_orchestrator.py from ljsysfurry/AgentFrame: direct link, hf CLI and curl.
- Browser
- Download file 12.4 kB
-
https://huggingface.co/ljsysfurry/AgentFrame/resolve/main/agentframe_orchestrator.py
- Command line
-
hf download hf://ljsysfurry/AgentFrame/agentframe_orchestrator.py
-
curl -L -o agentframe_orchestrator.py https://huggingface.co/ljsysfurry/AgentFrame/resolve/main/agentframe_orchestrator.py
12.4 kB
| """ | |
| AgentFrame 编排层 (Orchestrator) | |
| =============================== | |
| DeepSeek 决策 ↔ OpenClaw 执行的桥接层 | |
| 核心循环: | |
| 1. DeepSeek 分析用户意图 → 决定下一步 | |
| 2. 调用 OpenClaw 工具 (exec/browser/computer-use) | |
| 3. 工具结果 → 分层量化存入 KV 缓存 | |
| 4. 循环直到任务完成 | |
| 架构: | |
| Orchestrator | |
| ├── Brain: DeepSeek 客户端 (本地 L40S / API 兜底) | |
| ├── Hands: OpenClaw 工具桥 (exec/browser) | |
| ├── Memory: 前缀感知缓存池 (复用 agentframe_core.py) | |
| └── Loop: Agent 循环控制 | |
| 依赖: | |
| - agentframe_core.py (前缀缓存池 + KV 量化) | |
| - OpenClaw gateway (exec/browser 工具) | |
| - DeepSeek 模型 (本地或 API) | |
| """ | |
| import json | |
| import time | |
| import subprocess | |
| from typing import Dict, List, Optional, Any, Callable | |
| # ============================================================ | |
| # 1. Brain: DeepSeek 客户端抽象 (本地/API 可切换) | |
| # ============================================================ | |
| class DeepSeekBrain: | |
| """ | |
| DeepSeek 决策大脑 | |
| mode: 'local' (L40S 本地) | 'api' (DeepSeek 官方) | |
| """ | |
| def __init__(self, mode: str = "api", model: str = "deepseek-chat", | |
| api_key: str = "", base_url: str = "https://api.deepseek.com"): | |
| self.mode = mode | |
| self.model = model | |
| self.api_key = api_key | |
| self.base_url = base_url | |
| self.system_prompt = "" | |
| self.conversation: List[Dict] = [] | |
| def set_system_prompt(self, prompt: str): | |
| """设置 Agent 系统提示 (含工具定义)""" | |
| self.system_prompt = prompt | |
| self.conversation = [{"role": "system", "content": prompt}] | |
| def think(self, user_input: str, tools: List[Dict]) -> Dict: | |
| """ | |
| DeepSeek 决策: 返回 JSON {action, tool, args} 或 {action: "reply", content} | |
| """ | |
| if self.mode == "api": | |
| return self._think_api(user_input, tools) | |
| else: | |
| return self._think_local(user_input, tools) | |
| def _think_api(self, user_input: str, tools: List[Dict]) -> Dict: | |
| """API 模式 (OpenAI 兼容)""" | |
| import urllib.request | |
| self.conversation.append({"role": "user", "content": user_input}) | |
| payload = { | |
| "model": self.model, | |
| "messages": self.conversation, | |
| "tools": tools, | |
| "tool_choice": "auto", | |
| "stream": False, | |
| } | |
| req = urllib.request.Request( | |
| f"{self.base_url}/chat/completions", | |
| data=json.dumps(payload).encode(), | |
| headers={ | |
| "Content-Type": "application/json", | |
| "Authorization": f"Bearer {self.api_key}", | |
| }, | |
| ) | |
| with urllib.request.urlopen(req, timeout=60) as resp: | |
| data = json.loads(resp.read().decode()) | |
| msg = data["choices"][0]["message"] | |
| self.conversation.append(msg) | |
| # 解析工具调用 | |
| if msg.get("tool_calls"): | |
| tc = msg["tool_calls"][0] | |
| return { | |
| "action": "tool", | |
| "tool": tc["function"]["name"], | |
| "args": json.loads(tc["function"]["arguments"] or "{}"), | |
| } | |
| return {"action": "reply", "content": msg.get("content", "")} | |
| def _think_local(self, user_input: str, tools: List[Dict]) -> Dict: | |
| """本地模式 (L40S + V2-Lite, 待实现真实推理)""" | |
| # TODO: 接入 agentframe 的本地推理 (KV 优化) | |
| # 目前返回占位, 等 GPU 开机实现 | |
| return {"action": "reply", "content": "[本地模式待实现 - 需 GPU]"} | |
| def remember_tool_result(self, result: str): | |
| """把工具结果追加到对话 (供下轮决策)""" | |
| self.conversation.append({"role": "tool", "content": result}) | |
| # ============================================================ | |
| # 2. Hands: OpenClaw 工具桥 | |
| # ============================================================ | |
| class OpenClawHands: | |
| """ | |
| OpenClaw 工具执行桥 (调用 gateway 的 exec/browser) | |
| 通过 subprocess 调用 openclaw CLI, 或直接调用系统命令 | |
| """ | |
| def __init__(self, workspace: str = "/root/.openclaw/workspace"): | |
| self.workspace = workspace | |
| def exec(self, command: str, timeout: int = 30) -> Dict: | |
| """执行 shell 命令 (OpenClaw exec 能力)""" | |
| try: | |
| result = subprocess.run( | |
| command, | |
| shell=True, | |
| capture_output=True, | |
| text=True, | |
| timeout=timeout, | |
| cwd=self.workspace, | |
| ) | |
| return { | |
| "success": result.returncode == 0, | |
| "stdout": result.stdout[:2000], | |
| "stderr": result.stderr[:500], | |
| "exit_code": result.returncode, | |
| } | |
| except subprocess.TimeoutExpired: | |
| return {"success": False, "stdout": "", "stderr": "timeout", "exit_code": -1} | |
| def read_file(self, path: str) -> str: | |
| """读文件""" | |
| return self.exec(f"cat {path}")["stdout"] | |
| def write_file(self, path: str, content: str) -> bool: | |
| """写文件""" | |
| import base64 | |
| b64 = base64.b64encode(content.encode()).decode() | |
| result = self.exec(f"echo '{b64}' | base64 -d > {path}") | |
| return result["success"] | |
| def browser_open(self, url: str) -> Dict: | |
| """浏览器打开网页""" | |
| result = self.exec(f"openclaw browser --browser-profile openclaw open {url}") | |
| return {"success": result["success"], "note": "browser opened"} | |
| def browser_snapshot(self) -> str: | |
| """浏览器快照""" | |
| result = self.exec("openclaw browser --browser-profile openclaw snapshot") | |
| return result["stdout"] | |
| def list_tools(self) -> List[str]: | |
| """可用工具清单""" | |
| return ["exec", "read_file", "write_file", "browser_open", "browser_snapshot"] | |
| # ============================================================ | |
| # 3. Memory: KV 记忆集成 (前缀缓存池) | |
| # ============================================================ | |
| class AgentMemory: | |
| """Agent 记忆: 复用 agentframe_core 的前缀池 + 分层量化""" | |
| def __init__(self, system_prompt: str, prompt_tokens: int = 3000): | |
| from agentframe_core import PrefixPool, SessionManager, AbsorbedMLAEncoder | |
| self.pool = PrefixPool() | |
| self.sessions = SessionManager(self.pool) | |
| self.encoder = AbsorbedMLAEncoder() | |
| self.system_prompt = system_prompt | |
| # 创建主会话 | |
| self.session = self.sessions.create_session( | |
| "agent-main", system_prompt, prompt_tokens | |
| ) | |
| self.history: List[Dict] = [] | |
| def record(self, role: str, content: str, layer_idx: int = 0): | |
| """记录对话/工具结果到记忆 (分层量化)""" | |
| import numpy as np | |
| # 模拟 KV 写入: 思考用 INT8, 工具结果用 INT4 | |
| fake_kv = np.random.randn(1, 8, self.encoder.kv_rank) | |
| if role == "thought": | |
| kv = self.encoder.encode_thought(fake_kv) | |
| else: | |
| kv = self.encoder.encode_tool_result(fake_kv) | |
| self.sessions.append_tool_result(self.session, layer_idx, kv) | |
| self.history.append({"role": role, "content": content[:500]}) | |
| def memory_report(self) -> Dict: | |
| return self.sessions.session_memory(self.session) | |
| def close(self): | |
| self.sessions.close_session("agent-main") | |
| # ============================================================ | |
| # 4. Loop: Agent 主循环 | |
| # ============================================================ | |
| class AgentLoop: | |
| """Agent 执行循环: 思考 → 行动 → 观察 → 循环""" | |
| def __init__(self, brain: DeepSeekBrain, hands: OpenClawHands, memory: AgentMemory): | |
| self.brain = brain | |
| self.hands = hands | |
| self.memory = memory | |
| self.max_steps = 10 | |
| def _tool_schemas(self) -> List[Dict]: | |
| """给 DeepSeek 的工具定义 (OpenClaw 能力)""" | |
| return [ | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "exec", | |
| "description": "执行 shell 命令", | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "command": {"type": "string", "description": "要执行的命令"} | |
| }, | |
| "required": ["command"], | |
| }, | |
| }, | |
| }, | |
| { | |
| "type": "function", | |
| "function": { | |
| "name": "browser_open", | |
| "description": "打开网页", | |
| "parameters": { | |
| "type": "object", | |
| "properties": { | |
| "url": {"type": "string", "description": "网页地址"} | |
| }, | |
| "required": ["url"], | |
| }, | |
| }, | |
| }, | |
| ] | |
| def run(self, task: str) -> str: | |
| """执行一个任务""" | |
| self.brain.set_system_prompt(self.memory.system_prompt) | |
| self.memory.record("user", task) | |
| for step in range(self.max_steps): | |
| print(f"\n[Step {step+1}] 🧠 DeepSeek 思考中...") | |
| self.memory.record("thought", f"step {step+1}") | |
| decision = self.brain.think(task, self._tool_schemas()) | |
| if decision["action"] == "reply": | |
| print(f" 💬 Agent: {decision['content']}") | |
| return decision["content"] | |
| if decision["action"] == "tool": | |
| tool = decision["tool"] | |
| args = decision["args"] | |
| print(f" 🛠 调用 {tool}({args})") | |
| # 执行工具 | |
| if tool == "exec": | |
| result = self.hands.exec(args.get("command", "")) | |
| elif tool == "browser_open": | |
| result = self.hands.browser_open(args.get("url", "")) | |
| else: | |
| result = {"success": False, "stdout": f"未知工具 {tool}"} | |
| # 记录结果 (工具结果 → INT4 压缩) | |
| result_str = json.dumps(result, ensure_ascii=False)[:500] | |
| self.memory.record("tool_result", result_str) | |
| self.brain.remember_tool_result(result_str) | |
| task = result_str # 下一轮基于结果继续 | |
| return "[达到最大步数,任务未完成]" | |
| # ============================================================ | |
| # 5. 演示 | |
| # ============================================================ | |
| if __name__ == "__main__": | |
| print("=" * 60) | |
| print("AgentFrame 编排层 演示 (无 GPU 版)") | |
| print("=" * 60) | |
| # 1. 组装 | |
| sys_prompt = """你是智能助手,可以操控电脑完成任务。 | |
| 你有以下工具: | |
| - exec: 执行 shell 命令 | |
| - browser_open: 打开网页 | |
| 请根据用户需求,一步步完成任务。每次只调用一个工具,观察结果后再决定下一步。""" | |
| brain = DeepSeekBrain(mode="api", model="deepseek-chat", api_key="") # 无 key 时演示流程 | |
| hands = OpenClawHands() | |
| memory = AgentMemory(sys_prompt, prompt_tokens=3000) | |
| # 2. 测试手的能力 (无需 GPU) | |
| print("\n🖐 测试 OpenClaw 手:") | |
| r = hands.exec("echo 'AgentFrame 就绪!' && ls /root/.openclaw/workspace/*.py | head -3") | |
| print(f" exec: {'✅' if r['success'] else '❌'}") | |
| print(f" → {r['stdout'][:100]}") | |
| # 3. 测试记忆 (前缀池) | |
| print("\n🧠 测试记忆 (前缀缓存池):") | |
| memory.record("thought", "分析任务") | |
| memory.record("tool_result", "ls 输出: agentframe_core.py, agentframe_orchestrator.py") | |
| rep = memory.memory_report() | |
| print(f" 前缀引用数: {rep['prefix_refs']}") | |
| print(f" 增量内存: {rep['incremental_bytes']/1024:.0f}KB") | |
| # 4. Agent 循环 (无 API key 时走 reply 占位) | |
| print("\n🤖 Agent 循环:") | |
| loop = AgentLoop(brain, hands, memory) | |
| # 用本地模式跑流程 (不真正调 API) | |
| brain.mode = "local" | |
| result = loop.run("查看当前目录有什么文件") | |
| print(f" 结果: {result}") | |
| print("\n✅ AgentFrame 编排层骨架验证完成") | |
| print(" (真实 DeepSeek 推理需 GPU 开机后接入)") | |