OpenClaw 源码解读:从「只会聊天」到「真正干活」的 AI 框架是怎么炼成的
OpenClaw 源码解读:从「只会聊天」到「真正干活」的 AI 框架是怎么炼成的
编辑点评:OpenClaw 作为新一代 AI Agent 框架,最大的突破在于将 AI 从”聊天机器人”升级为”真正的生产力工具”。本文深入源码层面,解析其核心设计理念和实现细节,帮助开发者理解如何构建能够真正干活的 AI 系统。
如果你用过市面上的 AI 助手,可能会发现一个共同问题:它们很会聊天,但不会干活。
这种”只说不做”的 AI,本质上是一个高级聊天机器人,而不是真正的智能 Agent。
• 工具调用能力弱 – 只能调用预设的简单 API
• 安全边界模糊 – 要么权限过大危险,要么权限过小无用
OpenClaw 的源码设计,正是为了解决这些问题而生。
OpenClaw 的源码结构清晰,采用三层架构设计:
┌─────────────────────────────────────┐
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
└─────────────────────────────────────┘
┌─────────────────────────────────────┐
└─────────────────────────────────────┘
1. 会话管理核心:sessions.ts
privatesessions:Map<string,SessionState>=newMap();
asynccreateSession(config:SessionConfig):Promise<string>{
constsessionKey=generateSessionId();
constsession=newSessionState({
awaitthis.persistSession(sessionKey,session);
asyncsendMessage(sessionKey:string,message:string):Promise<Response>{
constsession=awaitthis.getSession(sessionKey);
constcontext=this.buildContext(session,message);
constresponse=awaitthis.agent.process(context);
session.update(response);
awaitthis.persistSession(sessionKey,session);
2. 工具执行引擎:tools/executor.ts
privatetoolRegistry:Map<string,Tool>=newMap();
privatepermissionMatrix:PermissionMatrix;
asyncexecute(toolName:string,params:any,context:ExecutionContext):Promise<any>{
consttool=this.toolRegistry.get(toolName);
thrownewError(`工具未找到:${toolName}`);
constpermission=this.permissionMatrix.check(
thrownewPermissionDeniedError(`权限不足:${toolName}`);
if(tool.requiresSandbox){
returnawaitthis.executeInSandbox(tool,params,context);
returnawaitPromise.race([
tool.execute(params,context),
timeout(tool.timeout||30000)
privateasyncexecuteInSandbox(tool:Tool,params:any,context:ExecutionContext):Promise<any>{
// 使用 Node.js Worker Threads 或子进程隔离
constsandbox=awaitSandbox.create({
memoryLimit:tool.memoryLimit||‘256MB’,
cpuLimit:tool.cpuLimit||‘50%’,
networkAccess:tool.networkAccess||false
returnawaitsandbox.execute(tool.code,params);
3. 模型适配器:models/adapter.ts
generate(prompt:string,options:GenerateOptions):Promise<GenerationResult>;
stream(prompt:string,options:GenerateOptions):AsyncIterable<Chunk>;
countTokens(text:string):number;
classAliyunAdapterimplementsModelAdapter{
asyncgenerate(prompt:string,options:GenerateOptions):Promise<GenerationResult>{
constresponse=awaitfetch(`${this.baseUrl}/chat/completions`,{
‘Authorization’:`Bearer ${this.apiKey}`,
‘Content-Type’:‘application/json’
model:options.model||‘qwen3.5-plus’,
messages:this.formatMessages(prompt),
max_tokens:options.maxTokens||4096,
constdata=awaitresponse.json();
returnthis.parseResponse(data);
async*stream(prompt:string,options:GenerateOptions):AsyncIterable<Chunk>{
constresponse=awaitfetch(`${this.baseUrl}/chat/completions`,{
body:JSON.stringify({/* … */,stream:true})
constreader=response.body.getReader();
constdecoder=newTextDecoder();
const{done,value}=awaitreader.read();
constchunk=decoder.decode(value);
for(constlineofchunk.split(‘\n’)){
if(line.startsWith(‘data: ‘)){
constdata=JSON.parse(line.slice(6));
yieldthis.parseChunk(data);
OpenClaw 的第一个关键方法是工具动态注册机制。
privateskillPaths:string[]=[
‘~/.local/share/openclaw/skills’,
asyncdiscover():Promise<Tool[]>{
for(constskillPathofthis.skillPaths){
constskills=awaitthis.scanDirectory(skillPath);
constmanifest=awaitthis.parseSkillManifest(skill);
consttool=this.manifestToTool(manifest);
privateasyncparseSkillManifest(skillDir:string):Promise<SkillManifest>{
constmanifestPath=path.join(skillDir,‘SKILL.md’);
constcontent=awaitfs.readFile(manifestPath,‘utf-8’);
constfrontmatter=this.extractFrontmatter(content);
description:frontmatter.description,
tools:this.parseToolsSection(content),
permissions:this.parsePermissions(content)
• 版本管理 – 支持 ClawHub 进行工具版本控制
OpenClaw 的第二个关键方法是上下文窗口智能管理。
大模型有 Token 限制(如 Qwen3.5-plus 最大 32K),但对话历史可能无限增长。如何:
1. 保留重要上下文
2. 丢弃冗余信息
3. 避免 Token 超限
privatemaxTokens:number=28000;// 预留空间给响应
privatecompressionThreshold:number=0.8;
asyncbuildContext(session:Session,newMessage:string):Promise<Context>{
constmessages=session.messages;
constcurrentTokens=this.countTokens(messages);
if(currentTokens<this.maxTokens*this.compressionThreshold){
returnthis.formatContext(messages,newMessage);
constcompressed=awaitthis.compressOldMessages(messages);
returnthis.formatContext(compressed,newMessage);
privateasynccompressOldMessages(messages:Message[]):Promise<Message[]>{
constrecentMessages=messages.slice(–recentCount);
constoldMessages=messages.slice(0,–recentCount);
if(oldMessages.length===0)returnrecentMessages;
constsummary=awaitthis.generateSummary(oldMessages);
{role:‘system’,content:`历史对话摘要:${summary}`},
privateasyncgenerateSummary(messages:Message[]):Promise<string>{
constprompt=`请总结以下对话的关键信息:
${messages.map(m=>`${m.role}: ${m.content}`).join(‘\n’)}
constresult=awaitthis.fastModel.generate(prompt);
• 分层管理 – 近期消息保留原文,早期消息压缩为摘要
OpenClaw 的第三个关键方法是子 Agent 协同机制。
privateagents:Map<string,SubAgent>=newMap();
asyncspawn(task:string,options:SpawnOptions):Promise<SubAgent>{
runtime:options.runtime||‘subagent’,
mode:options.mode||‘run’,
timeout:options.timeout||300000
agent.inheritContext(this.parentContext);
constchannel=awaitthis.createChannel(agent);
agent.setChannel(channel);
this.agents.set(agent.id,agent);
asynccoordinate(task:string):Promise<Result>{
constsubtasks=awaitthis.decomposeTask(task);
constresults=awaitPromise.all(
subtasks.map(st=>this.spawn(st.task,st.options))
returnthis.aggregateResults(results);
privateasyncdecomposeTask(task:string):Promise<Subtask[]>{
constprompt=`将以下任务分解为可并行执行的子任务:
constresult=awaitthis.model.generate(prompt);
returnJSON.parse(result.content);
constresult=awaitagent.coordinate(`
• 专业分工 – 每个子 Agent 专注特定领域
六、实战演练:用 OpenClaw 构建自动化工作流
schedule:“08***”# 每天早上 8 点
tool:tencent-security-api
types:[vulnerability,malware,apt]
constworkflow=awaitWorkflow.fromConfig(‘daily-intel.yaml’);
constresult=awaitworkflow.execute();
// 生成报告:/tmp/daily-briefing-20260407.md
// 发送通知:已发送到 security-team 频道
tool.timeout=120000;// 2 分钟
constsession=awaitsessions.spawn(task,{background:true});
constresults=awaitprocessInBatches(items,batchSize:100);
session.metadata.set(‘user_preference’,preference);
awaitmemory_search(query);
if(session.messageCount%10===0){
awaitcontextManager.compress(session);
openclawconfigshowpermissions
openclawconfigsettools.my-tool.permissionallow
openclawconfigsetsecurity.modeallowlist
openclawconfigsettools.allowlist“tool1,tool2,tool3”
• 从简单工具开始 – 先实现一个 SKILL.md,理解工具注册流程
• 善用记忆系统 – 将重要信息写入 MEMORY.md,避免上下文丢失
• 合理使用子 Agent – 复杂任务分解为独立子任务
mkdir-pskills/my-first-skill
cat>skills/my-first-skill/SKILL.md<< ‘EOF’
description: 我的第一个 OpenClaw 技能
openclawtestmy-first-skill
声明:本文基于 OpenClaw 公开源码分析,如有技术细节更新,请以官方文档为准。
• OpenClaw 官方文档:https://docs.openclaw.ai
• GitHub 仓库:https://github.com/openclaw/openclaw
• 技能市场:https://clawhub.ai
互动话题:你用过哪些 AI Agent 框架?OpenClaw 的哪些设计让你印象深刻?欢迎在评论区分享你的看法!