基于Cangjie的多智能体协同框架
介绍
苍穹用来形容广阔的天空、壮阔的景象,代表着壮阔、辽阔的意境。比如《诗经》中的“苍苍者天”,《庄子》中的“苍苍乎如在其上”的描述。苍穹常常被用来比喻高远的理想或抱负,也可以指代神话中的天空之神。
苍穹(CangChain)框架服务于软件厂商、模型厂商,帮助终端用户快速开发AI应用。
团队成员来自华为仓颉语言库团队、高校课题组(江南大学/浙江大学...)、社区开发者,是一支横跨学届和业界的开发团队。
特性
-
🚀 Query优化
-
🚀 提示词优化
-
💪 严格的鉴权机制
-
🛠️ 支持联邦学习
-
🌍 隐私保护机制
路线
软件架构
架构图
源码目录
.
├── build
│ ├── bin
│ └── cangchain
├── c_src
│ ├── api_request_multi.c
│ ├── build.sh
│ ├── google_search.c
│ ├── hnswlib
│ ├── hnswlibcj.h
│ ├── hnswlib.cpp
│ ├── include
│ ├── onnxruntime_c_api.h
│ ├── onnxruntime_cj_api.c
│ ├── onnx_runtime_wrapper.cc
│ └── README.md
├── doc
│ ├── assets
│ ├── cangchain-project-v3.pdf
│ ├── design.md
│ ├── feature_api.md
│ ├── langchain survey report.pdf
│ ├── privacy_data_training.csv
│ ├── 关于CUDA运行模型.pdf
│ ├── 分词器调研.pdf
│ ├── 提示词优化和向量调研.pdf
│ └── 自主智能体.pdf
├── lib
│ ├── charset
│ ├── crypto4cj
│ ├── libapirequest.so
│ ├── libcrypto.so
│ ├── libduckdb.so
│ ├── libgooglesearch.so
│ ├── libhnswlibcj.so
│ ├── libmycrypto.so
│ ├── libonnxruntime_cj_api.so
│ ├── libonnxruntime_providers_cuda.so
│ ├── libonnxruntime_providers_shared.so
│ ├── libonnxruntime_providers_tensorrt.so
│ ├── libonnxruntime.so -> libonnxruntime.so.1.15.1
│ ├── libonnxruntime.so.1.15.1
│ ├── libonnxutils.so
│ ├── README.md
│ └── uuid4cj
├── LICENSE
├── module.json
├── resource
│ ├── embedding_model.onnx
│ ├── privacy
│ ├── tokenizer.json
│ └── vectordb
├── src
│ ├── agent
│ ├── chain
│ ├── llmapi
│ ├── main.cj
│ ├── onnx
│ ├── onnxrt
│ ├── schema
│ ├── titoken
│ ├── tool
│ └── vdclient
└── test
├── HLT
└── LLT
doc文档目录,用于存放设计、API接口等文档src仓颉源码目录c_srcC语言的源码库,主要存放跨语言操作的封装C库的代码test测试目录lib项目依赖的三方库目录,包括C库so、仓颉库cjo等buildCangChain项目的编译生成的文件module.jsonCangChain项目编译的配置文件,cjpm会读取这个文件
接口说明
主要类和函数接口说明详见 API
使用说明
编译构建
cangjie版本: 0.51.4 C语言库的构建:
cd c_src
./build.sh
设置环境变量:
先切换到CangChain项目根目录
cd ../
export CANGCHAIN_HOME=$(pwd)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CANGCHAIN_HOME/lib:$CANGCHAIN_HOME/lib/charset:$CANGCHAIN_HOME/lib/crypto4cj:$CANGCHAIN_HOME/lib/uuid4cj
export CANGJIE_PATH=$CANGCHAIN_HOME/lib:$CANGCHAIN_HOME/lib/charset:$CANGCHAIN_HOME/lib/crypto4cj:$CANGCHAIN_HOME/lib/uuid4cj
export OPENAI_API_KEY=sess-y9JL7f5Y922VDrzonaDuQZmwIfqnkdUq7xqb8oea
export GOOGLE_API_KEY=AIzaSyDtj86vYYVIt2wA4TPpbrerYweQSq4xaX0
export SEARCH_ENGINE_ID=f4ece9b85ae75403b
*CANGCHAIN_HOME是CangChain项目的根目录,OPENAI_API_KEY、GOOGLE_API_KEY、SEARCH_ENGINE_ID是项目测试使用,请勿扩散。
仓颉语言的编译:
cjpm clean
cjpm build
生成的可执行文件的路径:./build/bin/main
功能示例
OpenAI模型交互
功能示例描述:
对输入的语句先进行分词,然后计算embedding
示例代码如下:
import llmapi.*
main() {
let llm = getLLMInstance(LLMType.OPEN_AI)
println(llm.query("who are you?"))
println(llm.query("translate what you have said into Chinese"))
}
执行结果如下:
I am an AI language model developed by OpenAI. I am designed to assist with answering questions and providing information on various topics.
我是由OpenAI开发的AI语言模型。我被设计用于回答问题并提供各种主题的信息。
onnx模型推理
功能示例描述:
加载模型,推理输出结果。
- 关于基于CUDA运行模型
- CangChain项目测试模型,下载链接: https://pan.baidu.com/s/1OcIcQYM6r8iJG2W3Xn00rw?pwd=pyrw 提取码: pyrw
示例代码如下:
from std import collection.*
from std import fs.*
from std import os.*
from std import os.posix.*
from std import math.*
import onnx.*
import titoken.*
func isPrivateData(res:HashMap<String, IDArray>):Int64{
var arr = softmax(res)
var maxIndex = argmax(arr)
return maxIndex;
}
func softmax(res:HashMap<String, IDArray>):ArrayList<Float32>{
var output = (res["output"] as XDArray<Float32>).getOrThrow()
var v1:Float32 = output[0,0]
var v2:Float32 = output[0,1]
var expv1 = math.exp(v1)
var expv2 = math.exp(v2)
var sum = expv1 + expv2
var s1 = expv1/sum
var s2 = expv2/sum
var arr = ArrayList<Float32>()
arr.append(s1)
arr.append(s2)
return arr
}
func argmax(arr:ArrayList<Float32>):Int64{
return if(arr[0]>arr[1]){0}else{1}
}
main() {
let model = ONNXModel(path:getcwd()+"/resource/privacy/privacy_model.onnx", option: CPU)
println("${model}")
let tokenizer = Tokenizer(tokensFilePath:getcwd()+"/resource/privacy/tokenizer.json")
var encodeInput = HashMap<String, IDArray>()
var attention_mask = [[1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 0], [1, 1, 1, 1, 1, 1, 0]]
encodeInput["input_ids"] = XDArray<Int64>([[101, 3736, 5722, 4689, 102]])
encodeInput["attention_mask"] = XDArray<Int64>([[1, 1, 1, 1, 1]])
// let encodeInput = tokenizer(["江苏省"])
println("encodeInput: ${encodeInput}")
let output = model(encodeInput)
println("output: ${output}")
let result = isPrivateData(output)
println("result: ${result}")
if(result == 0){
println("非隐私数据")
}else{
println("隐私数据")
}
}
执行结果如下:
cpuModel Path: /home/yang/sda/github/cangchain/resource/privacy/privacy_model.onnx
inputs:
input_ids: [-1 -1] TYPE_INT64
attention_mask: [-1 -1] TYPE_INT64
inputs:
output: [-1 2] TYPE_FLOAT
encodeInput: [(input_ids, [[ 101 3736 5722 4689 102]]), (attention_mask, [[1 1 1 1 1]])]
output: [(output, [[-1.070493 0.485676]])]
result: 1
隐私数据
计算embedding
功能示例描述:
对输入的语句先进行分词,然后计算embedding
示例代码如下:
from std import collection.*
from std import os.*
from std import os.posix.*
import titoken.*
main(): Int64 {
var sentences:Array<String> = ["苍穹是什么","苍穹"]
//分词
let tokenizer = Tokenizer(tokensFilePath: getcwd()+"/resource/privacy/tokenizer.json")
let embedder = Embedder(modelPath: getcwd()+"/resource/embedding_model.onnx", tokensFilePath:getcwd()+"/resource/tokenizer.json")
println("tokens: ${tokenizer(sentences)}")
//计算词嵌入向量
let sentence_embeddings = embedder(sentences)
println("embedding: ${sentence_embeddings}")
return 0
}
执行结果如下:
tensor.device: cpu
tokens: [(input_ids, [[ 101 5721 4957 102 784 720 102]
[ 101 5721 4957 102 784 720 102]]), (token_type_ids, [[0 0 0 0 0 0 0]
[0 0 0 0 0 0 0]]), (attention_mask, [[1 1 1 1 1 1 1]
[1 1 1 1 1 1 1]])]
embedding: [[0.010859, -0.030754, -0.044018, 0.058661, -0.166377, -0.056781, -0.050275, ..., 0.076615, 0.034190], [0.010859, -0.030754, -0.044018, 0.058661, -0.166377, -0.056781, -0.050275, -0.043021, -0.039094, -0.065006, ..., 0.076615, 0.034190]]
本地向量数据访问
功能示例描述: 在本地构建向量数据,文本相似度计算,
示例代码如下:
from std import collection.*
from std import os.*
from std import os.posix.*
from std import fs.*
import titoken.*
import vdclient.*
main(){
//创建Client
let vdclient = Client(persist_directory: getcwd()+"/resource/vectordb/")
//创建collection
let meta_data = HashMap<String, String>([("author","cangchain"),("name", "test")])
let vdclient_collection = vdclient.create_collection("test", meta_data)
//添加文本
println("添加文本")
let documents = Array<String>(["苍穹用来形容广阔的天空、壮阔的景象,代表着壮阔、辽阔的意境。比如《诗经》中的“苍苍者天”,《庄子》中的“苍苍乎如在其上”的描述。苍穹常常被用来比喻高远的理想或抱负,也可以指代神话中的天空之神。","服务于软件厂商、模型厂商,帮助终端用户快速开发AI应用"])
let metadata1 = HashMap<String, String>(("doc66","id66"))
let metadata2 = HashMap<String, String>(("doc67","id67"))
let isadd = vdclient_collection.add(Array<Int32>([66,67]), documents, Array<HashMap<String, String>>([metadata1,metadata2]))
if (isadd) {
println("添加成功!")
}
//更新文本
println("\n更新文本")
let update_id = Array<Int32>([1])
let update_text = "PyTorch 提供特定于领域的库,如 TorchText, TorchVision 和 TorchAudio,所有这些库都包含数据集。我们将Dataset作为参数传递给DataLoader。这将在我们的数据集上包装一个迭代器,并支持自动批处理、采样、随机打乱和多进程数据加载。 在这里,我们定义了一个大小为64的批处理,即 DataLoader 迭代器中的每个元素都会返回一个由64个特征和标签组成的批次数据。"
println("更新内容:${update_text}")
let isupdate = vdclient_collection.update(update_id, None, Array<String>([update_text]), None)
if (isupdate) {
println("更新成功!")
}
//query
println("\nQuery_1")
let query_text = "PyTorch"
let top_k: Int32 = 1
println("Query: ${query_text}")
let query_res = vdclient_collection.query(Array<String>([query_text]), top_k, None)
let res_doc = query_res[0][0][3]
println("doc信息:")
println("内容:${res_doc}")
println("dist:${query_res[1][0]}")
println("\nQuery_2")
let query_text2 = "苍穹是什么"
let top_k2: Int32 = 1
println("Query2: ${query_text2}")
let query_res2 = vdclient_collection.query(Array<String>([query_text2]), top_k2, None)
let res_doc2 = query_res2[0][0][3]
println("doc信息:")
println("内容:${res_doc2}")
println("dist:${query_res2[1][0]}")
//结束Client
let kill = vdclient.end()
}
执行结果如下:
tensor.device: cpu
添加文本
添加成功!
更新文本
更新内容:PyTorch 提供特定于领域的库,如 TorchText, TorchVision 和 TorchAudio,所有这些库都包含数据集。我们将Dataset作为参数传递给DataLoader。这将在我们的数据集上包装一个迭代器,并支持自动批处理、采样、随机打乱和多进程数据加载。 在这里,我们定义了一个大小为64的批处理,即 DataLoader 迭代器中的每个元素都会返回一个由64个特征和标签组成的批次数据。
更新成功!
Query_1
Query: PyTorch
doc信息:
内容:服务于软件厂商、模型厂商,帮助终端用户快速开发AI应用
dist:0.532009
Query_2
Query2: 苍穹是什么
doc信息:
内容:服务于软件厂商、模型厂商,帮助终端用户快速开发AI应用
dist:1.007491
成功保存!
Google Search
功能示例描述:
利用谷歌的search的api,获得专业知识和答案,以减轻大模型的幻觉。
示例代码如下:
from std import collection.*
from std import fs.*
import titoken.*
import vdclient.*
import tool.*
main(){
let google_tool = GoogleSearchRun()
let result: String = google_tool.run("cangjie")
println("result: ${result}")
return 0
}
执行结果如下:
result: "Cangjie ... This article is about the legendary figure. For the typing method, see Cangjie input method. Cangjie [tsʰáŋ.tɕjě] (simplified Chinese: 仓颉; ...",
开源协议
MIT
参与贡献
欢迎给我们提交PR,欢迎给我们提交Issue,欢迎参与任何形式的贡献。