我用代码
本文档介绍了如何通过编写代码来配置 PPAgent 应用,包括集成各种后端模型、消息源以及技能。
具体的每一个消息源等的详细配置,请参考配置部分。
本页部分内容由AI生成,如有配置问题,可在首页二维码加群交流。
配置概述
PPAgent 应用通过 src/app.ts
文件进行配置,它是应用的实际启动入口,负责初始化 PPAgent 实例并配置所有组件。配置内容主要包括以下几个部分:
- 后端模型 (Bots)
- 消息源 (Sources)
- 技能 (Skills)
- 智能体 (Agents)
- 任务 (Tasks)
启动流程
PPAgent 应用的启动流程如下,通常情况无需更改这部分代码:
- 通过
starter
函数初始化 PPAgent 实例 - 加载默认插件和 API 插件
- 启动应用
- 设置重启监听器
typescript
const starter = async () => {
const chat = new PPAgent({
// 配置项
});
await chat.use(defaultPlugin);
await chat.use(apiPlugin);
await chat.start();
return chat;
};
// 初始化应用
const chater = await starter();
// 监听重启事件,如果未来不使用页面配置,也可以删除这句代码
chater.globalEvent.on("restart", () => onRestart(chater));
配置后端模型 (Bots)
后端模型是处理用户消息并生成回复的组件。PPAgent 内置多种类型的后端模型,例如:
- DeepSeek(支持推理)
- OpenAI (GPT系列)
- Ollama
- 百度文心
- 腾讯混元
- 智谱清言
- FastGPT
- RagFlow
- QAnything
- Dify Agent
- Coze 等
每个后端模型的配置方式如下(详细配置项可以参考配置手册、API手册或者ts的描述文件):
typescript
{
name: 机器人类型名称,
options: {
instanceName: "实例名称",
// 其他特定于该机器人类型的配置项
}
}
例如,配置一个 OpenAI 机器人:
typescript
{
name: OpenAIBot.params.name,
options: {
instanceName: "openai-bot", // 需要全局唯一
apiKey: "你的API密钥",
apiBase: "API基础URL",
chatOptions: {
model: "gpt-4o-mini",
}
}
}
配置消息源 (Sources)
消息源是接收用户消息的渠道,PPAgent 支持多种消息源:
- 微信公众号 (WCOASource)
- 企业微信 (WeWorkSource)
- 钉钉机器人 (DingRobotSource)
- 飞书 (FeishuSource)
- QQ (QQSource)
- 微信对话平台 (WCAISource) 等
还有第三方实现的各类消息源,如基于gewechat的消息源,实现对接个人微信。
每个消息源的配置方式如下:
typescript
{
name: 消息源类型名称,
options: {
instanceName: "实例名称",
// 其他特定于该消息源类型的配置项
}
}
例如,配置一个飞书消息源:
typescript
{
name: FeishuSource.params.name,
options: {
instanceName: "feishu-app",
appId: "你的应用ID",
appSecret: "你的应用密钥",
replayTextMode: "stream",
richTextTitle: true
}
}
配置技能 (Skills)
技能是扩展智能体功能的组件,例如语音转文字、文字转语音、绘图、视频生成、消息总结等。PPAgent 内置了一些简单的技能,如:
- Sovite项目的文字转语音
- SenseVoice项目的语音转文字
- 百度文字转语音和语音转文字
- FishAudio的文字转语音
- 硅基流动的文字转语音和语音转文字
- 腾讯的文字转语音和语音转文字
- 讯飞的文字转语音和语音转文字
- 智普的绘图
- 智普的视频生成
- 硅基流动的绘图
技能配置方式如下:
typescript
{
name: 技能类型名称,
options: {
instanceName: "实例名称",
// 其他特定于该技能类型的配置项
}
}
例如,配置语音转文字技能:
typescript
{
name: SenseVoiceSTTSkill.params.name,
options: {
apiHost: "技能API地址",
authType: "basic",
userName: "用户名",
password: "密码",
instanceName: "sensevoice-stt",
}
}
配置智能体 (Agents)
智能体定义了如何将消息源、机器人和技能关联起来,包括回复规则、消息处理方式等。配置内容包括:
- 关联的消息源
- 使用的机器人
- 响应规则
- 消息分割规则
- 发送模式
- 技能应用规则
- ...
typescript
{
sourceInstanceNames: ["消息源实例名称列表"],
name: "代理名称",
botResponseRule: {
instanceName: "机器人实例名称",
respondTo: {
at: true,
refered: true,
names: ["xxx"] // 触发回复的关键名称,与上面是或的关系
}
},
minSendInterval: 1000, // 最小发送间隔
bufferWordsMinCount: 30, // 缓冲区最小字数
maxSplitCount: 5, // 最大分割数
splitImageFromBotText: true, // 从机器人文本中分离图片
removeImageAfterSplit: false, // 分离后是否删除图片
sendMode: "queue", // 发送模式
fallbackAnswer: "该功能暂不支持😀", // 失败时的回复
skillRules: [
// 技能应用规则,请参考详细配置手册
],
multiActiveChatInConversationTips: "哎呦,等我这句话说完再回复下一个!", // 多活跃聊天提示
multiActiveChatInConversationMode: "pool_tips", // 多活跃聊天模式
sendErrorLog: true // 是否发送错误日志
}
配置任务 (Tasks)
任务是定时或事件触发的操作,可以用于系统维护、定时通知等。支持的任务类型包括:
- 消息源事件任务 (SourceEventTaskTrigger)
- 全局事件任务 (GlobalEventTaskTrigger)
- 定时任务 (CronTaskTrigger)
任务配置方式如下:
typescript
{
name: "任务名称",
triggerName: 触发器类型名称,
triggerOptions: {
// 触发器配置项
},
runnerName: 运行器类型名称,
runnerOptions: {
// 运行器配置项
}
}
例如,配置定时任务:
typescript
{
name: "定时任务",
triggerName: CronTaskTrigger.params.name,
triggerOptions: {
cron: "*/5 * * * * *" // 每5秒执行一次
},
runnerName: EchoTaskRunner.params.name,
runnerOptions: {
instanceName: "echo-task-runner"
}
}
热重启机制
PPAgent 应用提供了热重启机制,当触发重启事件时,会先停止当前实例,然后创建新实例:
typescript
const onRestart = async (chater: PPAgent) => {
await chater.stop();
setTimeout(async () => {
chater.globalEvent.emit(GlobalEventNames.APP_RESTARTED);
chater.off("restart", onRestart);
chater = await starter();
chater.globalEvent.on("restart", () => onRestart(chater));
}, 500);
};
注意事项
- 配置文件中可能包含敏感信息(API密钥、密码等),请妥善保管和加密
- 在实际部署时,应从环境变量或配置文件中读取这些敏感信息,而不是硬编码
- 使用前先阅读各组件的文档,了解其支持的功能和配置选项
- 测试配置时,建议先使用较简单的配置,确认可用后再添加更多复杂配置
完整的配置示例
以下是一个完整的配置示例,包括一个 OpenAI 机器人、飞书消息源、语音转文本技能、智能体和定时任务:
typescript
// src/app.ts
import {
config,
PPAgent,
OpenAIBot,
IOpenAIBotOptions,
FeishuSource,
IFeishuSourceOptions,
ISenseVoiceSTTSkillOptions,
SenseVoiceSTTSkill,
SourceChatMessageType,
SourceEventType,
GlobalEventTaskTrigger,
IEventTaskTriggerOptions,
EchoTaskRunner,
GlobalEventNames,
defaultPlugin,
apiPlugin,
getLogger
} from "ppagent";
import { v4 } from "uuid";
const logger = getLogger("app");
const starter = async () => {
logger.debug("app starting");
const chat = new PPAgent({
name: "default",
agentServiceOptions: {
models: {
bots: [
{
name: OpenAIBot.params.name,
options: {
instanceName: "openai-bot-main",
apiKey: process.env.OPENAI_API_KEY || "your-api-key-here",
apiBase: "https://api.openai.com/v1",
chatOptions: {
model: "gpt-4o",
},
} as IOpenAIBotOptions,
},
],
sources: [
{
name: FeishuSource.params.name,
options: {
instanceName: 'feishu-app-main',
appId: process.env.FEISHU_APP_ID || 'your-app-id-here',
appSecret: process.env.FEISHU_APP_SECRET || 'your-app-secret-here',
replayTextMode: 'stream',
richTextTitle: true,
} as IFeishuSourceOptions,
},
],
skills: [
{
name: SenseVoiceSTTSkill.params.name,
options: {
apiHost: "https://your-api-host.com",
authType: "basic",
userName: process.env.STT_USER || "username",
password: process.env.STT_PASSWORD || "password",
instanceName: "sensevoice-stt-main",
} as ISenseVoiceSTTSkillOptions
}
],
agents: [
{
sourceInstanceNames: ["feishu-app-main"],
name: "chat-agent-main",
botResponseRule: {
instanceName: "openai-bot-main",
respondTo: {
at: true,
refered: true,
names: ["小助手"]
}
},
minSendInterval: 1000,
bufferWordsMinCount: 30,
maxSplitCount: 5,
splitImageFromBotText: true,
removeImageAfterSplit: false,
sendMode: "queue",
fallbackAnswer: "该功能暂不支持😀",
skillRules: [
{
instanceName: "sensevoice-stt-main",
messageTypes: [SourceChatMessageType.AUDIO],
skillApplyOn: "source",
}
],
multiActiveChatInConversationTips: "请稍等,我正在回复上一个问题...",
multiActiveChatInConversationMode: "pool_tips",
sendErrorLog: true,
}
],
},
},
offline: config.offline,
taskServiceOptions: {
tasks: [
{
name: "应用启动通知任务",
triggerName: GlobalEventTaskTrigger.params.name,
triggerOptions: {
instanceName: "app-started-task-trigger",
eventNames: [GlobalEventNames.APP_STARTED]
} as IEventTaskTriggerOptions,
runnerName: EchoTaskRunner.params.name,
runnerOptions: {
instanceName: "app-started-task-runner"
}
},
],
},
});
// 注册插件
await chat.use(defaultPlugin);
await chat.use(apiPlugin);
// 启动应用
await chat.start();
logger.debug("app started");
return chat;
};
// 热重启处理函数
const onRestart = async (chater: PPAgent) => {
logger.warn("app restarting, stop old instance...");
await chater.stop();
setTimeout(async () => {
logger.warn("old instance stopped, start new instance...");
chater.globalEvent.emit(GlobalEventNames.APP_RESTARTED, { title: "应用重启", id: v4() });
chater.off("restart", onRestart);
chater = await starter();
logger.warn("new instance started");
chater.globalEvent.on("restart", () => onRestart(chater));
}, 500);
};
// 启动应用
const chater = await starter();
chater.globalEvent.on("restart", () => onRestart(chater));