Skip to main content

Expression 內建函數

Asgard Expression 系統提供 8 個專用的內建函數,讓您在動態內容中處理對話歷史、資料轉換和編碼需求。

內建函數清單

對話歷史函數

history

取得指定索引區間的歷史對話紀錄清單

語法:

history(start, end);

參數:

  • start (number):起始位置(0 開始,支援負數倒數)
  • end (number):結束位置(包含該位置,支援負數倒數)

回傳:

  • string:對話紀錄清單,格式為純文字,每行代表一筆對話

範例:

history(0, 2); // 回傳索引 0, 1, 2 的三筆對話
history(-3, -1); // 回傳倒數第 3 筆至最後一筆對話
history(0, -1); // 回傳所有對話

回傳格式:

bot: Hi, how can I help you?
user: Hello, I need assistance with my order.
bot: Okay, please provide your order number.

historySize

取得目前頻道的歷史對話紀錄數量

語法:

historySize();

回傳:

  • number:對話記錄數量

範例:

historySize(); // 回傳數字,例如:5

資料處理函數

urlEncode

將字串進行 URL 編碼

語法:

urlEncode(val);

參數:

  • val (string):要編碼的字串

回傳:

  • string:URL 編碼後的結果

範例:

urlEncode('hello world'); // "hello%20world"
urlEncode('搜尋關鍵字'); // "%E6%90%9C%E5%B0%8B%E9%97%9C%E9%8D%B5%E5%AD%97"
urlEncode(prevMessage); // 將前一則訊息進行 URL 編碼

vecToStr

將向量陣列轉換為字串格式

語法:

vecToStr(vector, prefix, suffix, delimiter);

參數:

  • vector (array<number>):向量陣列
  • prefix (string):開頭字符
  • suffix (string):結尾字符
  • delimiter (string):分隔符

回傳:

  • string:轉換後的字串

範例:

vecToStr([1, 2, 3], '{', '}', ','); // "{1,2,3}"
vecToStr([0.1, 0.5, 0.8], '[', ']', '|'); // "[0.1|0.5|0.8]"

xpathExtract

利用 XPath 在 XML 文件中進行查找

語法:

xpathExtract(xml, path);

參數:

  • xml (string):XML 文件內容
  • path (string):XPath 查詢語法

回傳:

  • string:所有符合元素的 Inner Text,以換行符號分隔

範例:

const xml = '<root><item>1</item><item>2</item></root>';
xpathExtract(xml, '/root/item'); // "1\n2"

xpathExtract(responseXml, '//result/title'); // 查詢所有結果標題

日期時間函數

isoNow

回傳特定時區當前日期時間的 RFC3339 格式字串

語法:

isoNow(timezone);

參數:

  • timezone (string):IANA 時區名稱

回傳:

  • string:RFC3339 格式的當前日期時間

範例:

isoNow('Asia/Taipei'); // "2025-05-27T01:08:44+08:00"
isoNow('UTC'); // "2025-05-26T17:08:44Z"
isoNow('America/New_York'); // "2025-05-26T13:08:44-04:00"

isoToday

回傳特定時區當前日期的 RFC3339 格式字串

語法:

isoToday(timezone);

參數:

  • timezone (string):IANA 時區名稱

回傳:

  • string:RFC3339 格式的當前日期

範例:

isoToday('Asia/Taipei'); // "2025-05-27"
isoToday('UTC'); // "2025-05-26"
isoToday('America/New_York'); // "2025-05-26"

進階應用範例

對話分析與摘要

// 分析對話趨勢
(() => {
const totalMessages = historySize();
if (totalMessages === 0) return '無對話記錄';

// 取得最近對話進行分析
const recentCount = Math.min(10, totalMessages);
const recentHistory = history(-recentCount, -1);

const lines = recentHistory.split('\n');
const userMessages = lines.filter(line => line.startsWith('user:')).length;
const botMessages = lines.filter(line => line.startsWith('bot:')).length;

return `分析最近 ${recentCount} 則對話:使用者 ${userMessages} 則,機器人 ${botMessages}`;
})();

API 整合與資料處理

// 建構複雜 API 查詢
(() => {
const keyword = prevMessage || '';
const encodedQuery = urlEncode(keyword);
const timestamp = isoNow('UTC');

// 建構查詢參數
const params = [`q=${encodedQuery}`, `timestamp=${timestamp}`, `channel=${customChannelId || 'default'}`].join('&');

return `https://api.example.com/search?${params}`;
})();

XML 資料解析

// 處理複雜 XML 回應
(() => {
if (!xmlResponse) return '無 XML 資料';

try {
const titles = xpathExtract(xmlResponse, '//result/title');
const prices = xpathExtract(xmlResponse, '//result/price');

if (!titles) return '無搜尋結果';

const titleList = titles.split('\n');
const priceList = prices ? prices.split('\n') : [];

let result = '搜尋結果:\n';
titleList.forEach((title, index) => {
const price = priceList[index] || '價格未知';
result += `${index + 1}. ${title} - ${price}\n`;
});

return result;
} catch (e) {
return 'XML 解析錯誤';
}
})();

向量資料處理

// 向量相似度比較
(() => {
const userVector = [0.1, 0.5, 0.8, 0.2];
const systemVector = [0.2, 0.4, 0.7, 0.3];

// 格式化為不同格式供不同系統使用
const formats = {
json: vecToStr(userVector, '[', ']', ','),
csv: vecToStr(userVector, '', '', ','),
sql: vecToStr(userVector, '(', ')', ','),
};

return `向量格式化結果:
JSON: ${formats.json}
CSV: ${formats.csv}
SQL: ${formats.sql}`;
})();

時間序列處理

// 建立帶時間戳的日誌
(() => {
const timezone = 'Asia/Taipei';
const now = isoNow(timezone);
const today = isoToday(timezone);

const messageCount = historySize();
const hasError = prevError ? true : false;

const logEntry = {
date: today,
timestamp: now,
messages: messageCount,
hasError: hasError,
channel: customChannelId || 'unknown',
};

return `[${now}] 日誌:頻道 ${logEntry.channel}${logEntry.messages} 則訊息${hasError ? ',有錯誤' : ''}`;
})();

效能最佳化

函數調用快取

// ✅ 快取常用值,避免重複調用
(() => {
const messageCount = historySize(); // 只調用一次
const timezone = 'Asia/Taipei';
const currentTime = isoNow(timezone); // 只調用一次

if (messageCount === 0) {
return `[${currentTime}] 新對話開始`;
}

const recentHistory = messageCount > 5 ? history(-5, -1) : history(0, -1);

return `[${currentTime}] 對話記錄:${messageCount} 則\n${recentHistory}`;
})();

條件式執行

// ✅ 避免不必要的函數調用
(() => {
// 先檢查基本條件
if (!prevMessage) return '無訊息需要處理';

// 只在需要時才調用編碼函數
const needsEncoding = /[^\w\s]/.test(prevMessage);
const processedMessage = needsEncoding ? urlEncode(prevMessage) : prevMessage;

return `處理結果:${processedMessage}`;
})();

這些內建函數提供強大的資料處理能力,讓您能在 Expression 中輕鬆處理複雜的對話邏輯和資料轉換需求。