Hawa Code CodeMode API OutputSchema 自进化学习

1、使用示例

Hawa 执行 github 统计任务,快速了解一下 Hawa Code 是如何自主识别补全Code Mode API 中缺失的 OutputSchema 。


任务

分析一下我的 github 账号下哪个项目 git 提交次数最多,这个项目每个提交人的提交次数分别是多少,不统计 fork 的项目

执行步骤解析

1、获取当前 github 账号信息

● Code(async () => {                              …
const me = await codemode.github.get_me();
return me;
})
⎿ {
"login": "jiweigang1",
"id": 3021648,
...
"updated_at": "2026-09-25T16:40:17Z"
}
}

2、查询当前账号下所有项目

Code(async () => {                                                                                                                                     …
const repos = [];
let page = 1;
let total = 0;
while (page <= 3) {
const r = await codemode.github.search_repositories({ query: "user:jiweigang1 fork:false", sort: "updated", order: "desc", perPage: 100, page,
minimal_output: false });
if (!r || !r.items || r.items.length === 0) break;
total = r.total_count || 0;
repos.push(...r.items.filter(x => !x.fork).map(x => ({ name: x.full_name, default_branch: x.default_branch, pushed_at: x.updated_at })));
if (r.items.length < 100) break;
page++;
}
return { total, count: repos.length, repos };
})
⎿ {
"total": 46,
"count": 46,
...
}
]
}

3、获取 list_commits API 方法参数和描述

● Code(async () => {                                                …
const docs = await codemode.describe("github.list_commits");
return docs;
})
⎿ {
"path": "github.list_commits",
"description": "Get list of commits of a branch in a GitHub repository. Returns at least 30 results per page by default, but can return more if
specified using the perPage parameter (up to 100).\n\n...
"types": "declare const github: {\n /**\n * Get list of commits of a branch in a GitHub repository. Returns at least 30 results per page by
default, but can return more if specified using the per...
"kind": "method"
}

4、在第一个仓库试一次 list_commits,确认返回结构。

● Code(async () => {                                                                                                              …
const r = await codemode.github.list_commits({ owner: "jiweigang1", repo: "hcode-pages", perPage: 100, fields: ["sha"] });
return { type: Array.isArray(r), len: Array.isArray(r) ? r.length : null, sample: Array.isArray(r) ? r[0] : r };
})
⎿ {
"type": true,
"len": 100,
"sample": {
"sha": "ae4e3858d448ea22cb6d3a4edef099f42bddb529"
}
}

5、推断出出参结构并进行保存,同时统计出提交次数最多的项目

● Code(async () => {                                                                                                                                            …
await codemode.saveOutputSchema("github.list_commits", {
type: "array",
items: {
type: "object",
properties: {
sha: { type: "string" },
html_url: { type: "string" },
commit: {
type: "object",
properties: {
message: { type: "string" },
author: {
type: "object",
properties: {
name: { type: "string" },
email: { type: "string" },
date: { type: "string" }
}
},
committer: {
type: "object",
properties: {
name: { type: "string" },
email: { type: "string" },
date: { type: "string" }
}
}
}
},
author: {
type: "object",
nullable: true,
properties: {
login: { type: "string" },
id: { type: "number" }
}
},
committer: {
type: "object",
nullable: true,
properties: {
login: { type: "string" },
id: { type: "number" }
}
}
}
}
}, "list_commits returns an array of commit objects; fields depend on the fields parameter");

const repos = ["hcode-pages","all-skills","hawa-code","Agent-Toolkit","hawa-hands","hawa-computer-use","hawa-cli-analysis","hawa-code2","Appwite","claude
-code","MetaDesktop","blog","The-Story-of-the-Stone","claude-cookbooks","ucode-ide","claude-code-sdk","claude-code-starter","vsclilogger","agenter","deep-l
earning-newbie","MAmzGO","AmzGo","fine-dev","AlipayAmzGO","ByteBuddy-learning","Vercel","ad-agent","Dagger2-learning","maven-jar-template","WechatAmzgo","s
uperdisplay","test-app","AWS","hexo-theme-navy-at","hexo-theme-navy","Apm-Tester","ChromeDriver","GradleTest","asm-learning","resource","eshop","JgWidgets"
,"StreetBox","google-collections","wf","jg-table"];
const branches = { "hcode-pages":"master","hawa-computer-use":"master","hexo-theme-navy":"master","test-app":"master","GradleTest":"master","asm-learning
":"master","resource":"master","eshop":"master","StreetBox":"master","google-collections":"master","wf":"master","jg-table":"master","JgWidgets":"gh-pages"
};
const counts = [];
for (const repo of repos) {
let page = 1, total = 0;
while (true) {
const r = await codemode.github.list_commits({ owner: "jiweigang1", repo, sha: branches[repo] || "main", perPage: 100, page, fields: ["sha"] });
const len = Array.isArray(r) ? r.length : 0;
total += len;
if (len < 100) break;
page++;
if (page > 50) break; // 安全上限,单仓库最多统计 5000 条
}
counts.push({ repo, total });
}
counts.sort((a, b) => b.total - a.total);
return counts;
})
⎿ [
{
"repo": "hcode-pages",
...
"total": 1
}
]

