梅科尔工作室Cangjie Magic探索-个性化的意象联想诗词创作大师
在我接触仓颉编程语言的几天里,我惊叹于其搭建智能体的效率,简单的配置环境和快捷的编译,让我忍不住去实现一些小的案例,来分享我溢于言表的感受。尤其是仓颉结合MCP协议,简洁高效的编程带来了极好的开发和使用体验。
考虑到现在仓颉Magic还未达到公测版本,较少的api和包会限制一些想法,但就体验来说依旧是瑕不掩瑜的,能让大家看到该语言的优越性和前景。
接下来我将以步骤级教程,分享个性化的意象联想诗词创作大师的案例实现。案例功能我结合了我目前对于仓颉的浅显理解,在能达到范围之内实现的一个简单案例,能够凸显仓颉语言的优势和MCP服务的强大能力,案例主要分为MCP Client和MCP Server的构建。
笔者其实有很多创意想法,奈何于自己对于仓颉语法的理解浅薄和早期版本的仓颉还不够成熟,我的案例实现了使用者用一些词来描述感觉,server端智能体根据描述选取合适的意象(一种类别的诗词意象内置于一种组件中)返回到client端的智能体,它根据描述和意象创作诗词。
1. 下拉仓颉Magic包和准备大模型API
进入到仓颉Magic GitCode网页CangjieMagic,在登录后点击下载zip文件,可以顺手点一个star。
将压缩包解压到新创建的项目文件夹中,笔者新建名为project cangjie。
我的案例开发将基于官方的示例包,简单来说server端位于示例包下,便于环境配置,client端则随意,server和client的交互在本地通过指令进行(详见下文)。
通常情况下server端以SSE服务器形式,提供url给client端使用,为快速体验,在此不做拓展。
可用大模型api和名称见下图。主要使用到两个参数:API_KEY和模型名称
2.MCP server端开发
仓颉安装详见我另一个博客:超简单的仓颉安装教程
将解压的CangjieMagic-dev文件夹拖到CodeArts IDE for Cangjie快捷方式打开或在IDE中打开指定路径文件夹,沿下图路径进入到examples目录下。案例主要以框选的文件为参考实现,其中health_monitor和mcp_server是MCP的服务端,mcp_client为客户端。
点击进入mcp_sever的main.cj,可以看到组件工具和智能体Agent直接使用cangjie的语法糖(@tool、@agent)定义
话不多说,我们创建自己的server端。照葫芦画瓢,右键examples目录新建文件夹,笔者命名为test。在文件夹下新建文件,如:main.cj。
在toml配置文件中添加以下代码,后续build编译时能将server打包成可执行文件
// 若文件名是其他,记得替换test
[package.package-configuration."magic.examples.test"]
output-type = "executable"
在main.cj里首先得package自身,并导入一些包
// 若文件名是其他,记得替换test
package magic.examples.test
import magic.dsl.*
import magic.prelude.*
import magic.config.Config
import magic.mcp.StdioMCPServer
import log.LogLevel
我按照我的想法搭建好组件和server端的诗词意象推荐agent,仓颉的语法参考官网仓颉编程语言官网,在此推荐官网首页右下角的仓颉小智智能体,能够一定程度上帮助解决语法报错问题,但别指望它写出来一个sever端。
以下是server端的简单demo示例,你可以在此基础上改写你的想法:
package magic.examples.xxx //记得替换
import magic.dsl.*
import magic.prelude.*
import magic.config.Config
import magic.mcp.StdioMCPServer
import log.LogLevel
// 组件写法:
@tool[description: "描述一下该组件"]
func xxx(形参): 输出类型 {
return xxx
}
// 如:
@tool[description: "Multiply two numbers"]
func multiply(a: Int64, b: Int64): Int64 {
return a * b
}
// 智能体写法:
@agent[
model: "siliconflow:deepseek-ai/DeepSeek-V3", // 替换为你使用的大模型
description: "小学算术计算器", // 智能体描述
tools: [xxx, multiply] // 写入可选择的组件
]
class Calculator {
@prompt(
"精通小学课本上的算术计算"
"对于加减乘除运算得心应手"
)
}
main() {
Config.env["SILICONFLOW_API_KEY"] = "sk-jc*********************nd" // 替换为你的api_key
Config.logLevel = LogLevel.INFO
Config.logFile = "./logs/mcp-server.log"
let agent = Calculator() //导入智能体提示词
StdioMCPServer.startWith([agent])
}
进入终端输入cjpm build,将代码打包成可执行文件
cjpm build
如果返回以下,则server端到此完成
// Terminal
Array contains empty value: []
cjpm build success
3.MCP Client端开发
在仓颉工程文件夹下新建文件夹,笔者新文件夹叫做demo。选择dynamic后我们需要在toml文件里单独指明cj文件打包类型。
在src文件夹下创建一个main.cj文件(代码package自身)和mcp_client文件夹,mcp_client文件夹下再创建main.cj用来编写客户端代码
// src.main 注意替换demo
package demo
在cjpm.toml中配置依赖和必要代码,以下代码直接复制修改
[dependencies]
magic = { path = "D:\\project cangjie\\CangjieMagic-dev" } // 替换为自己的SDK地址
[package]
cjc-version = "0.53.18"
compile-option = "-Woff unused --cfg \"faiss=disable,sqlite=disable,llamacpp=disable,http=curl\" "
description = "nothing here"
link-option = ""
name = "demo"
output-type = "dynamic" // 在下面要单独制定打包类型
src-dir = ""
target-dir = ""
version = "1.0.0"
[package.package-configuration."demo.mcp_client"]
output-type = "executable" // 在此指定
[profile.test.build]
compile-option = "-Woff unused --cfg \"faiss=disable,sqlite=disable,llamacpp=disable,http=curl\" " // 禁用警告
好,现在在mcp_client.main中完成客户端的代码编写
// src.mcp_client.main
package demo.mcp_client
import magic.dsl.*
import magic.prelude.*
import magic.config.Config
import log.LogLevel
@agent[
model: "siliconflow:deepseek-ai/DeepSeek-V3",
executor: "react",
mcp: [
{ command: "cjpm", args: ["run", "--skip-build", "--name", "magic.examples.test"] } // 使用命令自动调用本地的server端
// {url:"https:*******"}
// 如果server端以SSE服务器形式
]
]
class ShapeClientAgent {
@prompt(
"你是一个创作诗词大师,用户会用自然语言描述。"
"你需要将描述转发给server端的诗意推荐助手,由它选择合适的意象来描述用户的语言。"
"你只需负责理解用户的描述,从诗意推荐助手返回的意象中再次筛选合适的意象,并创作诗词。"
"若用户没有指定形式,请写一首现代诗和一首古诗/词,按照用户输入内容模仿代表性诗人的风格,如:用户如果输入“爱情”作为描述,那么你可能需要模仿徐志摩的风格进行创作。"
"输出结果后,输出诗意推荐助手推荐的意象和你从中选取的意象和原因"
)
}
main() {
Config.env["SILICONFLOW_API_KEY"] = "sk-j**********************d"
Config.logLevel = LogLevel.INFO
Config.logFile = "./logs/mcp-client.log"
let agent = ShapeClientAgent()
let result = agent.chat("蓝调、忧郁")
println(result)
}
完成后,在终端输入cjpm build
D:\project cangjie\demo>cjpm build
Warning: there is no '.cj' file in directory 'D:\project cangjie\CangjieMagic-dev\src\examples\mini_rag\data', and its subdirectories will not be scanned as source code
Warning: there is no '.cj' file in directory 'D:\project cangjie\CangjieMagic-dev\src\examples\mini_rag\tiktoken', and its subdirectories will not be scanned as source code
Array contains empty value: []
cjpm build success
到此,server端和client端均完成编写
4.案例运行展示
在客户端运行终端,输入:
cjpm run --name demo.mcp_client
(base) PS D:\project cangjie\demo> cjpm run --name demo.mcp_client
Warning: there is no '.cj' file in directory 'D:\project cangjie\CangjieMagic-dev\src\examples\mini_rag\data', and its subdirectories will not be scanned as source code
Warning: there is no '.cj' file in directory 'D:\project cangjie\CangjieMagic-dev\src\examples\mini_rag\tiktoken', and its subdirectories will not be scanned as source code
**现代诗:《蓝调》**
(模仿徐志摩风格)
你是一抹忧郁的蓝,
像江水上浮动的孤帆,
轻轻,轻轻,
载不动许多愁。
青鸟掠过天空的伤口,
衔来一封未寄出的信,
在莲花的倒影里,
我读懂了沉默。
**古诗:《虞美人·江上愁》**
(模仿李煜风格)
江水流春去欲尽,
孤帆远影碧空尽。
青鸟不传云外信,
莲花空结雨中愁。
**诗意推荐助手推荐的意象**:
1. 江 (river)
2. 湖 (lake)
3. 天空 (sky)
4. 青鸟 (bluebird)
5. 莲花 (lotus)
6. 离愁 (parting sorrow)
7. 孤帆 (lonely sail)
8. 洛神 (Goddess of the Luo River)
9. 彼岸花 (red spider lily)
**选取的意象及原因**:
- **江**、**孤帆**:以流动的江水与孤帆的意象强化漂泊无依的忧郁,古典与现代诗中均适用。
- **青鸟**:象征未达的愿望,与“蓝调”的未完成感呼应。
- **莲花**:水中生长的纯净与哀愁,暗合“忧郁”的沉淀感。
其他意象如“洛神”“彼岸花”虽美,但偏向神话悲剧,与用户简洁的“蓝调”主题稍显疏离,故未采用。
5.结束
整体案例的实现过程非常迅速且简单,主要难点在于对仓颉语言的熟悉。仓颉语言的代码设计偏向自然语言,降低了学习门槛,同时官方提供了详细的文档教程和智能体辅助工具,进一步减轻了上手难度。随着仓颉Magic公测版本的逐步成熟以及更多案例的积累,仓颉语言将引领智能体技术和MCP(多智能体协作平台)时代的革新,开启全新的技术篇章。