""" 升级后 Agent 体验脚本 — 展示 P0-P4 + 记忆增强的全部能力 """ import asyncio import sys import os # 修复 Windows GBK 终端编码问题 if sys.platform == "win32": import io sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace") sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding="utf-8", errors="replace") sys.path.insert(0, os.path.join(os.path.dirname(__file__), "backend")) from app.agent_runtime.core import AgentRuntime from app.agent_runtime.schemas import ( AgentConfig, AgentLLMConfig, AgentToolConfig, AgentBudgetConfig, AgentMemoryConfig, ) from app.core.hooks import HookManager, HookConfig, HookEvent, HookContext DEMO_MEMORY_DIR = os.path.join(os.path.dirname(__file__), ".demo_memory") def setup_demo_memories(): """预置演示记忆文件""" from app.core.memdir import MemoryDir, MemoryType md = MemoryDir(DEMO_MEMORY_DIR) # 清除旧记忆 for f in os.listdir(DEMO_MEMORY_DIR): if f.endswith(".md"): os.remove(os.path.join(DEMO_MEMORY_DIR, f)) if os.path.exists(os.path.join(DEMO_MEMORY_DIR, "MEMORY.md")): os.remove(os.path.join(DEMO_MEMORY_DIR, "MEMORY.md")) md.save_memory( "user_preferences.md", MemoryType.USER, "用户: Python全栈开发者", "用户有8年Python后端经验,偏好简洁的函数式风格,不喜欢过度抽象的类层次", "用户是一位资深Python全栈开发者,习惯使用 FastAPI + SQLAlchemy 技术栈。\n" "代码风格偏好:偏好简洁、扁平、显式的代码,不喜欢深层继承和过度抽象。\n" "Why: 用户在代码评审中多次提到'不要为未来设计'和'三行重复比一个错误抽象好'。\n" "How to apply: 新功能直接用函数实现,除非有明确的3+处复用才提取类。", ) md.save_memory( "feedback_testing.md", MemoryType.FEEDBACK, "测试规范: 集成测试用真实数据库", "集成测试必须使用真实数据库而非 mock,因为 mock 与生产环境不一致曾导致故障", "集成测试必须使用真实数据库,不要 mock。\n" "Why: 2026年3月有一次生产迁移失败,因为mock测试通过但真实schema不兼容。\n" "How to apply: 所有涉及 SQLAlchemy session 的测试用例必须使用测试数据库。", ) md.save_memory( "project_release.md", MemoryType.PROJECT, "项目: v2.1 6月25日发布", "当前版本v2.1计划于2026-06-25发布,冻结日前需优先完成安全审计和API文档", "v2.1 发布日期: 2026年6月25日。\n" "Why: 客户合同中约定的交付日期,延期每天有违约金。\n" "How to apply: 优先完成P0 Security Audit和API Documentation,非关键UI调整推迟到v2.2。", ) md.save_memory( "reference_monitoring.md", MemoryType.REFERENCE, "参考: 生产监控面板地址", "Grafana监控面板和Sentry错误追踪的外部地址", "Grafana: http://grafana.internal:3000/d/api-latency\n" "Sentry: https://sentry.internal/organizations/myorg/projects/api\n" "Kibana: http://kibana.internal:5601/app/logs", ) print(f" [预置] 4条演示记忆已写入 {DEMO_MEMORY_DIR}") return md async def main(): print("=" * 60) print("天工 Agent 升级体验 — 全部新特性已启用") print("=" * 60) # 1. 预置记忆 print("\n[1/5] 初始化文件式记忆系统 (MEMORY.md)") md = setup_demo_memories() manifest = md.scan() print(f" 已加载 {manifest.total_files} 条记忆") # 2. 注册审计 Hook print("\n[2/5] 注册安全审计 Hook") tool_log: list = [] async def audit_hook(ctx: HookContext): tool_log.append(f"[审计] {ctx.event.value} tool={ctx.tool_name}") return None # 不拦截 hooks = HookManager(hooks=[ HookConfig( event=HookEvent.PRE_TOOL_USE, matcher="*", description="审计所有工具调用", python_handler=audit_hook, ), HookConfig( event=HookEvent.POST_TOOL_USE, matcher="*", description="审计工具结果", python_handler=audit_hook, ), ]) print(f" 已注册 {len(hooks.get_hooks(HookEvent.PRE_TOOL_USE))} 个 PreToolUse Hook") # 3. 构建配置 (所有新特性开启) print("\n[3/5] 构建 Agent 配置") config = AgentConfig( name="升级体验Agent", system_prompt=( "你是一个智能助手,运行在升级后的天工平台上。\n" "你可以使用工具的读写能力帮助用户完成任务。\n" "注意系统提示词中包含的记忆信息,根据需要使用它们。" ), llm=AgentLLMConfig( provider="deepseek", model="deepseek-v4-flash", temperature=0.7, max_iterations=8, ), tools=AgentToolConfig( permission_level="acceptEdits", ), memory=AgentMemoryConfig( enabled=True, max_history_messages=20, memory_dir_enabled=True, memory_dir_path=DEMO_MEMORY_DIR, persist_to_db=False, # 演示模式不写DB vector_memory_enabled=False, learning_enabled=False, ), budget=AgentBudgetConfig( max_llm_invocations=20, max_tool_calls=30, ), ) # 4. 创建 Runtime runtime = AgentRuntime(config=config, hook_manager=hooks) print(f" ✓ 权限级别: {runtime.tool_manager._permission.level.value}") print(f" ✓ 文件式记忆: {'启用' if runtime._memdir else '禁用'} ({runtime._memdir_manifest.total_files if runtime._memdir_manifest else 0}条)") print(f" ✓ Hook 管理: {len(hooks.get_hooks(HookEvent.PRE_TOOL_USE))} PreToolUse + {len(hooks.get_hooks(HookEvent.POST_TOOL_USE))} PostToolUse") print(f" ✓ 计划模式: {'启用' if runtime.plan_mode else '禁用'}") print(f" ✓ 崩溃恢复: 已初始化") # 5. 运行对话 print("\n[4/5] 开始对话...") print("-" * 40) test_queries = [ "你好!请用 list_files 看看当前目录有什么文件,简单列出即可", "根据你的记忆,我应该用什么代码风格来写一个新功能?", ] for i, query in enumerate(test_queries, 1): print(f"\n--- 第 {i} 轮 ---") print(f"用户: {query}") result = await runtime.run(query) print(f"Agent: {result.content[:300]}...") print(f"(迭代{result.iterations_used}次, 调用{result.tool_calls_made}个工具)") # 6. 总结 print("\n" + "=" * 60) print("[5/5] 新特性实战验证结果") print("=" * 60) print(f" 权限检查: AgentToolManager 内置 PermissionChecker (acceptEdits)") print(f" Hook 审计: 记录了 {len(tool_log)} 次工具调用") if tool_log: for log in tool_log[:5]: print(f" {log}") print(f" 文件记忆: MEMORY.md + {manifest.total_files} 条分类记忆") print(f" 记忆目录: {DEMO_MEMORY_DIR}") print(f" 对话轮数: {len(test_queries)}") print(f" 会话 ID: {runtime.context.session_id}") if __name__ == "__main__": asyncio.run(main())