5、提交最多的是 hcode-pages(3185 次)。接下来统计该项目每个提交人的提交次数。

Code(async () => {                                                                                                                                     …
const perAuthor = {};
const perLogin = {};
let page = 1;
while (true) {
const r = await codemode.github.list_commits({ owner: "jiweigang1", repo: "hcode-pages", sha: "master", perPage: 100, page, fields: ["commit",
"author"] });
if (!Array.isArray(r) || r.length === 0) break;
for (const c of r) {
const name = c.commit && c.commit.author ? c.commit.author.name : "unknown";
perAuthor[name] = (perAuthor[name] || 0) + 1;
const login = c.author && c.author.login ? c.author.login : name;
perLogin[login] = (perLogin[login] || 0) + 1;
}
if (r.length < 100) break;
page++;
if (page > 60) break;
}
const byName = Object.entries(perAuthor).sort((a, b) => b[1] - a[1]);
const byLogin = Object.entries(perLogin).sort((a, b) => b[1] - a[1]);
return { pages: page, total: byName.reduce((s, x) => s + x[1], 0), byName, byLogin };
})
⎿ {
"pages": 32,
"total": 3185,
...
]
]
}

统计结果

分析完成。以下是统计结果(已排除 fork 项目,共 46 个非 fork 仓库)。

提交次数最多的项目

https://github.com/jiweigang1/hcode-pages — 共 3185 次提交,远超第二名 hawa-code(1237 次)。这是一个 Hexo 博客(GitHub Pages)仓库,包含大量 Hexo
主题相关的历史提交,因此提交者数量非常多(按 Git 署名统计有上千人)。

该项目提交人 Top 15(按 commit 署名统计)

┌─────────────────────────┬──────────┐
│ 提交人 │ 提交次数 │
├─────────────────────────┼──────────┤
│ Tommy Chen (tommy351) │ 306 │
│ curbengh │ 193 │
│ jigang │ 122 │
│ lzjqsdd │ 116 │
│ Xuanwo │ 107 │
│ Abner Chou (NoahDragon) │ 78 │
│ dependabot[bot] │ 70 │
│ MDLeom │ 69 │
│ Sukka (SukkaW) │ 65 │
│ YoshinoriN │ 52 │
│ hexo-crowdin[bot] │ 46 │
│ 漩涡 │ 45 │
│ yoshinorin │ 44 │
│ D-Sketon │ 33 │
│ dependabot-preview[bot] │ 33 │
└─────────────────────────┴──────────┘

其余提交人均在 30 次以下,绝大多数只有 1~5 次提交(大量 Hexo 主题/插件的一次性上游提交)。

2、OutputSchema 自主学习

2.1、OutputSchema 缺失

Hawa Code 把 MCP 转换为 Code Mode provider API,然后通过 JavaScript 代码级联调用这些 API 执行任务。

MCP 工具都会提供 InputSchema,可以保证工具正确调用,但是很多 MCP 工具都没有提供 OutputSchema,这就导致模型无法判断出参结果,从而无法做到代码级联调用。

2.2、OutputSchema 解析

如果 MCP 工具没有提供 OutputSchema,比较简单的方式是通过工具的返回结果推断 OutputSchema,这个方式常规场景中都是可行的,其有两种方案:

  • 执行调用时候程序通过返回结果生成 OutputJSONSchema,优势是不需要模型参与。
  • 通过模型自主的判断 OutputJSONSchema,优势是可以提高准确性。

Hawa Code 采取的方案就是第二种,符合 Hawa Code 理念“模型会越来越聪明,应该让模型去主导更多的事情”。同时模型可以提高准确性,比如返回结果是一个枚举值,模型可以通过多次的返回结果去订正 OutputJSONSchema。

在以上的示例中 HawaCode 首先从第一个仓库试一次 list_commits,确认返回结构。然后进行了保存。模型可以选择多种方式和合适的时机去解析 OutputSchema 结构。

2.3、渐进式学习

在以上的示例中,Hawa Code 执行了多次调用,相比传统的工具调用大量减少了模型调用次数,示例中不存在分页多次调用问题,Hawa Code 在多次使用 Github API 过程中会逐渐补全缺失的 OutputSchema,如果 OutputSchema 是全量的,Hawa Code 执行两次模型调用就可以完成此任务。

  1. 获取 API 描述和出参和入参结构
  2. 执行业务落地代码调用。

Code Mode 非常适合处理复杂的业务逻辑任务,而对于传统的工具调用就很难做到,比如执行上千次分页调用。

欢迎了解使用 Hawa Code:https://www.hawacode.com/docs/