@vibe-lark/larkpal-agent
v0.2.30
Published
LarkPal Agent SDK — 基于火山方舟的 AI Agent 引擎,实现 larkpal RuntimeAdapter 接口
Readme
@vibe-lark/larkpal-agent
LarkPal Agent SDK — 基于火山方舟的 AI Agent 引擎,实现 larkpal RuntimeAdapter 接口。
概述
larkpal-agent 是一个通用的 AI Agent 运行时引擎,可作为 larkpal 平台的 AI 执行后端。它采用 AsyncGenerator query loop 模式,基于 Vercel AI SDK + 火山方舟(OpenAI 兼容)进行 LLM 调用。
核心能力
- RuntimeAdapter 实现 — 对接 larkpal 的运行时接口,可替代 Claude Code 作为 AI 引擎
- Tool 注册与执行 — 支持并发安全/串行策略的工具系统
- MCP Client — 内置 MCP(Model Context Protocol)客户端,支持多租户认证透传
- Skill 引擎 — 基于 YAML front matter 的 Skill 定义格式(对齐 Anthropic Claude Code 标准)
- 流式事件输出 — 适配 larkpal 的 RuntimeStreamCallbacks
安装
npm install @vibe-lark/larkpal-agent要求 Node.js >= 22.0.0
快速开始
import {
LarkpalAgentAdapter,
ToolRegistry,
defineTool,
} from '@vibe-lark/larkpal-agent'
import { z } from 'zod'
// 1. 定义工具
const greetTool = defineTool({
name: 'greet',
description: '向用户问好',
parameters: z.object({ name: z.string() }),
async execute(input) {
return { content: `Hello, ${input.name}!` }
},
})
// 2. 创建 Adapter
const adapter = new LarkpalAgentAdapter({
llm: {
baseURL: 'https://ark.cn-beijing.volces.com/api/v3',
apiKey: process.env.ARK_API_KEY!,
defaultModel: 'ep-xxx',
},
systemPrompt: 'You are a helpful assistant.',
tools: [greetTool],
})
// 3. 执行 prompt(流式)
const result = await adapter.executePrompt('session-1', {
prompt: '请向 Alice 问好',
callbacks: {
onTextDelta: (delta) => process.stdout.write(delta),
onToolCallStart: (name) => console.log(`\n[Tool] ${name}`),
},
})项目结构
src/
├── adapter/ # LarkpalAgentAdapter — RuntimeAdapter 实现
├── core/ # 核心类型定义(Message, Tool, Stream Event 等)
├── llm/ # LLM Provider(火山方舟 OpenAI 兼容)
├── mcp/ # MCP Client + Tool 桥接
├── query/ # AsyncGenerator query loop
├── skills/ # Skill 引擎(加载、解析、执行)
│ └── definitions/ # 示例 Skill 文件
└── tools/ # Tool 定义与注册表开发
# 安装依赖
npm install
# 开发模式(watch)
npm run dev
# 构建
npm run build
# 运行测试
npm test
# 类型检查
npm run typecheck多租户认证(MCP 透传)
在 SaaS 多租户场景下,larkpal-agent 支持在每次 execute 前动态注入认证头,透传到 MCP 工具调用:
const result = await adapter.executePrompt('session-1', {
prompt: '诊断空间',
authHeaders: {
'x-tenant-key': 'tenant-abc',
'x-user-id': 'user-123',
},
})Per-request LLM 配置
多租户场景下,不同租户可使用不同的 LLM 凭据:
const result = await adapter.executePrompt('session-1', {
prompt: '分析数据',
llmConfig: {
baseURL: 'https://ark.cn-beijing.volces.com/api/v3',
apiKey: 'tenant-specific-key',
model: 'tenant-specific-endpoint',
},
})Skill 格式
Skill 文件采用 YAML front matter + Markdown body 格式:
---
name: my-skill
description: "技能描述"
allowed-tools: tool-a, tool-b
effort: medium
maxTurns: 10
---
# 技能标题
## 步骤编排
1. 调用 `tool-a` 获取数据
2. 分析结果并调用 `tool-b` 写入事件日志契约
queryLoop 仍然返回 AsyncGenerator<StreamEvent>,同时会给每个事件补充可持久化 envelope 字段:
const events: AgentEventEnvelope[] = []
for await (const event of queryLoop(llmConfig, {
messages,
systemPrompt,
tools,
context,
eventRecorder: {
append(envelope) {
events.push(envelope)
},
},
})) {
// existing StreamEvent consumption still works
}推荐宿主用 JSONL 持久化 AgentEventEnvelope,再派生 run snapshot / artifact snapshot / chat transcript:
{"seq":1,"eventId":"run-a:000001","runId":"run-a","type":"tool-call-start","event":{"type":"tool-call-start","toolCallId":"call-1","toolName":"x","args":{}}}
{"seq":2,"eventId":"run-a:000002","runId":"run-a","type":"tool-call-result","event":{"type":"tool-call-result","toolCallId":"call-1","toolName":"x","result":{"ok":true}}}
{"seq":3,"eventId":"run-a:000003","runId":"run-a","type":"result","event":{"type":"result","terminal":{"reason":"completed","finalText":"已完成。","turnCount":1}}}seq 在单 run 内严格递增,eventId 可用于幂等去重。result.terminal.finalText 是宿主生成最终 assistant message 的权威文本来源。
宿主也可以用 reduceAgentRun(events) 从事件日志重建 run snapshot:
import { reduceAgentRun } from '@vibe-lark/larkpal-agent'
const snapshot = reduceAgentRun(events)
// snapshot.status / finalText / toolEvents / verifierOutput / finalArtifacts发布
npm run build
npm publishLicense
MIT
