LangSC 操作手册
适用版本:LangSC 2.5.x · 本手册随包维护,反映当前源码的真实 API 与最新发展。 定位:这是 LangSC 的权威、完整操作手册(概念 + API + 示例 + 工程约定)。它是教材实训《附录A LangSC 使用指南》的 全面升级版超集——附录 A 的全部内容在此均有覆盖并经订正,另补入 2.5.x 的新能力。两者冲突时,以本手册为准。
LangSC(Language Structure Computing,语言结构计算开发包)用 Python(ctypes)封装三套原生 C/C++ 引擎, 并在其上提供可视化与智能体两层,配套"结构化思维 = 单元·关系·属性"的教学主线:
| 层 | 组成 | 说明 |
|---|---|---|
| 智能体 | agentkit(Demo/labs/agent/) |
单/多智能体回路,可选 LangGraph |
| 可视化 | GPF 的 Show* / Draw* / Dot* |
pygraphviz 跨平台渲染 + 词云 |
| Python 封装 | gpf.py bcc.py jss.py _utils.py |
稳定、文档化的用户接口 |
| 原生引擎 | gpflib bcclib jsslib(.dll/.so/.dylib) |
定长 caller-allocated 缓冲的 C API |
| 远程服务 | BSTService 句法分析网关 · KG 知识图谱服务 | 句法树/组块/依存、知识图谱 |
三个类(GPF/BCC/JSS)完全独立,可单独使用,也可组合使用。
示例验证状态:本手册所有本地示例(GPF 分词/词性/网格/可视化、BCC 检索、JSS SQL、agentkit)均在 Windows + Python 3.14 上 逐一真跑验证,文中"实测输出 →"的结果为真实运行所得。远程示例(GPF 的
Tree/Chunk/Dep句法网关、JSS 的KG*知识图谱) 依赖联网服务:验证时句法网关处于"服务繁忙"状态,故其返回以适配器代码契约的形状给出并标注"(远程,需联网)"。
0. 相对《附录A》的新增与变化(务必先读)
| 主题 | 旧(附录A) | 新(本手册 / 2.5.x) |
|---|---|---|
| 可视化依赖 | 需系统安装 Graphviz(dot),Windows 自带 Graph/dot.exe |
改用 pygraphviz,其二进制 wheel 自带 Graphviz,三平台免装系统 Graphviz。旧 dot.exe 于 2.3.0 移除 |
| Python 版本 | 3.6+ | 3.10+(匹配 pygraphviz 二进制 wheel) |
| 句法分析(Tree/Chunk/Dep) | 连 cit.blcu.edu.cn(已失效) |
走 BSTService 公开网关 POST {parser_url}/v1/public/parser/{stree|chunk|dep},免登录;parser_url 为构造参数,默认 https://cnlp.blcu.edu.cn/ice/api。返回形状经适配器转换(Tree 不再是 {Type,Units,POS}) |
BCC Run 返回 |
引擎原始 JSON | 统一信封 {type,query,total,distinct,approximate,records:[...]},records 可被 JSS 直接建表 |
JSS Run 失败 |
返回空列表 [] |
无结果返回 [];但 SQL 错误/引擎异常/未初始化会 raise RuntimeError 并带诊断信息 |
| JSS 知识图谱 | 无 | 新增 KGImport/KGImportPath/KGList/KGSubgraph/KGExpand/KGDelete(远程 HTTP,Neo4j 后端) |
| 智能体 | 无 | 新增 agentkit:run_loop/run_pipeline/run_supervised + LangGraph 适配 |
| 路径编码 | 未规范 | 统一经 _utils.native_path(POSIX→UTF-8;Windows→ANSI+8.3 短名回退) |
| 线程安全 | 仅进程级 init 锁 | 每实例 RLock 串行化数据面;Segment/POS 走线程本地真并行 |
| 原生库架构 | x86_64 | macOS 已提供 universal(x86_64+arm64);Linux .so 仍为单架构,ARM 需另编 |
| 实训 | 8 个 lab | 10 个 lab(新增 lab9 单智能体、lab10 多智能体) |
1. 概述与安装
1.1 设计理念与核心概念
LangSC 采用三模块设计——GPF、BCC、JSS 各自独立,分别提供结构分析、语料库检索与数据搜索能力。贯穿三者的核心概念:
- 网格(Grid):GPF 的核心数据结构。文本映射为二维网格,列对应字符位置,行对应标注层次。所有分析结果最终都可加载到网格统一管理。
- 单元(Unit):网格基本元素,用坐标
(列号,行号)标识(如(2,1))。单元可横跨多列(如"北京大学"跨 4 列),并携带键值对属性(如POS=n)。 - 关系(Relation):两个单元间的有向关系,三元组
(Head, Sub, Relation),如"读"与"书"之间的VOB。 - 属性(KV):单元/关系/网格上的键值对。单元·关系·属性即"结构化思维"的三要素。
| 模块 | 全称 | 功能 |
|---|---|---|
| GPF | Grid-based Parsing Framework | 分词、词性标注、句法分析、结构化标注、可视化、FSA 规则 |
| BCC | BCC Corpus | 语料库索引与检索,词频/上下文/计数统计 |
| JSS | JSON Structured Search | JSON/JSONL 的 SQL 检索,多种索引;并含知识图谱 KG* |
1.2 安装与依赖
pip install LangSC
| 依赖 | 用途 | 备注 |
|---|---|---|
pygraphviz |
跨平台图渲染 | wheel 自带 Graphviz 二进制,无需系统安装 dot |
wordcloud |
词云 | ShowCloud |
requests |
远程调用 | 句法网关、KG 服务 |
chardet |
文件编码探测 | 语料/数据自动识别编码 |
pywin32 |
仅 Windows | 释放 DLL 句柄 |
- Python 3.10+。
- 中文渲染需宿主有 CJK 字体:DOT 模板用
fontname="fangsong";Windows 自带,Linux 需装fonts-wqy-zenhei或 Noto Sans CJK,否则中文显示为方块。词云经_find_cjk_font自动探测(可用font_path=覆盖)。 - Windows 上跑 Python 工具链(如 twine)建议
set PYTHONUTF8=1 PYTHONIOENCODING=utf-8。
1.3 导入与构造
from LangSC import GPF, BCC, JSS
gpf = GPF() # 默认数据路径 ./data
gpf = GPF("./mydata") # 指定数据路径
bcc = BCC("corpus") # 指定语料目录(路径建议 ASCII)
jss = JSS("./kb") # 指定 JSON 数据目录(自动索引并加载)
完整构造签名:
GPF(dataPath="./data", parser_url="https://cnlp.blcu.edu.cn/ice/api")
BCC(dataPath="./data")
JSS(dataPath, log_level=0, log_filename="", kg_url="https://cit.blcu.edu.cn/jss", kg_timeout=60)
| 参数 | 所属 | 说明 |
|---|---|---|
dataPath |
三者 | 数据/语料/JSON 目录;自动索引。相对路径会被规范为 ./ 前缀 |
parser_url |
GPF | 句法分析网关基址(Tree/Chunk/Dep);公网走 /ice/api(裸 /api 禁 POST) |
log_level / log_filename |
JSS | 日志级别(0 关)与日志文件;空串不写文件 |
kg_url / kg_timeout |
JSS | 知识图谱服务基址与超时;本机直连用 http://127.0.0.1:8100 |
1.4 功能概览
| 模块 | 功能域 | 主要方法 |
|---|---|---|
| GPF | 结构计算 | Parse()(分词/词性/句法树/依存/组块) |
| GPF | 可视化 | ShowStructure() ShowGrid() ShowCloud() |
| GPF | 网格操作 | SetText() AddUnit() AddRelation() AddStructure() GetUnit() GetRelation() |
| GPF | 数据表 | CallTable() GetItem() GetItemKV() |
| GPF | FSA | CallFSA() GetNode() |
| BCC | 语料检索 | Run() CallBCC() AddBCCKV() GetBCCKV() ClearBCCKV() |
| JSS | 数据搜索 | Run() Terminate() |
| JSS | 知识图谱 | KGImport() KGList() KGSubgraph() KGExpand() KGDelete() |
1.5 自动索引机制
三个类构造时都检查数据目录下的 IdxLog_<GPF|BCC|JSS>.txt:
- 有日志 → 已是索引目录,直接加载。
- 无日志 → 扫描源文件(GPF 表/FSA、BCC 语料、JSS
.json/.jsonl),在<path>Idx/下建索引、写日志,下次据时间戳避免重复索引。
2. GPF —— 语言结构分析
2.1 Parse —— 结构计算
Parse 是 GPF 最常用的方法,输入文本,返回 JSON 字符串,需 json.loads() 转 Python 对象。
import json
from LangSC import GPF
gpf = GPF()
Ret = gpf.Parse(text, Structure="分析类型")
分词(Segment)
Ret = gpf.Parse("今天天气真好", Structure="Segment")
# → '["今天", "天气", "真", "好"]' (实测)
words = json.loads(Ret)
词性标注(POS,默认)
Ret = gpf.Parse("今天天气真好", Structure="POS")
# → '["今天/t", "天气/n", "真/d", "好/a"]' (实测)
for tag in json.loads(Ret):
word, pos = tag.split("/")
常用词性标记:
| 标记 | 含义 | 标记 | 含义 | 标记 | 含义 |
|---|---|---|---|---|---|
| n | 名词 | v | 动词 | a | 形容词 |
| d | 副词 | r | 代词 | p | 介词 |
| u | 助词 | c | 连词 | m | 数词 |
| q | 量词 | t | 时间词 | f | 方位词 |
| ns | 地名 | nr | 人名 | nt | 机构名 |
| w | 标点 |
组块(Chunk)、句法树(Tree)、依存(Dep)—— 走远程网关
这三种调用 {parser_url}/v1/public/parser/{stree|chunk|dep},入参 {"text": text};网关返回 CommonResponse 的
data(拍平结构),由 GPF._adapt_{chunk,dep,tree} 转成渲染端可直接消费的序列/树/图形状(所以 AddStructure/ShowStructure/Show* 无需改动即可消费):
# 组块:适配为「序列」—— ["组块/词性", ...]
Ret = gpf.Parse("我们大家今天下午在操场集合", Structure="Chunk")
# 句法树:适配为「嵌套树」—— {label: [子节点...]}(叶子为字符串;同名兄弟用列表)
Ret = gpf.Parse("我们大家今天下午在操场集合", Structure="Tree")
# 依存:适配为「图/三元组」—— [["下标:词","下标:词","role"], ...]
# 节点用 "下标:词" 避免同形词在图中被合并
Ret = gpf.Parse("学生认真地读书", Structure="Dep")
⚠️ 网关是远程服务:返回"句法分析服务繁忙中"时,
Parse抛RuntimeError("句法分析网关返回异常: ..."); 网络失败抛RuntimeError("句法分析网关调用失败 (url): ...")。生产代码应捕获重试;离线环境 Tree/Chunk/Dep 不可用, 但Segment/POS永远本地可用。
推荐用法——加载到网格后用网格操作做结构化查询:
gpf.SetText("学生认真地读书")
Ret = gpf.Parse("学生认真地读书", Structure="Dep")
gpf.AddStructure(Ret) # 依存(图)加载到网格
for u in gpf.GetUnit("Rel=SBV"): # 查主谓关系
print(gpf.GetUnitKV(u, "Word"))
gpf.ShowStructure(Ret, "dependency.png") # 可视化
其他参数
gpf.Parse("这些都是我们爱的人", Structure="POS", Web=True) # 经云服务(默认本地)
gpf.Parse("在北京语言大学读书", Structure="Segment", Table="UserDict") # 指定用户词典表
输入超过
Max_Length(1024 字符)会warnings.warn并截断,仅前 1024 字参与分析。
Structure 参数汇总
| 参数值 | 功能 | 执行位置 | 返回(json.loads 后) |
|---|---|---|---|
"Segment" |
分词 | 本地 DLL | ["今天","天气","真","好"] |
"POS"(默认) |
词性标注 | 本地 DLL | ["今天/t","天气/n","真/d","好/a"] |
"Chunk" |
组块 | 远程网关 | 序列 ["组块/词性", ...] |
"Tree" |
短语结构树 | 远程网关 | 嵌套 {label:[子节点...]} |
"Dep" |
依存 | 远程网关 | 三元组图 [["下标:词","下标:词","role"], ...] |
2.2 结构可视化(Show)
统一经 GPF._render_dot()(pygraphviz)生成图片。
ShowStructure —— 传 JSON 字符串,自动识别类型
gpf = GPF()
# 序列(JSON 数组,元素为字符串或对象)
gpf.ShowStructure('["我们", "大家", "喜欢", "上课"]', "seq.png")
gpf.ShowStructure('["我们/r", "大家/n", "喜欢/v"]', "pos.png")
gpf.ShowStructure('[{"我们":{"POS":"r"}}, "大家", "喜欢/v"]', "rich_seq.png")
# 树(JSON 对象,值为数组表示子节点)
gpf.ShowStructure('{"S":[{"NP":[{"r":"我们"},{"n":"大家"}]},{"VP":{"v":"喜欢"}}]}', "tree.png")
# 图(JSON 数组,元素为三元组 [头,尾,关系])
gpf.ShowStructure('[["读","学生","SBV"],["读","书","VOB"],["读","认真","ADV"]]', "dep.png")
gpf.ShowStructure('{"学习":[["我","主语"],["在","mod"]]}', "graph.png") # 字典形式的图
# 词云(JSON 对象,值为数值表示频率)
gpf.ShowStructure('{"发展":140,"经济":70,"推进":66,"建设":63,"加强":53}', "cloud.png")
# 结构化 JSON(Parse 结果)直接可视化
gpf.ShowStructure(gpf.Parse("我们大家今天下午在操场集合", Structure="Tree"), "parse_tree.png")
ShowGrid —— 显示网格
gpf = GPF()
gpf.AddStructure(gpf.Parse("我们大家今天下午在操场集合", Structure="Tree"))
gpf.ShowGrid("grid.png") # 仅单元
gpf.ShowGrid("grid_rel.png", IsShowRel=True) # 单元 + 关系
网格图单元按类型着色:灰=字符(Char)、绿=词语(Word)、浅蓝=短语(Phrase)、金=组块(Chunk)。
实测:上述
ShowStructure四类(序列/树/图/词云)与ShowGrid均成功生成 PNG(例如seq.png7.9KB、tree.png22KB、graph.png12KB、cloud.png11KB、grid.png28KB)。无需系统 Graphviz;中文显示需宿主 CJK 字体。
细分渲染器与底层
gpf.ShowTree(json); gpf.ShowSeq(json); gpf.ShowGraph(json)
gpf.ShowUnit(u, "u.png"); gpf.ShowRelation("rel.png")
gpf.DrawTree(json, tag); gpf.DrawSeq(json); gpf.DrawGraph(json, tag) # 返回 DOT 片段
gpf.Dot2Img(dot, name); gpf.DotFile(dot_file, img); gpf.DotBuff(dot, img)
gpf.ShowCloud(json, "cloud.png", font_path=None) # 词云;font_path 覆盖 CJK 字体
2.3 网格操作(Grid)
设置文本
gpf = GPF()
gpf.SetText("孩子们都吃撑了")
gpf.GetText() # "孩子们都吃撑了"
gpf.GetText(0, 2) # 子串(位置 0→2)
添加单元
# 方式1:自动定位(推荐)——GPF 在文本中查词语位置
u1 = gpf.AddUnit("孩子们")
u3 = gpf.AddUnit("吃")
# 方式2:指定结束列号(colNo,从 0 开始的结束位置)
u1 = gpf.AddUnit("孩子们", 2)
u3 = gpf.AddUnit("吃", 4)
print(u1) # 返回单元号字符串,如 "(2,1)"
添加单元属性
gpf.AddUnitKV(u3, "POS", "v")
gpf.AddUnitKV(u1, "Role", "Agent")
添加关系
gpf.AddRelation(u3, u1, "sbj") # 吃 → 孩子们(主语)
gpf.AddRelationKV(u3, u1, "sbj", "Weight", "3") # 关系属性(值建议 ASCII,见下方提示)
⚠️ 已知问题:
AddRelationKV的中文值在当前原生库存在编码往返缺陷(如存入施事读回为乱码鏂戒簨); 单元属性AddUnitKV的中文值正常(词形、HeadWord等均正确)。关系属性暂用 ASCII 值,或把语义中文放到单元属性上。
查询网格(含实测输出)
gpf = GPF(); gpf.SetText("孩子们都吃撑了")
u1 = gpf.AddUnit("孩子们"); u2 = gpf.AddUnit("都"); u3 = gpf.AddUnit("吃"); u4 = gpf.AddUnit("撑了")
# 实测 → AddUnit 返回单元号:u1="(2,2)" u2="(3,1)" u3="(4,1)" u4="(6,2)"
gpf.AddUnitKV(u3, "POS", "v"); gpf.AddUnitKV(u1, "Role", "Agent")
gpf.AddRelation(u3, u1, "sbj"); gpf.AddRelation(u3, u4, "cmp")
gpf.GetUnitKV(u1, "Word") # 实测 → '孩子们' ("Word"/"HeadWord" → str)
gpf.GetUnit("POS=v") # 实测 → ['(4,1)']
gpf.IsUnit(u3, "POS=v") # 实测 → 1
gpf.GetRelation() # 实测 → [['(4,1)','(2,2)','sbj'], ['(4,1)','(6,2)','cmp']]
gpf.GetUnitKV(u3) # 省略 key → 全部属性 {Key:[Vals]}
# 实测(节选)→ {'Word':['吃'],'POS':['v'],'From':['4'],'To':['4'],
# 'Type':['Char','Word'],'USub-sbj':['(2,2)'],'USub-cmp':['(6,2)'], ...}
len(gpf.GetGrid()) # 实测 → 7(列数)
单元属性里系统会自动维护一批派生键:From/To(起止列)、HeadWord、Type(Char/Word/...)、
USub-<role>(某关系下的子单元)、RSub(关系角色集合)等——它们让"单元·关系·属性"可被结构化查询。
条件查询单元
gpf.GetUnit("POS=v") # 按属性查,返回单元号列表
gpf.GetUnit("Sem=*") # 通配:有语义属性的单元
gpf.GetUnit("Type=Word|Type=Phrase") # | 表示或
gpf.GetUnit("POS=n", UnitNo="(0,5)", UExpress="Sub") # 限定范围
gpf.IsUnit(u3, "POS=v") # 0/1
gpf.IsRelation(u3, u1, "sbj") # 0/1
从 Parse 结果构建网格
AddStructure 自动识别多种 JSON:GPF 结构 JSON(带 Type)/ 树 / 序列 / 图,统一加载到网格。
gpf = GPF()
gpf.AddStructure(gpf.Parse("我们大家今天下午在操场集合", Structure="Tree"))
gpf.ShowGrid("grid.png", IsShowRel=True)
网格级属性
gpf.AddGridKV("URoot", u3) # 标记根节点
gpf.AddGridKV("Source", "Manual")
2.4 数据表(Table)
数据表以 .tab 文本格式存储,索引后 API 访问。格式:
Table 表名
数据项1
Key1=Value1
Key2=[Value2a Value2b]
Coll=[Role1 Role2]
数据项2
...
查询与加载:
gpf = GPF("./data") # 目录下需有已索引的表
gpf.GetItem() # 所有表名
gpf.GetItem("Event_Tab") # 表内全部数据项
gpf.GetItem("Event_Tab", "Coll=Agent") # 条件过滤
gpf.GetItemKV("Event_Tab", "吃") # 数据项全部属性(dict)
gpf.GetItemKV("Event_Tab", "吃", "Coll") # 指定属性(list)
gpf.SetTable("City") # 设定当前表
gpf.CallTable("City") # 加载并设定表
gpf.GetSuffix("tab", sentence) # 后缀匹配
gpf.GetPrefix("tab", sentence) # 前缀匹配
GetItem/GetItemKV是GetTableItem/GetTableItemKV的别名,等价可用。
2.5 有限状态自动机(FSA)
FSA 是 GPF 的规则匹配引擎,在网格上做模式匹配。.fsa 文件格式:
FSA 规则名(参数)
上下文模式
{操作代码}
示例(数量关系识别):
FSA Time(Nearby=Yes, MaxLen=Yes)
POS=m POS=q ?的 Entry:[POS=n]
{
UF = self.GetUnit(0)
UT = self.GetUnit(-1)
self.AddRelation(UF, UT, "数量")
}
模式语法:KV 表达式 POS=v/Word=吃;? 可有可无;+ 可重复;[] 搭配表;() 保序;^ 离合;Entry:[KV] 匹配入口。
运行与结果:
gpf = GPF()
gpf.SetText("李明把守的大门被他破了")
gpf.AddStructure(gpf.Parse(gpf.GetText(), Structure="Dep"))
gpf.AddStructure(gpf.Parse(gpf.GetText(), Structure="Segment"))
gpf.CallTable("Sep_V") # 若规则依赖数据表
gpf.CallFSA("SepV1") # 运行规则
for u in gpf.GetUnit("Tag=SepWord"):
print(gpf.GetUnitKV(u, "Word"))
动作块内可用方法:self.GetNode(-1)/GetNode("$T") 取路径号;self.GetUnit(0)/GetUnit(-1) 取节点单元;以及全部网格操作(self.AddRelation/AddUnitKV/...)。
🔒 安全:
CallFSA/RunFSA会对引擎返回的操作串执行exec()。只加载可信来源的.fsa规则文件。
3. BCC —— 语料库检索(语言的组合性实例集)
3.1 构造、索引与编码契约
bcc = BCC("corpus") # 首次自动索引到 corpusIdx/
- 查询 / 结果 走 UTF-8(引擎内部
UTF8_2_GBK/GBK2UTF8)。 - 语料内容必须 GBK(
_utils.process_file在所有平台显式写 GBK)。 - 路径建议 ASCII:BCC 引擎自身
fopen对 CJK 临时路径会失败(即便 Windows),请保持语料/索引目录为 ASCII。
3.2 BCC 检索语言
完整格式:
[Lua:]查询体{条件}[范围]操作(参数)
| 部分 | 必填 | 默认 | 说明 |
|---|---|---|---|
Lua: |
否 | 无 | 加此前缀时生成脚本带 Lua 标记 |
| 查询体 | 是 | — | 检索核心 |
{条件} |
否 | 无条件 | 过滤 |
[范围] |
否 | 全语料 | 语料子集 |
操作(参数) |
否 | Context(10,0,100) |
输出形式 |
最简形式只需查询体,如 n喜欢。
(1)检索单元(6 种;词性用英文字母,词形用汉字):
| 类型 | 格式 | 示例 | 含义 |
|---|---|---|---|
| 词性+词形 | 词性汉字 |
n喜欢 |
词性 n 且含"喜欢" |
| 词形+词性 | 汉字词性 |
喜欢v |
含"喜欢"且词性 v |
| 纯词形 | 汉字 |
喜欢 |
含"喜欢"的任意词 |
| 纯词性 | 词性 |
n |
任意名词 |
| 词性+特征 | 词性[*汉字] |
q[*的] |
特征值含"的"的 q 词 |
| 词性+全特征 | 词性[*] |
q[*] |
q 词的所有特征 |
(2)连接符(写在两个检索单元之间):紧邻(相连/空格)、* 同句任意距离、^ 跨句。例:nv / n*v / n^v。
(3)修饰符:~n 句首 / n~ 句尾;.n 左定位 / n. 右定位;(~)n 层级深度 1,((~))n 深度 2。
(4)块内查询(同一词/短语内部):v[n喜欢] 共享边界 · v[*n喜欢] 共享右边界 · v[n喜欢*] 共享左边界 · v[*n喜欢*] 完全包含。
条件 {}:$1/$2 指代查询体第 1/2 个检索单元结果;{$1=$2}、{$1=[A,B]}(在集合内)、多条件 ; 分隔。
范围 []:[(0,713)] / [(0,713);(714,928)](并集)。
操作:Context(窗口,页,每页)(默认 10,0,100)· Freq(最大条数[,统计对象,上下文数])(默认 1000)· Count()。
复合查询:A AND B(在 B 结果内检索 A)、A NOT B(排除 B 后检索 A);前后须有空格,各部分可带自己的 {}/[]/操作。
bcc.Run("~JJ美丽{$1=[A,B]} AND 好{$1=$2}")
bcc.Run("n喜欢v{}Context() NOT 的{}")
3.3 Run 参数
bcc.Run(Query, **Others)
| 参数 | 默认 | 说明 |
|---|---|---|
Command/Output |
"Freq" |
"Freq" 词频 / "Context" 上下文 / "Count" 计数 |
Number |
100 | 结果数量 |
Target |
"$Q" |
Freq 统计目标 |
WinSize |
20 | Context 窗口 |
PageNo |
0 | Context 分页(从 0 起) |
Print |
"" |
"Lua" 输出生成的 Lua 检索脚本 |
Service |
"" |
远程检索服务 |
Python 参数与检索式中操作冲突时,Python 参数优先。例:
bcc.Run("n喜欢v{}Context()", Command="Freq", Number=50)最终按 Freq 输出。
3.4 结果统一信封(2.5.x 新)
Command ∈ {Context, Freq, Count} 的返回被规范化为统一信封(其余命令原样返回):
{
"type": "Context|Freq|Count",
"query": "<原始检索式>",
"total": <int>, // 命中总量
"distinct": <int>, // 仅 Freq:不同词数
"approximate": <bool>,
"records": [ ... ] // 扁平记录,JSS 可直接建表
}
records 元素:
- Freq:
{"id","word","freq","sources?":[{"doc","freq"}]} - Context(KWIC):
{"id","keyword","left","right","doc","source_id"} - Count:
{"id","freq"}
实测一 —— bcc.Run("a的n", Command="Freq", Number=10)(语料含"美丽的花/聪明的学生/..."):
{
"type": "Freq", "query": "a的n", "total": 7, "distinct": 5, "approximate": true,
"records": [
{"id": 1, "word": "美丽的花", "freq": 2},
{"id": 2, "word": "聪明的学生", "freq": 2},
{"id": 3, "word": "红的旗帜", "freq": 1},
{"id": 4, "word": "勇敢的战士", "freq": 1},
{"id": 5, "word": "伟大的祖国", "freq": 1}
]
}
实测二 —— bcc.Run("好", Command="Context", Number=5)(KWIC 上下文,| 为句/条边界):
{
"type": "Context", "query": "好", "total": 2, "approximate": false,
"records": [
{"id": 1, "keyword": "好", "left": "...她唱得非常", "right": "|天气真好啊|...",
"doc": "demo_text", "source_id": "9lVAC9i"}
]
}
实测三 —— bcc.Run("a的n", Command="Count") → {"type":"Count","query":"a的n","total":7,"approximate":true,"records":[{"id":1,"freq":7}]}。
3.5 检索示例
以下示例展示检索式写法;具体命中取决于你的语料内容。标注"✅ 实测"的在本手册配套的小语料上已真跑返回结果。
bcc.Run("a的n", Command="Freq", Number=10) # ✅ 实测:美丽的花/聪明的学生/红的旗帜/勇敢的战士/伟大的祖国
bcc.Run("好", Command="Context", Number=5) # ✅ 实测:返回 2 条 KWIC
bcc.Run("a的n", Command="Count") # ✅ 实测:total=7
bcc.Run("n*v", Command="Freq", Number=5) # ✅ 实测:同句名词…动词,total=2
bcc.Run("v", Command="Freq", Number=10) # ✅ 实测:唱/表扬/保卫/跑/热爱/盛开/喜欢…
bcc.Run("a的n", Command="Freq", Number=500) # 形容词+的+名词 高频搭配
bcc.Run("v得a", Command="Context", Number=50) # 动词+得+形容词 上下文
bcc.Run("把nv", Command="Freq") # 把字句
bcc.Run("u~", Command="Freq", Number=200) # 句尾助词
bcc.Run("~nv", Command="Context", Number=100) # 句首名词接动词
bcc.Run("n喜欢v{}[(0,713);(714,928)]Context(20,0,10)") # 限定语料范围
bcc.Run("a的n", Command="Count") # 仅计数
bcc.Run("a的n", Command="Context", Number=100, PageNo=1) # 翻页
bcc.Run("a的n", Command="Freq", Target="$1", Number=500) # 按目标统计
bcc.Run("a的n", Print="Lua") # 查看生成的 Lua 脚本
3.6 词表管理、管理命令与导出
bcc.AddBCCKV("颜色词", "红 黄 蓝 绿")
bcc.GetBCCKV("颜色词") # ✅ 实测 → {"type":"GetKV","total":1,"res":["红","黄","蓝","绿"]}(原始 JSON 字符串)
bcc.GetBCCKV() # 所有词表
bcc.GetBCCKVs()
bcc.Run("a的n{$1=[颜色词]}", Command="Freq") # 在条件中引用词表(见下方说明)
bcc.ClearBCCKV("颜色词") # 清一个
bcc.ClearBCCKV() # 清全部
关于
{条件}:{$1=$2}、{$1=[词表/集合]}是合法的 BCC 检索式语法(见 §3.2)。其命中与$1/$2指代的 具体跨度及语料强相关——在本手册的小语料上,a的n{$1=[颜色词]}实测返回 0 条。请勿假设条件过滤必然有结果, 以你的真实语料为准;词表的增删查(AddBCCKV/GetBCCKV/ClearBCCKV)本身已验证可用。
直接下发管理命令(不检索),通过 CallBCC:
| 命令 | 说明 |
|---|---|
AddTag(标签,值) / AddKV(键=值) |
添加标签/键值 |
GetTags() / GetKeys() |
所有标签名 |
GetTagVal(键) / GetValues(键) |
指定标签的值 |
ClearTag() / ClearKV() / ClearTag(标签) |
清标签 |
SetMax(数值) |
最大检索数 |
SpeedUp(数值) |
加速参数 |
AddLimit(起,止) / ClearLimit() |
语料范围限制 |
bcc.CallBCC("SetMax(100000)")
BCC.to_jsonl(bcc.Run("a的n"), "freq.jsonl") # 把信封 records 落为 JSONL
bcc.IndexBCC(filelistname, **Others) # 手动建索引
挖掘闭环:
BCC.Run(...).records→to_jsonl→JSS("...")建表检索,即"语料库(组合性)→知识库(聚合性)"。
4. JSS —— JSON 结构检索 + 知识图谱(语言的聚合性结果)
4.1 本地 SQL 检索
核心特性:多种索引(KV 精确 / BM25 全文 / Affix 模糊 / Number / Float / Date / 语义向量);SQL SELECT 接口;内置中文分词;跨平台;C++ 倒排索引 + 双数组 Trie。
from LangSC import JSS
jss = JSS("./data", log_level=1, log_filename="jss.log") # 自动索引并加载
rows = jss.Run('SELECT TOP 10 id, title FROM docs WHERE title LIKE "机器学习"')
- 返回:
Run返回引擎结果的results字段——行查询为记录字典列表;COUNT等汇总为字典(实测SELECT COUNT(*)→{"count": 8})。 - 失败不再静默(2.5.x):无结果返回
[];但无results(SQL 语法错/引擎报错)或未初始化 →raise RuntimeError带诊断;结果超 10MB 缓冲报截断。用完可jss.Terminate()(析构自动调用)。 - 大小写敏感:表名、字段名严格区分大小写,须与 cfg 一致。数据/配置用 UTF-8。
配置文件 cfg_*.txt
命名 cfg_<数据文件名>.txt(如 poets.jsonl → cfg_poets.txt);缺失则按首条记录自动推断生成。它相当于面向检索的"本体"。
{
"table_name": "docs",
"record_format": "jsonl", // "jsonl" 或 "json"
"content": { // 输出字段名 → 源 JSON 路径
"id": "id",
"name": "product.info.name", // . 嵌套(≤5 层)
"tags": "data[].tags" // [] 数组字段
},
"combin": { "all_text": ["title", "abstract"] },// 组合字段:跨字段检索
"index": {
"kv": ["id", "category"],
"number": ["weight"],
"float": ["price"],
"date": ["created"],
"bm25": ["title", "abstract"],
"affix": ["title"],
"sem": ["title"]
}
}
索引类型与运算符
| 类型 | 关键字 | 说明 | 适用 |
|---|---|---|---|
| KV | kv |
精确匹配 | = != IN BETWEEN |
| BM25 | bm25 |
全文(自动分词,TF-IDF) | LIKE '关键词'(无通配符) |
| Affix | affix |
子串/通配 | LIKE '%关键词%' |
| Number | number |
64 位整数 | = != > >= < <= BETWEEN IN |
| Float | float |
64 位浮点 | 同 Number |
| Date | date |
日期时间 | = BETWEEN |
| Semantic | sem |
语义向量 | LIKE '@查询' |
SQL 语法参考
SELECT id, title FROM docs WHERE title LIKE '关键词' -- 指定字段
SELECT * FROM docs WHERE id = 'doc001' -- 全字段 + 精确
SELECT TOP 10 id FROM docs WHERE title LIKE '搜索词' -- TOP
SELECT id FROM docs WHERE title LIKE '搜索词' LIMIT 20 -- LIMIT
SELECT * FROM docs WHERE category='技术' AND weight>50 -- AND/OR/NOT
SELECT * FROM docs WHERE title LIKE '关键词' ORDER BY weight DESC -- 排序
SELECT a.title,b.name FROM a JOIN b ON a.id=b.ref WHERE a.title LIKE 'AI' -- JOIN
SELECT COUNT(*) FROM docs -- 计数 → {"count": N}
SELECT RAND(10) FROM docs -- 随机 N 条
运算符:= !=/<> > >= < <= BETWEEN ... AND ... IN (...) LIKE。
LIKE 按前缀自动选索引:无通配符→BM25,%关键词%→Affix,@查询→语义。
完整示例一:文档搜索
数据 data/docs.jsonl:
{"id":"doc001","title":"Python编程入门指南","abstract":"介绍Python基础语法","category":"技术","weight":85}
{"id":"doc002","title":"机器学习算法详解","abstract":"讲解常用机器学习算法","category":"技术","weight":92}
{"id":"doc004","title":"人工智能发展历史","abstract":"从图灵测试到深度学习","category":"科学","weight":88}
配置 data/cfg_docs.txt:
{
"table_name": "docs", "record_format": "jsonl",
"content": {"id":"id","title":"title","abstract":"abstract","category":"category","weight":"weight"},
"index": {"kv":["id","category"], "number":["weight"], "bm25":["title","abstract"], "affix":["title"]}
}
查询(右侧为实测输出):
jss = JSS("./data")
jss.Run('SELECT id,title,weight FROM docs WHERE title LIKE "机器学习"')
# → [{"id":"doc002","title":"机器学习算法详解","weight":92}]
jss.Run('SELECT id,title FROM docs WHERE category = "科学"')
# → [{"id":"doc004","title":"人工智能发展历史"}]
jss.Run('SELECT id,title,weight FROM docs WHERE weight >= 85')
# → [{...doc001 85},{...doc004 88},{...doc002 92}]
jss.Run('SELECT id,title FROM docs WHERE category="技术" AND weight>80')
# → [{"id":"doc001",...},{"id":"doc002",...}]
jss.Run('SELECT id,title FROM docs WHERE title LIKE "%Python%"')
# → [{"id":"doc001","title":"Python编程入门指南"}]
jss.Run('SELECT COUNT(*) FROM docs') # → {"count": 5}
jss.Run('SELECT RAND(2) FROM docs') # → 随机 2 条
完整示例二:嵌套 JSON(路径映射)
{"product":{"id":"P001","info":{"name":"笔记本电脑","price":5999.0,"brand":"联想"}},"meta":{"created":"2025-03-15"}}
{
"table_name":"products","record_format":"jsonl",
"content":{"id":"product.id","name":"product.info.name","price":"product.info.price","brand":"product.info.brand","created":"meta.created"},
"index":{"kv":["id","brand"],"float":["price"],"date":["created"],"bm25":["name"],"affix":["name"]}
}
jss = JSS("./data")
jss.Run('SELECT id,name,price FROM products WHERE brand = "罗技"')
# → [{"id":"P002","name":"无线鼠标","price":129.9},{"id":"P003","name":"机械键盘","price":399.0}]
jss.Run('SELECT id,name,price FROM products WHERE price BETWEEN 100.0 AND 1000.0')
# → [{"id":"P002",...129.9},{"id":"P003",...399.0}] (笔记本 5999 被排除)
jss.Run('SELECT id,name FROM products WHERE created BETWEEN "2025-03-01" AND "2025-12-31"')
# → [{"id":"P001",...},{"id":"P002",...},{"id":"P003",...}]
以上嵌套路径映射(
product.info.name等)、float/date索引与BETWEEN均为实测通过。
完整示例三:多表 JOIN
目录下多文件自动各建一表,支持跨表:
jss = JSS("./data") # articles.jsonl + authors.jsonl
jss.Run('''SELECT articles.title, authors.name
FROM articles JOIN authors ON articles.author_id = authors.id
WHERE articles.title LIKE "人工智能"''')
注意事项
- 表名/字段名大小写敏感,须与 cfg 一致。2. 数据/配置用 UTF-8。3.
Run内部 10MB 缓冲,单次结果勿超限。 - 索引后表只读,时间戳避免重复索引。5. 同字段可建多种索引,按运算符自动选。6. 全文依赖分词词典
base.lex(包内已带)。7. cfg 缺失自动生成。
4.2 知识图谱 KG*(2.5.x 新)
KG* 走 HTTP(requests),后端 Neo4j,不依赖本地 DLL、不需要已加载的本地表;服务不可用返回 HTTP 503 → RuntimeError。
节点 {id,label,type,graph_id,props?},边 {id,source,target,type,label,graph_id,props?}。
jss = JSS("./kb", kg_url="http://127.0.0.1:8100") # 或默认公网 https://cit.blcu.edu.cn/jss
r = jss.KGImport("mygraph.zip") # 上传 jss-kg/v1 包(.zip / 目录 / zip 字节)
r = jss.KGImportPath("server/rel/path") # 导入服务器 KG_IMPORT_ROOT 下已有包
graphs = jss.KGList() # 列出图谱
sub = jss.KGSubgraph(gid, q="破门", hops=2, limit=200) # 种子邻域子图
exp = jss.KGExpand(gid, node_id, limit=50) # 单跳扩展(按 node id)
jss.KGDelete(gid) # 删除图谱
| 方法 | 端点 | 说明 |
|---|---|---|
KGImport(package, allow_reserved=False) |
POST /kg/graphs/import |
上传 zip/目录/字节;返回 {graph_id,name,nodes,edges,warnings,replaced} |
KGImportPath(path, allow_reserved=False) |
POST /kg/graphs/import_path |
服务器端已有包 |
KGList() |
GET /kg/graphs |
[{graph_id,name,node_count,edge_count,...}](可能空) |
KGSubgraph(graph_id, q, hops=2, limit=200) |
POST /kg/subgraph |
种子先按 id 再按 label;hops∈{1,2,3},limit≤2000;返回 {seed,nodes,edges} |
KGExpand(graph_id, node_id, limit=50) |
POST /kg/expand |
仅按 node id;limit≤500 |
KGDelete(graph_id) |
DELETE /kg/graphs/{id} |
返回 {"deleted": gid} |
5. 智能体 agentkit(2.5.x 新)
位于 LangSC/Demo/labs/agent/,把"结构化思维"做成可运行的智能体框架——结构即状态(状态 = 单元·关系·属性),
零依赖最小核即可离线运行,也可一键跑在 LangGraph 上。
from labs.agent import (new_state, Agent, AgentRelation,
run_loop, run_pipeline, run_supervised, tools, llm)
5.1 状态与声明
state = new_state(goal, question="", constraints=None, memory=None)
Agent(name, role="", tools=[], temperature=0.3) # 单元=Agent;属性=role/tools
AgentRelation(source, target, relation_type="sequential") # 关系(边)
LOOP_ORDER # ["perceive","plan","decide","execute","reflect"]
RELATION_TYPES # ("sequential","parallel","hierarchical","conditional")
5.2 三种执行器
run_loop(state, stages, max_iters=5) # 单体回路:感知→规划→决策→执行→反思;reflect 置 state['done']
run_pipeline(state, agents) # 多体顺序:共享状态按边流转;agents=[(name, fn), ...]
run_supervised(state, router, specialists, finisher=None, max_steps=8) # supervisor 条件路由
5.3 工具层与决策中枢
tools.perceive_structure(gpf, text, structure="POS") # 感知:调 GPF
tools.search_corpus(bcc, query, command="Freq", number=50)# 检索:调 BCC
tools.query_kb(jss, sql) # 查知识库:调 JSS
llm.available() # 是否配置了 LLM
llm.call_llm(prompt, fallback=None, timeout=60) # 决策;未配置时模板降级
5.4 LangGraph 适配(可选)
from labs.agent.langgraph_adapter import (
to_langgraph, pipeline_to_langgraph, supervisor_to_langgraph, GraphState)
app = to_langgraph(stages, max_iters=5) # 单体
app = pipeline_to_langgraph(agents) # 线性多体
app = supervisor_to_langgraph(classify, specialists, reporter)# 条件路由
5.5 最小可运行示例(实测)
from labs.agent import new_state, run_loop, run_pipeline, run_supervised
# ① 单体回路:感知→决策→反思,reflect 达标即收敛
def perceive(s): s["seen"] = s.get("question", ""); return s
def decide(s): s["n"] = s.get("n", 0) + 1; return s
def reflect(s):
if s["n"] >= 3: s["done"] = True; s["answer"] = "数到了%d" % s["n"]
return s
st = run_loop(new_state("数到3", question="go"),
{"perceive": perceive, "decide": decide, "reflect": reflect}, max_iters=5)
# ✅ 实测 → {'iters': 3, 'answer': '数到了3', 'done': True}
# ② 多体顺序:共享状态按边流转,trace 记录经过的 Agent
st2 = run_pipeline(new_state("流水线"),
[("分析Agent", lambda s: s), ("检索Agent", lambda s: s)])
# ✅ 实测 → st2['trace'] == ['分析Agent', '检索Agent']
# ③ supervisor 条件路由:router 决定下一个专家,finisher 收尾
def router(s): return "知识Agent" if "知识Agent" not in s.get("visited", []) else "done"
st3 = run_supervised(new_state("路由"), router,
{"知识Agent": lambda s: s}, finisher=lambda s: s)
# ✅ 实测 → st3['trace'] == ['supervisor→知识Agent', '知识Agent', 'supervisor→done', '报告Agent']
配合工具层即成真·智能体:
tools.perceive_structure(gpf, text)感知结构、tools.search_corpus(bcc, q)查语料、tools.query_kb(jss, sql)查知识库,llm.call_llm(prompt)做决策(未配置 LLM 时模板降级,仍可离线判分)。
6. 跨平台、编码与并发(工程约定)
- 路径编码:所有进入原生 C API 的路径经
_utils.native_path(POSIX→os.fsencodeUTF-8;Windows→当前 ANSI 代码页,越界字符回退 8.3 短名)。JSS 直接走;GPF/BCC 经_enc_path。- 优先 ASCII 数据路径。JSS 全平台支持 CJK 路径,GPF 预期支持,BCC 必须 ASCII。超出 Windows ANSI 的字符(emoji/西里尔)需卷启用 8.3 短名,否则抛清晰错误。
- BCC 语料内容必须 GBK;查询入/结果出为 UTF-8。
- CJK 渲染需宿主 CJK 字体(见 §1.2)。
- 进程级单模型:
IsCRFInit/IsPOSInit/IsGPFInit/IsBCCInit每进程一套模型;一个进程内多个 GPF 实例不能各载不同模型——用多进程。 - 线程安全(2.5.x):每实例
threading.RLock串行化共享 RetBuff/句柄的数据面方法;Segment/POS走线程本地_seg_ctx真并行;进程级 init 由模块锁保护。- 边界:锁只保单次调用的内存安全,不保跨多次调用的逻辑原子性(如
SetGridText→GetGrid之间被别的线程插入)——需原子序列请用独立实例或外部锁;多进程对同一索引目录会文件碰撞,用不同输出目录。
- 边界:锁只保单次调用的内存安全,不保跨多次调用的逻辑原子性(如
- 错误诊断:原生库加载失败经
format_native_load_error给出平台化提示;缓冲截断由_check_trunc报错(可增大缓冲重试)。 - 原生库架构:macOS 为 universal(x86_64+arm64);Linux
.so为单架构 x86_64,ARM Linux 需另编,否则cdll.LoadLibrary抛诊断错误。 - 离线验证范围:当前跨平台改动在 Windows 实测 + 源码分析;Linux/macOS 的
.so/.dylib需在对应平台重建并测试。
7. 综合示例
用到
Structure="Tree"的示例(7.1、7.4)需联网句法网关;离线时可改用ShowStructure直接传本地 JSON(见 7.2)。 本地引擎部分(分词/词性/网格/可视化、BCC、JSS、挖掘闭环)均已实测可运行。
7.1 分析并可视化(Tree 需联网)
from LangSC import GPF
gpf = GPF()
Ret = gpf.Parse("今天我们上语言结构通论课程", Structure="Tree")
gpf.ShowStructure(Ret, "tree_result.png")
7.2 手动构建结构并可视化
gpf = GPF()
gpf.ShowStructure('{"S":[{"NP":[{"r":"我们"},{"n":"大家"}]},{"VP":{"v":"喜欢"}}]}', "manual_tree.png")
gpf.SetText("我们大家喜欢")
u1, u2, u3 = gpf.AddUnit("我们"), gpf.AddUnit("大家"), gpf.AddUnit("喜欢")
gpf.AddUnitKV(u1,"POS","r"); gpf.AddUnitKV(u2,"POS","n"); gpf.AddUnitKV(u3,"POS","v")
gpf.AddRelation(u3,u1,"SBV"); gpf.AddRelation(u3,u2,"SBV")
gpf.ShowGrid("manual_grid.png", IsShowRel=True)
7.3 语料库搭配检索
from LangSC import BCC
bcc = BCC("corpus")
bcc.Run("a的n", Command="Freq", Number=500)
bcc.AddBCCKV("颜色词", "红 黄 蓝 绿 白 黑")
bcc.Run("a的花{$1=[颜色词]}", Command="Freq")
7.4 Parse + Grid + Show 完整流程(Tree 需联网)
gpf = GPF()
gpf.AddStructure(gpf.Parse("我们大家今天下午在邵逸夫操场集合", Structure="Tree"))
for Col in gpf.GetGrid():
for U in Col:
print(U, gpf.GetUnitKV(U,"Word"), gpf.GetUnitKV(U))
for r in gpf.GetRelation():
print(gpf.GetUnitKV(r[0],"Word"), "→", gpf.GetUnitKV(r[1],"Word"), r[2])
gpf.ShowGrid("full_grid.png", IsShowRel=True)
7.5 GPF + BCC + JSS + 智能体(挖掘闭环)
from LangSC import GPF, BCC, JSS
gpf, bcc, jss = GPF(), BCC("corpus"), JSS("./kb")
text = "深度学习在自然语言处理中的应用"
pos = gpf.Parse(text, Structure="POS") # 感知:结构
freq = bcc.Run("深度学习", Command="Freq") # 组合性:语料
BCC.to_jsonl(freq, "mined.jsonl") # 语料 → 知识库(挖掘闭环)
# docs = jss.Run('SELECT title FROM papers WHERE title LIKE "深度学习"') # 聚合性:知识库
gpf.SetText(text); gpf.AddStructure(pos); gpf.ShowGrid("result.png")
8. 实训映射(测试即判分)
LangSC/Demo/labs/ 下 10 个"测试即判分"实验,每个含 solution.py/student.py/test_*.py/README.md;
LANGSC_LAB_IMPL=student 切换被测实现。对应"结构化思维"六环节:
| 部分 | 环节 | 实验 | 能力 |
|---|---|---|---|
| 一、语言的结构 | 数据(JSON) | lab1_json |
JSON 表示 |
| 形式化(grid) | lab2_grid |
网格:集合/序列/树/图 | |
| 要素 | lab3_unit_rel_attr |
单元·关系·属性 | |
| 计算(Parse) | lab4_parse |
分词/词性/句法树/依存 | |
| 二、语言的数据 | 语料库(组合性) | lab5_corpus |
BCC |
| 知识库(聚合性) | lab6_kb |
JSS | |
| 三、从数据到智能 | 挖掘闭环 | lab7_mining |
语料→知识库 |
| 应用 | lab8_application |
综合 | |
| 单智能体 | lab9_agent |
agentkit run_loop |
|
| 多智能体 | lab10_multiagent |
run_pipeline + supervisor |
pip install LangSC pytest
cd LangSC/Demo
pytest labs -v # 参考解(验证环境)
LANGSC_LAB_IMPL=student pytest labs -v # 判分学生实现
配套《LangSC 实训手册》(Demo/labs/实训手册.md / .docx)自成体系。
9. 常见问题
- Q1
import LangSC报错 / 库加载失败? 确认已pip install LangSC,包目录下有对应平台库(gpflib.dll/libgpflib.so/libgpflib.dylib等)。错误信息已由format_native_load_error给出平台化提示(含 ARM 架构不匹配)。 - Q2
Parse返回怎么用? 返回 JSON 字符串,json.loads()转 Python 对象。 - Q3 BCC 没结果? 确认语料为 GBK、路径为 ASCII、已索引;先用
bcc.Run("的")验证。 - Q4 可视化图片没生成? 2.5.x 无需系统 Graphviz(pygraphviz 自带);检查输出路径可写、宿主有 CJK 字体(中文变方块即缺字体);词云需
wordcloud与中文字体。 - Q5
AddUnit的位置参数?colNo是单元结束位置的列号(从 0 起),省略则自动定位(推荐)。 - Q6 单元编号格式? 字符串
"(列号,行号)",如"(2,1)";直接用AddUnit的返回值即可。 - Q7 BCC 检索式各部分?
查询体{条件}[范围]操作(参数):{}条件、[]范围、操作名后圆括号。 - Q8
Parse(Structure="Tree/Chunk/Dep")报"网关繁忙/调用失败"? 这是远程服务状态,非本地 bug;捕获RuntimeError重试或稍后再试;离线改用本地Segment/POS。 - Q9 JSS SQL 没结果或报
RuntimeError? 确认表名/字段名大小写与 cfg 一致、数据 UTF-8;开日志JSS("./data", log_level=1, log_filename="jss.log")排查。SQL 语法错会直接抛异常(非静默)。 - Q10 多线程/多进程? 见 §6:同实例并发已加锁;
Segment/POS可并行;不同进程用不同索引目录。
10. 探索与思考
观察工具的边界:用 LangSC 分析 5 个你自己写的句子(含长句、口语、网络用语),看分词与词性标注哪里准、哪里错,推测原因。
import json from LangSC import GPF gpf = GPF() for sent in ["句子1","句子2","句子3","句子4","句子5"]: print(sent, json.loads(gpf.Parse(sent, Structure="POS")))工具与人的分工:LangSC 能自动分词/标注/检索,但不"理解"语言。哪些环节必须由人完成?人与工具各擅长什么?
设计分析流程:研究"把"字句结构,你会如何组合
Parse、BCC 检索、网格操作?写出思路。BCC 检索语言实践:
a的n(形+的+名)、u~(句尾助词)、n*v(同句名词动词)、vn{}Context() NOT 的{}(排除"的"的动宾)。
11. API 全量速查
GPF(from LangSC import GPF)
| 簇 | 方法 |
|---|---|
| 分析 | Parse(text, Structure=, Web=, Table=) · Segment(text, table="") · POS(text, table="") · CallService |
| 网格文本 | SetText/SetGridText · GetText/GetGridText · GetGrid · GetStructure · AddGrid/AddGridJS/AddStructure/AddSeq/AddTree/AddGraph/Add2Grid |
| 单元 | AddUnit · AddUnitKV · GetUnit(s) · GetWord · GetUnitKV(s) · IsUnit · GetFSAUnit |
| 关系 | AddRelation · AddRelationKV · GetRelation(s) · GetRelationKV(s) · IsRelation |
| 属性 | AddGridKV/AddTextKV · GetGridKV(s)/GetTextKV |
| 表 | SetTable · CallTable · GetTable · GetItem/GetTableItem(s) · GetItemKV/GetTableItemKV(s) · IsTable · GetSuffix/GetPrefix · IndexTable |
| FSA | RunFSA · CallFSA · IndexFSA · GetFSAParam/GetParam · GetFSANode/GetNode |
| 可视化 | Show/ShowStructure/ShowGrid/ShowUnit/ShowRelation/ShowTree/ShowSeq/ShowGraph/ShowCloud · Draw* · Dot2Img/DotFile/DotBuff |
| 工具 | Reduce · Write2File/WriteColl2File · GetLog · GPFInit · GPFPersons |
BCC(from LangSC import BCC)
BCC(dataPath) · Run(Query, Command=, Number=, Target=, WinSize=, PageNo=, Print=, Service=) · CallBCC(query) ·
AddBCCKV/GetBCCKV(s)/ClearBCCKV · IndexBCC · to_jsonl(静态)
JSS(from LangSC import JSS)
JSS(dataPath, log_level=, log_filename=, kg_url=, kg_timeout=) · Run(sql, table="") · Terminate() ·
KGImport/KGImportPath/KGList/KGSubgraph/KGExpand/KGDelete
agentkit(from labs.agent import ...)
new_state · Agent/AgentRelation · run_loop/run_pipeline/run_supervised · LOOP_ORDER/RELATION_TYPES ·
tools.perceive_structure/search_corpus/query_kb · llm.available/call_llm ·
langgraph_adapter.to_langgraph/pipeline_to_langgraph/supervisor_to_langgraph
本手册随源码维护;若与源码行为不符,以源码与本手册的"最新发展"章节为准。《附录A》保持不变,其内容已在此全面升级并覆盖。