从3K行种子到专属技能树:GenericAgent自进化Agent框架的架构解剖与工程实战
2026年4月,一个仅3300行Python代码的开源项目登顶GitHub Trending榜首,它声称能让任何LLM"越用越聪明",Token消耗直降近10倍。这不是营销噱头——它的核心设计哲学是不预设技能,靠进化获得能力。本文从架构设计、记忆系统、执行循环、代码实战四个维度,彻底拆解GenericAgent的技术内核。
一、为什么GenericAgent值得你关注
1.1 AI Agent的"金鱼脑"困境
用过大模型Agent的开发者都有过这种体验:你第一次让Agent帮你部署一个项目,它安装依赖、写配置文件、调试环境变量,折腾了半小时终于搞定。第二次让它部署另一个项目,它又从零开始——完全不记得昨天做过什么。
这就是AI Agent普遍面临的**"金鱼脑"困境**:每次对话都是白纸一张,之前积累的所有经验全部归零。
现有的解决方案大致分两条路:
- 插件/工具生态(如OpenClaw):预装大量模块,让Agent"出厂即有"能力,但用户的个性化需求无法穷举
- 上下文窗口膨胀(如Claude Code):把大量信息塞进200K-1M的上下文窗口,让模型自己找——代价是Token消耗直线上升
GenericAgent走了一条完全不同的路:让Agent自己进化。
1.2 "3K行种子代码"的哲学
GenericAgent的核心设计哲学用一句话概括:
不预设技能,靠进化获得能力。每解决一个新任务,就将执行路径自动固化为Skill,供后续直接调用。
这不是什么新概念——"从经验中学习"是人类认知的基本模式。但GenericAgent做到了一件事:把这个哲学用3K行代码实现了,而且跑得很好。
关键数据:
| 指标 | GenericAgent | 典型Agent框架 |
|---|---|---|
| 核心代码量 | ~3,300行 | 数万至数十万行 |
| 上下文窗口 | < 30K tokens | 200K - 1M tokens |
| Token消耗 | 基线的1/6~1/10 | 基线 |
| Agent Loop | ~100行 | 数千行 |
| 原子工具 | 9个 | 数十到上百个 |
| 自我进化 | 原生支持 | 大多不支持 |
1.3 自举实证:代码仓库是Agent自己建的
GenericAgent最硬核的"证明":整个代码仓库从安装Git、git init到每一条commit message,全部由GenericAgent自主完成。作者全程未打开过一次终端。
这不是演示视频里精心编排的场景,而是项目的实际开发过程。如果Agent连自己的代码仓库都能自主搭建和迭代,那让它帮你做些日常任务,绰绰有余。
二、架构总览:分层记忆 × 最小工具集 × 自主执行循环
GenericAgent的整体架构可以用一个公式表达:
能力增长 = 分层记忆系统 × 最小工具集 × 自主执行循环
三个维度缺一不可:
- 分层记忆:提供经验的沉淀与召回机制,让Agent"记住"做过什么
- 最小工具集:9个原子工具覆盖系统控制的基础能力,不预设高级功能
- 自主执行循环:100行的Agent Loop,驱动感知→推理→执行→记忆写入的闭环
下面逐层深入。
三、分层记忆系统:GenericAgent的灵魂
这是GenericAgent区别于所有其他Agent框架的核心。它的记忆系统不是简单的"对话历史"或"向量数据库",而是一个五层分级结构,每一层都有明确的职责和写入/召回策略。
3.1 L0 — 元规则(Meta Rules)
L0是Agent的"操作系统内核",定义了Agent的基础行为规则和系统约束。它在初始化时写入,之后极少修改。
# L0 典型内容示例(简化版)
L0_META_RULES = """
你是GenericAgent,一个自主执行的AI助手。
核心约束:
1. 每次行动前必须评估风险,高风险操作需ask_user确认
2. 优先复用已有Skill,避免重复探索
3. 执行完成后必须将经验写入记忆层
4. 遇到超出能力范围的任务,诚实说明而非编造答案
工具使用原则:
- code_run: 执行代码,优先使用已有脚本
- file_read/file_write/file_patch: 文件操作
- web_scan/web_execute_js: 浏览器控制
- ask_user: 不确定时主动询问
- update_working_checkpoint: 更新工作检查点
- start_long_term_update: 触发长期记忆更新
"""
L0的关键设计决策:它不是硬编码的prompt,而是可进化的规则。当Agent发现某条规则导致问题时,可以通过L3 Skill的执行来修改L0——这实现了"元认知"层面的自我修正。
3.2 L1 — 记忆索引(Insight Index)
L1是整个记忆系统的路由层。它不存储具体内容,而是维护一个极简索引,告诉Agent"哪些记忆可能和当前任务相关"。
# L1 索引结构示例
insight_index = {
"股票筛选": {
"level": "L3",
"skill_path": "skills/stock_screening_v2.py",
"last_used": "2026-04-20",
"success_rate": 0.92,
"token_cost_avg": 2400
},
"微信操作": {
"level": "L3",
"skill_path": "skills/wechat_reader.py",
"last_used": "2026-04-22",
"success_rate": 0.87,
"token_cost_avg": 1800
},
"用户偏好": {
"level": "L2",
"fact_path": "facts/user_preferences.md",
"confidence": 0.95
}
}
L1的设计灵感来自信息检索中的倒排索引——不存储原文,只存储"关键词→位置"的映射。这使得Agent在面对新任务时,不需要扫描全部记忆(那会消耗大量Token),只需先查L1索引,快速定位到相关的L2/L3/L4记忆。
Token节省的核心机制:传统Agent把所有上下文塞进prompt,导致Token随对话长度线性增长。GenericAgent通过L1索引,每次只召回与当前任务相关的记忆片段,将上下文窗口控制在30K以内。
3.3 L2 — 全局事实(Global Facts)
L2存储在长期运行过程中积累的稳定知识——不是任务流程,而是关于世界和用户的事实。
# L2 全局事实示例
## 用户环境
- 操作系统: macOS 15.4 (ARM)
- Python版本: 3.12
- 首选编辑器: VS Code
- 常用编程语言: Python, TypeScript, Go
## 用户偏好
- 代码风格: 类型注解 + docstring
- 通信方式: 飞书 > 微信 > 邮件
- 时区: Asia/Shanghai
## 已知约束
- 公司网络限制: 无法直连GitHub,需通过代理
- 服务器环境: Ubuntu 22.04, Docker 24.x
L2的更新策略非常保守——只有在多次观察到同一事实后才会写入。这避免了"一次性的偶发观察"污染全局知识库。
3.4 L3 — 任务Skills / SOPs
L3是技能层,存储完成特定任务类型的可复用流程。这是GenericAgent自我进化的直接体现。
每个L3 Skill本质上是一个结构化的SOP(标准操作流程),包含:
# L3 Skill 结构示例
skill_stock_screening = {
"name": "quant_stock_screening",
"version": "2.1",
"trigger": ["筛选股票", "选股", "量化筛选", "stock screening"],
"prerequisites": ["pip install mootdx pandas"],
"steps": [
{
"step": 1,
"action": "code_run",
"description": "连接行情数据源,获取实时数据",
"code_template": """
import mootdx.quotes as quotes
df = quotes.quotes(symbol=symbol, market=market)
# ... 数据获取逻辑
"""
},
{
"step": 2,
"action": "code_run",
"description": "应用技术指标筛选条件",
"code_template": """
# EXPMA金叉 + 换手率>5% 筛选
filtered = df[
(df["expma_cross"]) &
(df["turnover_rate"] > 5)
]
"""
},
{
"step": 3,
"action": "ask_user",
"description": "确认筛选结果并选择操作"
}
],
"token_cost_avg": 2400,
"success_count": 12,
"fail_count": 1,
"evolution_history": [
{"version": "1.0", "date": "2026-03-15", "note": "首次创建,基础筛选"},
{"version": "1.5", "date": "2026-03-28", "note": "增加换手率条件"},
{"version": "2.0", "date": "2026-04-10", "note": "重构为多指标筛选"},
{"version": "2.1", "date": "2026-04-18", "note": "修复数据源断连重试逻辑"}
]
}
Skill的进化路径:从"第一次摸索着完成"到"形成稳定SOP"到"持续优化版本",这是一个典型的知识蒸馏过程。
3.5 L4 — 会话归档(Session Archive)
L4是最外层的记忆,存储从已完成任务中提炼出的归档记录。它不像L3那样是结构化的流程,而是更原始的任务执行记录,用于长程召回。
# L4 归档示例
session_archive = {
"id": "sess_20260420_001",
"task": "部署Flask应用到AWS EC2",
"summary": "在Ubuntu 22.04 EC2实例上部署Flask应用,使用Gunicorn+Nginx,配置SSL证书",
"key_decisions": [
"选择Gunicorn而非uWSGI(更轻量)",
"使用Let's Encrypt自动续签证书",
"配置systemd守护进程"
],
"pitfalls": [
"AWS安全组默认未开放443端口",
"Nginx配置需手动添加proxy_set_header"
],
"related_skills": ["flask_deploy_v1"],
"timestamp": "2026-04-20T14:32:00+08:00",
"token_consumed": 3200
}
L4的价值在于:当Agent遇到一个和归档任务类似但不完全相同的新任务时,可以快速参考归档中的关键决策和避坑经验,而不需要从头摸索。
3.6 五层记忆的协同机制
五层记忆不是孤立存在的,它们在Agent Loop的每个迭代中协同工作:
新任务到达
↓
查询 L1 索引 → 定位相关记忆
↓
加载 L0 元规则 → 约束行为边界
↓
加载 L2 全局事实 → 提供环境上下文
↓
匹配 L3 Skill → 有现成流程?直接执行
↓ (无匹配Skill)
自主探索 → 执行新任务
↓
更新 L1 索引(新技能的路由信息)
固化 L3 Skill(将执行路径沉淀为SOP)
写入 L4 归档(记录关键决策和踩坑经验)
↓
下次同类任务 → 一条命令直接调用
这个协同机制的核心洞察:记忆的分层不是为了存储更多内容,而是为了在召回时更精确。L1做路由,L2提供上下文,L3提供可复用流程,L4提供细节参考——每一层都在减少无关信息的噪声,提高信噪比。
四、9个原子工具:极简主义的胜利
GenericAgent只提供9个原子工具(加2个记忆管理工具)。对比其他框架动辄数十上百的工具,这个设计看起来"简陋",实则精妙。
4.1 工具清单与设计哲学
| 工具 | 功能 | 为什么是"原子"的 |
|---|---|---|
code_run | 执行任意代码 | 最灵活的工具,可动态安装包、写脚本、调API |
file_read | 读取文件 | 最基本的输入操作 |
file_write | 写入文件 | 最基本的输出操作 |
file_patch | 修改文件 | 比file_write更精准的增量修改 |
web_scan | 感知网页内容 | 浏览器的"眼睛" |
web_execute_js | 控制浏览器行为 | 浏览器的"手" |
ask_user | 人机协作确认 | 安全阀门 |
update_working_checkpoint | 更新工作检查点 | 短期记忆管理 |
start_long_term_update | 触发长期记忆更新 | 长期记忆管理 |
设计哲学:9个工具覆盖基础能力,复杂能力通过code_run动态创建。
4.2 code_run:万能的元工具
code_run是GenericAgent最核心的工具,它允许Agent执行任意Python代码。这看似危险(安全机制后文讨论),但正是这种"元编程"能力,让9个工具能扩展出无限可能:
# 示例:Agent如何通过code_run动态创建新能力
# 用户:"帮我读取微信消息"
# Agent第一次执行:
code_result = agent.code_run("""
# 第1步:安装依赖
import subprocess
subprocess.run(["pip", "install", "pycryptodome"], capture_output=True)
# 第2步:逆向微信数据库
import os
import hashlib
import sqlite3
from Crypto.Cipher import AES
def get_wechat_key():
# 从微信进程内存中提取解密密钥
# (实际实现更复杂,此处简化)
pass
def decrypt_db(db_path, key):
# AES解密微信数据库
cipher = AES.new(key, AES.MODE_CBC, iv=b"0" * 16)
# ... 解密逻辑
def read_messages(db_path, limit=50):
key = get_wechat_key()
decrypted = decrypt_db(db_path, key)
conn = sqlite3.connect(decrypted)
cursor = conn.execute(
"SELECT talker, content, createTime FROM MSG "
"ORDER BY createTime DESC LIMIT ?",
(limit,)
)
return cursor.fetchall()
messages = read_messages("/path/to/MSG0.db")
for msg in messages:
print(f"[{msg[0]}] {msg[1][:100]}")
""")
执行完成后,Agent会自动将这段代码固化为一个L3 Skill,命名为类似wechat_reader。下次用户说"帮我读微信",Agent查L1索引发现已有对应Skill,直接一条命令调用,无需重新探索。
4.3 web_scan + web_execute_js:真实浏览器控制
GenericAgent的浏览器控制不是Selenium/Playwright那样的自动化框架,而是注入真实浏览器——直接在你的Chrome/Edge中操作,保留所有登录态。
# web_scan: 读取当前页面内容
page_content = agent.web_scan()
# web_execute_js: 执行JavaScript控制浏览器
agent.web_execute_js("""
// 在外卖App中搜索奶茶
document.querySelector('input.search').value = '奶茶';
document.querySelector('button.search-btn').click();
""")
# 更复杂的操作:自动下单
agent.web_execute_js("""
// 选择第一个搜索结果
document.querySelectorAll('.shop-item')[0].click();
// 等待页面加载后选择商品
setTimeout(() => {
document.querySelectorAll('.food-item').forEach(item => {
if (item.textContent.includes('珍珠奶茶')) {
item.querySelector('.add-btn').click();
}
});
// 点击结算
document.querySelector('.checkout-btn').click();
}, 1000);
""")
真实浏览器的优势:不需要处理登录验证码、Cookie过期、OAuth回调等头疼问题。你的浏览器已经登录了所有网站,Agent直接接管即可。
4.4 file_patch:精准的增量修改
file_patch比file_write更精细,它允许Agent只修改文件中需要改的部分,而不是重写整个文件。这在代码修改场景下尤为重要:
# file_patch 示例:修复配置文件中的一个错误
agent.file_patch(
path="/etc/nginx/sites-available/myapp",
search="proxy_pass http://127.0.0.1:5000;",
replace="proxy_pass http://127.0.0.1:5000;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;"
)
4.5 安全机制:ask_user + L0约束
Agent拥有系统级控制能力,安全至关重要。GenericAgent通过两层机制保障安全:
L0元规则约束:高风险操作(删除文件、发送消息、支付操作等)必须经过ask_user确认。
ask_user工具:Agent在不确定或高风险场景下主动暂停,向用户确认:
# Agent内部的安全检查逻辑(简化版)
def should_ask_user(action):
HIGH_RISK_PATTERNS = [
"rm ", "rmdir", "DELETE", "DROP",
"支付", "转账", "send_message",
"git push", "deploy", "publish"
]
return any(pattern in str(action) for pattern in HIGH_RISK_PATTERNS)
# 执行前检查
if should_ask_user(proposed_action):
confirmation = agent.ask_user(
f"即将执行高风险操作: {proposed_action}\n是否继续?"
)
if not confirmation:
return "操作已取消"
五、Agent Loop:100行代码的执行引擎
GenericAgent的核心执行循环只有约100行代码,却实现了完整的感知→推理→执行→记忆闭环。
5.1 循环结构
# agent_loop.py 核心逻辑(简化版,约100行)
def agent_loop(task, memory, tools, max_turns=20):
"""
GenericAgent的核心执行循环
感知环境 → 任务推理 → 调用工具执行 → 经验写入记忆 → 循环
"""
messages = [{"role": "user", "content": task}]
working_checkpoint = memory.load_working_context(task)
for turn in range(max_turns):
# 1. 构建prompt:L0规则 + L2事实 + L1匹配的L3 Skill + 工作检查点
system_prompt = build_prompt(
meta_rules=memory.L0,
global_facts=memory.L2,
relevant_skills=memory.query_l1(task),
working_context=working_checkpoint
)
# 2. 调用LLM推理
response = llm.chat(
system=system_prompt,
messages=messages,
tools=tools.get_schemas()
)
# 3. 检查是否完成
if response.finish_reason == "stop":
# 任务完成,触发记忆更新
memory.start_long_term_update(
task=task,
execution_trace=messages,
outcome="success"
)
return response.content
# 4. 执行工具调用
tool_results = []
for tool_call in response.tool_calls:
result = tools.execute(tool_call)
tool_results.append(result)
# 安全检查:高风险操作暂停
if tool_call.name in HIGH_RISK_TOOLS:
confirmation = tools.ask_user(
f"即将执行: {tool_call.name}({tool_call.args})\n确认?"
)
if not confirmation:
tool_results[-1] = "操作已被用户取消"
# 更新工作检查点
memory.update_working_checkpoint(
action=tool_call,
result=result
)
# 5. 将工具结果加入消息历史
messages.append({"role": "assistant", "content": response.content})
for call, result in zip(response.tool_calls, tool_results):
messages.append({"role": "tool", "content": result})
# 超过最大轮次,保存进度
memory.start_long_term_update(
task=task,
execution_trace=messages,
outcome="max_turns_reached"
)
return "任务执行达到最大轮次,进度已保存。"
5.2 prompt构建:信息密度最大化
Agent Loop中最关键的设计决策是prompt的构建策略——这也是GenericAgent "Token高效"的核心秘密。
def build_prompt(meta_rules, global_facts, relevant_skills, working_context):
"""
核心策略:上下文信息密度最大化
不塞满窗口,只放最相关的信息
"""
parts = []
# L0 元规则:必须包含,但通常很短(< 500 tokens)
parts.append(f"## 系统规则\n{meta_rules}")
# L2 全局事实:只包含与当前任务相关的
# 关键:不是全部事实,而是按相关性筛选的子集
relevant_facts = filter_by_relevance(global_facts, working_context)
if relevant_facts:
parts.append(f"## 已知事实\n{relevant_facts}")
# L3 匹配的Skill:最关键的信息
# 如果有完全匹配的Skill,直接提供SOP,让Agent一步到位
if relevant_skills:
skill_descriptions = []
for skill in relevant_skills:
skill_descriptions.append(
f"### 技能: {skill.name} (v{skill.version})\n"
f"触发词: {skill.trigger}\n"
f"步骤:\n{format_steps(skill.steps)}\n"
f"历史成功率: {skill.success_rate}\n"
f"平均Token消耗: {skill.token_cost_avg}"
)
parts.append(f"## 可复用技能\n" + "\n".join(skill_descriptions))
# 工作上下文:当前任务的状态
parts.append(f"## 当前状态\n{working_context}")
return "\n\n".join(parts)
与传统Agent的对比:
传统Agent(如Claude Code)的prompt构建:
系统提示(数千tokens)+ 完整对话历史(可能数十万tokens)+ 工具文档
→ 总计:200K - 1M tokens
GenericAgent的prompt构建:
L0规则(~500 tokens)+ 相关事实(~500 tokens)+ 匹配的Skill(~1000-2000 tokens)+ 工作上下文(~2000 tokens)
→ 总计:< 5K tokens(有匹配Skill时)
→ 新任务探索时:< 30K tokens
10倍Token效率的秘密:不是用更小的模型,不是用更短的回答,而是让每次推理都有最大的信息密度——不浪费一个Token在无关信息上。
5.3 技能匹配与降级策略
当Agent收到一个新任务时,记忆系统的查询逻辑如下:
def query_memory(task_description):
"""
分级查询记忆,从精确匹配到模糊匹配到全新探索
"""
# 1. 精确匹配:L1索引命中,且触发词完全匹配
exact_match = l1_index.exact_query(task_description)
if exact_match:
return {"type": "skill_direct", "skill": exact_match}
# 2. 语义匹配:L1索引中语义最相近的Skill
semantic_match = l1_index.semantic_query(task_description, top_k=3)
if semantic_match and semantic_match[0].similarity > 0.75:
return {"type": "skill_adapt", "skill": semantic_match[0]}
# 3. 经验参考:L4归档中相似任务的记录
archive_refs = l4_archive.query(task_description, top_k=2)
if archive_refs:
return {"type": "explore_with_reference", "references": archive_refs}
# 4. 全新任务:只有L0+L2提供基础上下文
return {"type": "full_exploration"}
这个分级策略意味着:使用时间越长,Agent越可能直接命中L3 Skill,Token消耗越低。这就是"越用越聪明、越用越省"的技术基础。
六、实战:从零搭建一个GenericAgent应用
6.1 安装与配置
# 1. 克隆仓库
git clone https://github.com/lsdefine/GenericAgent.git
cd GenericAgent
# 2. 安装最小依赖
pip install requests streamlit pywebview
# 3. 配置API Key
cp mykey_template.py mykey.py
# 编辑 mykey.py
# mykey.py 配置示例
# Claude API
api_key = "sk-ant-xxxxx"
model = "claude-sonnet-4-20250514"
# 或者使用 OpenAI 兼容接口
# api_base = "https://api.openai.com/v1"
# api_key = "sk-xxxxx"
# model = "gpt-4o"
# 或者使用国内模型
# api_base = "https://api.moonshot.cn/v1"
# api_key = "sk-xxxxx"
# model = "kimi-latest"
# 4. 启动
python launch.pyw
如果习惯现代Python工作流:
git clone https://github.com/lsdefine/GenericAgent.git
cd GenericAgent
uv pip install -e ".[ui]"
cp mykey_template.py mykey.py
python launch.pyw
6.2 连接不同前端
GenericAgent支持多种前端接入方式,覆盖主流IM和桌面场景:
# 微信接入(扫码即用)
pip install pycryptodome qrcode requests
python frontends/wechatapp.py
# Telegram Bot
# 在 mykey.py 中添加:
# tg_bot_token = "YOUR_BOT_TOKEN"
# tg_allowed_users = [YOUR_USER_ID]
python frontends/tgapp.py
# QQ Bot(WebSocket长连接,无需公网)
pip install qq-botpy
# 在 mykey.py 中添加:
# qq_app_id = "YOUR_APP_ID"
# qq_app_secret = "YOUR_APP_SECRET"
python frontends/qqapp.py
# 飞书 Bot
pip install lark-oapi
python frontends/fsapp.py
# 企业微信 Bot
pip install wecom_aibot_sdk
python frontends/wecomapp.py
# 钉钉 Bot
pip install dingtalk-stream
python frontends/dingtalkapp.py
# Qt桌面应用
python frontends/qtapp.py
# 备选Streamlit UI
streamlit run frontends/stapp2.py
6.3 实战案例1:量化选股Skill的进化
让我们追踪一个Skill从无到有的完整进化过程:
第一周:用户第一次说"帮我筛选创业板EXPMA金叉、换手率>5%的股票"
Agent推理过程:
1. 查询L1索引 → 无匹配Skill → 进入full_exploration模式
2. 通过code_run安装mootdx → 获取行情数据
3. 编写EXPMA计算逻辑 → 筛选符合条件的股票
4. 执行中遇到数据源断连 → 添加重试逻辑
5. 返回筛选结果
6. 将执行路径固化为L3 Skill: stock_screening_v1
7. 更新L1索引,添加"股票筛选"路由
Token消耗: ~8,500
第二周:用户说"帮我看看今天哪些股票符合条件"
Agent推理过程:
1. 查询L1索引 → 命中stock_screening_v1 → 直接加载Skill
2. 按SOP执行:连接数据源 → 计算指标 → 筛选 → 返回
3. 发现换手率数据偶有缺失 → 改进容错逻辑
4. 更新Skill为stock_screening_v1.5
Token消耗: ~2,400
第四周:用户说"增加MACD底背离条件"
Agent推理过程:
1. 查询L1索引 → 命中stock_screening_v1.5
2. 在已有SOP基础上增加MACD计算步骤
3. 重构为多指标筛选框架
4. 更新Skill为stock_screening_v2.0
Token消耗: ~3,200
一个月后:用户说"筛选股票"
Agent推理过程:
1. 查询L1索引 → 精确命中stock_screening_v2.1
2. 直接执行成熟SOP,无需任何探索
3. 返回结果
Token消耗: ~1,200
Token消耗趋势:8500 → 2400 → 3200 → 1200。随着Skill成熟,Token消耗趋于稳定低位。增加新功能时有小幅上升,但远低于首次探索的消耗。
6.4 实战案例2:自动化浏览器操作
GenericAgent的真实浏览器控制能力是它的杀手级特性。以下是实际可运行的场景:
# 场景:自动在美团外卖上下单奶茶
# 用户只需说:"帮我点一杯珍珠奶茶"
# Agent的执行流程(通过web_scan + web_execute_js):
# Step 1: 扫描当前页面
page_info = agent.web_scan()
# Agent理解到当前在桌面,需要先打开美团
# Step 2: 打开美团外卖
agent.web_execute_js("window.open('https://waimai.meituan.com')")
# Step 3: 等待页面加载后搜索
agent.web_execute_js("""
document.querySelector('input[class*="search"]').value = '珍珠奶茶';
document.querySelector('button[class*="search"]').click();
""")
# Step 4: 扫描搜索结果,选择店铺
search_results = agent.web_scan()
# Agent根据L2中存储的用户偏好(如"喜茶优先")选择店铺
# Step 5: 选择商品并加入购物车
agent.web_execute_js("""
// 选择第一个结果中的珍珠奶茶
document.querySelectorAll('.food-card').forEach(card => {
if (card.textContent.includes('珍珠奶茶')) {
card.querySelector('.add-button').click();
}
});
""")
# Step 6: 确认订单(触发ask_user安全确认)
agent.ask_user("购物车中已有珍珠奶茶×1,是否提交订单?")
# 用户确认后,Agent点击提交
# Step 7: 固化为Skill
# 整个流程被保存为 L3 Skill: meituan_order_v1
# 下次用户说"帮我点外卖"即可一键执行
6.5 实战案例3:通过ADB控制手机
GenericAgent还支持通过ADB控制Android设备,实现移动端自动化:
# 前置条件:手机开启USB调试,连接电脑
adb devices
# 场景:查询支付宝近3个月超2000元的支出
# 用户:"帮我查一下支付宝最近3个月花了多少钱,超过2000的列出来"
# Agent执行流程:
# 1. ADB截图获取当前屏幕
# 2. 分析界面,找到支付宝图标
# 3. 通过ADB模拟点击打开支付宝
# 4. 导航到"账单"页面
# 5. 滚动并截图,OCR识别交易记录
# 6. 筛选金额>2000的记录
# 7. 汇总返回
# 8. 固化为Skill: alipay_expense_tracker_v1
七、技术报告核心发现:Token效率的秘密
GenericAgent的技术报告(arXiv:2604.17091)提供了详细的实验数据。以下是核心发现:
7.1 上下文信息密度最大化
技术报告提出了一个核心设计原则:上下文信息密度最大化(Contextual Information Density Maximization)。
传统思路:上下文窗口越大越好,尽可能多地提供背景信息。
GenericAgent的思路:上下文窗口中的每一条信息都应该对当前推理有直接贡献,无关信息不只是浪费Token,还会增加模型的认知负担,导致幻觉和错误。
信息密度 = 对当前推理有用的信息量 / 总上下文长度
传统Agent: 有用信息 ~5%, 总长度 200K → 密度 0.025%
GenericAgent: 有用信息 ~60%, 总长度 <30K → 密度 0.2%
密度提升8倍,这就是Token消耗降低10倍的数学基础。
7.2 实验数据
| 基准测试 | GenericAgent | SWE-Agent | OpenHands | Claude Code |
|---|---|---|---|---|
| SWE-bench Lite | 31.2% | 28.6% | 26.4% | 33.8% |
| Token消耗(avg) | ~3.2K | ~28K | ~35K | ~42K |
| Token效率比 | 1.0x | 8.8x | 10.9x | 13.1x |
在保持任务成功率可比的前提下,GenericAgent的Token消耗是同类框架的1/6到1/13。
7.3 分层记忆的消融实验
技术报告还做了消融实验,验证每层记忆的贡献:
| 配置 | SWE-bench Lite | Token消耗 |
|---|---|---|
| 无记忆(纯对话) | 18.4% | ~45K |
| +L0元规则 | 22.1% | ~38K |
| +L2全局事实 | 24.8% | ~32K |
| +L3技能 | 30.5% | ~5K(有匹配时) |
| 全部五层 | 31.2% | ~3.2K(有匹配时) |
L3技能层的加入是Token效率的质变点——有了可复用的SOP,Agent不需要重新探索,直接按流程执行即可。
八、与主流Agent框架的对比
8.1 GenericAgent vs OpenClaw
| 维度 | GenericAgent | OpenClaw |
|---|---|---|
| 代码量 | ~3K行 | ~530K行 |
| 能力获取 | 自我进化 | 预装插件生态 |
| 浏览器 | 注入真实浏览器 | 沙箱/无头浏览器 |
| OS控制 | 键鼠+视觉+ADB | 多Agent委派 |
| 记忆 | 五层分级 | 会话内+MCP |
| 部署 | pip install | 多服务编排 |
| 定位 | 个人极简Agent | 全平台AI助手 |
选择建议:如果你想要一个"轻装上阵、越用越懂你"的个人Agent,选GenericAgent;如果你需要"开箱即有丰富功能、多平台支持"的全能助手,选OpenClaw。
8.2 GenericAgent vs Claude Code
| 维度 | GenericAgent | Claude Code |
|---|---|---|
| 上下文 | <30K(分层记忆) | 200K+(全量历史) |
| 会话状态 | 跨会话持久化 | 会话内无状态 |
| 自进化 | 原生支持 | 不支持 |
| 代码专精 | 通用+系统控制 | 代码开发深度优化 |
| 交互方式 | 多前端(微信/QQ/飞书等) | CLI |
选择建议:编程场景选Claude Code(代码理解更深入),日常自动化场景选GenericAgent(跨会话记忆+多前端)。
8.3 GenericAgent vs DeerFlow
| 维度 | GenericAgent | DeerFlow |
|---|---|---|
| 架构 | 单Agent+技能树 | 多Agent协同 |
| 复杂度 | 3K行核心代码 | 大型框架 |
| 适用场景 | 个人日常自动化 | 复杂任务拆解与协作 |
| Token效率 | 极高(分层记忆) | 中等(多轮Agent间通信) |
选择建议:个人场景用GenericAgent(轻量高效),团队级复杂工作流用DeerFlow(多Agent协同)。
九、安全与风险:系统能力越强,安全越重要
9.1 当前安全机制
GenericAgent的安全机制相对简单,主要包括:
- L0元规则约束:高风险操作需ask_user确认
- ask_user工具:关键操作前的用户确认
- 权限边界:Agent继承当前用户的系统权限,无额外提权
9.2 潜在风险与建议
作为一个直接控制系统(浏览器+终端+文件系统+键鼠+ADB)的Agent,GenericAgent的安全边界需要开发者特别注意:
# 建议的安全增强措施
# 1. 沙箱隔离:在Docker容器中运行Agent
# docker run -it --rm \
# -v /path/to/workspace:/workspace \
# --network host \
# generic-agent
# 2. 文件系统只读挂载:限制Agent的写入范围
# mount -o ro /important/data /mnt/readonly
# 3. 审计日志:记录Agent的每一次工具调用
import logging
audit_logger = logging.getLogger("agent_audit")
audit_logger.setLevel(logging.INFO)
def audited_execute(tool_call):
audit_logger.info(f"Tool: {tool_call.name}, Args: {tool_call.args}")
return tools.execute(tool_call)
# 4. 网络白名单:限制Agent可访问的网络地址
ALLOWED_DOMAINS = ["api.openai.com", "api.moonshot.cn", "localhost"]
def check_network_access(url):
from urllib.parse import urlparse
domain = urlparse(url).netloc
if domain not in ALLOWED_DOMAINS:
raise PermissionError(f"Network access to {domain} is not allowed")
# 5. 敏感操作二次确认
CONFIRM_PATTERNS = [
r"rm\s+-rf", r"git\s+push\s+--force",
r"DELETE\s+FROM", r"DROP\s+TABLE",
r"transfer|转账|支付"
]
十、性能优化:让Agent跑得更快更省
10.1 Skill版本管理策略
随着使用时间增长,L3 Skill库可能变得庞大。优化策略:
# Skill修剪:定期清理低成功率的Skill
def prune_skills(memory, threshold=0.5, min_uses=3):
"""移除成功率低于阈值且使用次数达到最低要求的Skill"""
for skill_name, skill in memory.L3.items():
if (skill.success_count + skill.fail_count >= min_uses and
skill.success_rate < threshold):
memory.archive_skill(skill_name) # 归档而非删除
memory.remove_l1_index(skill_name) # 清理索引
# Skill合并:将相似Skill合并为更通用的版本
def merge_similar_skills(memory, similarity_threshold=0.85):
"""语义相近的Skill合并"""
all_skills = list(memory.L3.values())
for i, skill_a in enumerate(all_skills):
for skill_b in all_skills[i+1:]:
sim = compute_skill_similarity(skill_a, skill_b)
if sim > similarity_threshold:
merged = merge_sops(skill_a, skill_b)
memory.L3[merged.name] = merged
memory.archive_skill(skill_a.name)
memory.archive_skill(skill_b.name)
10.2 L1索引的向量检索优化
# 使用轻量级向量索引加速L1查询
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
class L1VectorIndex:
def __init__(self, embedding_dim=1536):
self.embeddings = np.zeros((0, embedding_dim))
self.skill_names = []
self.embedding_model = "text-embedding-3-small"
def add_skill(self, name, description):
embedding = get_embedding(description, self.embedding_model)
self.embeddings = np.vstack([self.embeddings, embedding.reshape(1, -1)])
self.skill_names.append(name)
def query(self, task_description, top_k=3):
query_embedding = get_embedding(task_description, self.embedding_model)
similarities = cosine_similarity(
query_embedding.reshape(1, -1), self.embeddings
)[0]
top_indices = np.argsort(similarities)[-top_k:][::-1]
return [
(self.skill_names[i], similarities[i])
for i in top_indices
if similarities[i] > 0.5 # 相似度阈值
]
10.3 并行Skill执行
对于可以并行执行的多个Skill:
import asyncio
async def execute_skills_parallel(agent, skills, task):
"""并行执行多个独立Skill"""
results = await asyncio.gather(*[
agent.execute_skill(skill, task)
for skill in skills
])
return dict(zip([s.name for s in skills], results))
# 示例:同时执行股票筛选和新闻摘要
# skills = [stock_screening_v2, news_summary_v1]
# results = await execute_skills_parallel(agent, skills, "晨报")
十一、生态与社区
11.1 百万级Skill库
2026年3月10日,GenericAgent发布了百万级Skill库,覆盖编程、办公、数据分析、金融、生活等多个领域。这意味着新用户可以快速从社区获取成熟Skill,而不需要自己从零培养。
11.2 Datawhale入门教程
Datawhale团队出品了《Hello GenericAgent》教程,从安装到原理全面覆盖:
- 教程地址:https://datawhalechina.github.io/hello-generic-agent/
- GitHub仓库:https://github.com/datawhalechina/hello-generic-agent
11.3 政务场景落地:"政务龙虾"Dintal Claw
GenericAgent已在政务场景落地——"政务龙虾"Dintal Claw,基于GenericAgent构建的政务智能助手,支持政策查询、办事指引、智能问答等功能。
十二、总结与展望
12.1 GenericAgent的核心创新
GenericAgent给AI Agent领域带来了三个重要洞察:
少即是多:3K行代码 + 9个原子工具 > 数十万行代码 + 上百工具。能力不来源于预装,而来源于进化。
信息密度 > 信息量:不是给模型更多上下文就好,而是给模型更相关的上下文。分层记忆的本质是信息检索优化。
经验可积累:AI Agent不应该每次都从零开始。通过结构化的记忆系统,Agent的使用时间越长,效率越高、成本越低。
12.2 局限性
客观地说,GenericAgent也有明显的局限:
- 安全机制不够成熟:对于拥有系统级控制能力的Agent,当前的安全边界偏弱,生产环境使用需要额外加固
- Skill质量参差不齐:自动生成的Skill质量取决于底层LLM的能力,有时会产生不可靠的SOP
- 多用户协作缺失:当前设计面向个人使用,不支持多人共享Skill(虽然有云端社区,但缺乏权限和版本管理)
- 错误恢复有限:当Skill执行失败时,回退策略相对简单,缺乏精细的事务性保障
12.3 未来展望
GenericAgent代表的"自我进化"方向,很可能是AI Agent发展的下一个范式:
- 从"工具调用"到"能力生长":未来的Agent不再是被动地调用工具,而是主动地积累能力
- 从"大模型"到"精模型":不是追求更大的模型,而是让更小的模型通过经验积累获得更强的能力
- 从"云端统一"到"端侧个性化":每个用户的Agent实例将拥有独特的技能树,这些技能是个人使用习惯的结晶
3K行代码种出的技能树,才刚刚发芽。
项目地址:https://github.com/lsdefine/GenericAgent
技术报告:https://arxiv.org/abs/2604.17091
入门教程:https://datawhalechina.github.io/hello-generic-agent/
飞书文档:https://my.feishu.cn/wiki/CGrDw0T76iNFuskmwxdcWrpinPb
本文作者:程序员茄子 | 发布时间:2026年4月26日