重拾 Lua:从月亮语言到 FreeSWITCH 里的胶水

Posted on 一 14 9月 2026 in Tech • Tagged with tech, lua, freeswitch, scripting, mod_lua, dialplan

十几年前我做过一个《A Glance of Lua》的分享,如今大半忘光了。这篇先用老程序员重拾旧语言的角度,把 Lua 最该记住的那几样东西——表即一切、元表、闭包、协程、C API——快速过一遍;再落到 FreeSWITCH:mod_lua 到底把脚本挂在哪几个位置(dialplan、XML handler、event hook、startup script),配一组能看懂的例子、几条最佳实践和最容易栽的坑。Lua 语法基于 5.x,FreeSWITCH 部分引用官方 scripting 文档。


Continue reading

拨号计划 101:FreeSWITCH 里那台可编程状态机

Posted on 一 14 9月 2026 in Tech • Tagged with freeswitch, dialplan, VoIP, Contact Center, routing

很多人把 FreeSWITCH 的拨号计划当成一个"路由配置文件",改完 reloadxml 就完事。可它其实是一台按呼叫上下文运行的状态机:一通电话进来,它一条条判断条件、往 channel 上贴变量、排一串要执行的动作,最后决定这通电话走哪条路。理解了这一点,IVR、排队、转接、录音这些呼叫中心功能才不再是黑盒。本文以 XML 拨号计划为主,配少量 Lua,讲清它是什么、能干什么、怎么写、有哪些最佳实践和常见坑,最后用几个真实呼叫中心场景演示排障技巧。


Continue reading

OpenSIPS 入门:一台 SIP 服务器,一个可编程的呼叫路由引擎

Posted on 一 14 9月 2026 in Tech • Tagged with tech, sip, opensips, voip, rtc, telephony

FreeSWITCH 那几篇讲的是"怎么接通一路电话",这篇换个角度:当你有成千上万路电话、要做注册、鉴权、路由、限流、防欺诈时,前面挡在最前线的往往是 OpenSIPS。它是什么、怎么编译、一次注册和一次呼叫在脚本里到底怎么流转、代码结构长什么样、有哪些best practice、又有哪些新手必踩的坑——一次讲清。


Continue reading

webrtc-to-freeswitch:一个浏览器软电话的架构、流程与协议全解

Posted on 一 14 9月 2026 in Tech • Tagged with tech, webrtc, sip, freeswitch, vue, fastapi

上一篇讲清了 SIP.js 怎么打进 FreeSWITCH,这次把它做成了一个完整项目——webrtc-to-freeswitch。这篇从整体架构、信令与媒体的完整流程、协议分层三个层面把它讲透:它是什么、有什么用、怎么用;浏览器到 FreeSWITCH 之间一次通话到底发生了什么;以及最容易被忽略、却最容易踩坑的 FreeSWITCH 侧配置——WSS binding、candidate ACL、ext-rtp-ip。


Continue reading

焦虑与沉没成本:写给夜里睡不着的自己

Posted on 日 13 9月 2026 in Journal • Tagged with journal, mindset, sunk-cost

一篇写给自己的私人札记,已加密。


Continue reading

用 SIP.js 从浏览器打电话到 FreeSWITCH

Posted on 五 11 9月 2026 in Tech • Tagged with tech, webrtc, sip, freeswitch, javascript

SIP.js 官方 demo 一键就能打通电话,但那是因为对端是一台匿名公共服务器。想让浏览器真正打进自己的 FreeSWITCH,绕不开三件 demo 帮你藏起来的事:注册、鉴权、还有一座 WSS 到 SIP 的桥。这篇拆掉 demo-1,把这三件事补齐。


Continue reading

给 FreeSWITCH 写测试:从单元测试到集成测试,用一个真 bug 串起来

Posted on 四 10 9月 2026 in Tech • Tagged with tech, freeswitch, testing, unit-test, integration-test, c, pcre2, sipp

给 FreeSWITCH 写测试有两条路:一条是自带的 FST 框架,起一个真 core、真 session,在进程内测 switch_* 函数;另一条是拉起整个服务、用 SIPp 打真呼叫、看 ESL 事件的集成测试。本文用我修的一个 mod_dialplan_xml use-after-free bug(PR #3151)串起前者,再讲清后者什么时候非用不可、怎么搭、坑在哪,最后给一张"这个 bug 该写哪种测试"的决策表和检查清单。


Continue reading

C 插件系统实战指南:dlopen 没告诉你的四件事

Posted on 一 07 9月 2026 in Tech • Tagged with tech, C, dlopen, plugin, so, abi, dynamic-linking, best-practice

dlopen 只有四个函数,半小时能学完。难的是它没管的四件事——入口点怎么找、插件怎么回调宿主、ABI 怎么不崩、卸载怎么办。这篇把这四个问题的传统答案讲清楚,给一份可编译运行的完整参考实现(357 行),再用 10 个实测的崩溃现场说明常见错误。含 Linux/macOS 差异对照和一份可勾选的 checklist。


Continue reading

C 语言的动态加载、依赖注入与服务注册:把 FreeSWITCH 的模块机制拆到底

Posted on 一 07 9月 2026 in Tech • Tagged with tech, C, freeswitch, dlopen, plugin, dependency-injection, service-registry, abi

C 没有反射,凭什么能用字符串 "answer" 找到一个函数?把 FreeSWITCH 的模块系统从 dlopen 拆到函数指针派发,四层结构讲透:动态加载、依赖注入、服务注册、运行时查找。所有结论都在 FreeSWITCH 1.11.3-dev 上实测过,包括亲手写一个 50 行模块热加载进跑着的进程,以及三个实测出来的坑。


Continue reading

LLM API 的变迁:OpenAI-compatible 为什么不等于兼容

Posted on 一 07 9月 2026 in Tech • Tagged with tech, LLM, API, OpenAI, Anthropic, Gemini, Responses API, Chat Completions, tool-calling

LLM API 已经从 prompt 字符串、messages 对话,走到由 typed items、事件流和工具循环组成的 Agent 接口。OpenAI-compatible 往往只能保证最简单的文本请求长得相似,不能保证工具调用、流式事件、状态、推理内容和错误语义一致。本文比较 Chat Completions、Responses API、Anthropic Messages 与 Gemini,给出选型框架、适配层边界和兼容性测试清单。


Continue reading

APR 入门:一个 30 年前的答案,为什么还在你的代码库里

Posted on 日 06 9月 2026 in Tech • Tagged with tech, C, APR, apache, freeswitch, memory-pool, portability

APR(Apache Portable Runtime)是 C 语言事实上的"缺失标准库",它的核心是内存池——不追踪每个对象的释放,而是按生命周期批量丢弃。这篇讲清 APR 的设计理念、常用模块、快速上手路径、以及 FreeSWITCH 为什么要把它 fork 出来改名。所有代码在 APR 1.7.6 上实测。


Continue reading

人格的力量:知识不再稀缺之后,靠什么立得住

Posted on 六 05 9月 2026 in Journal • Tagged with journal, 人格, 尽责性, 情绪稳定性, 知行合一, 王阳明, 大五人格, AI, 职业成长

"知识就是力量"这句话,前半截在 AI 时代快要失效了——知道一件事的成本已经降到接近零,可把知道变成做对的成本一分没降。王阳明讲知行合一,说的正是这一段落差:知不只是 What,还有 Why 和 How,而这两样只能在事上练出来。Gignac 2025 年那篇论文更给了一个意外的好消息:智商、尽责性、情绪稳定性这三样里,后两样彼此高度相关,却几乎跟智商无关——也就是说,最值钱的那块地基,跟你天赋多高没什么关系,是可以修的。


Continue reading

C++ 悬垂引用与 lambda 捕获:语法上最省事,出事时最难查

Posted on 六 05 9月 2026 in Tech • Tagged with tech, C++, memory, reference, lambda, dangling, sanitizer, modern-cpp

引用和 lambda 捕获是 C++ 里最省事的两个语法,也是最容易悄悄出事的两个。悬垂引用在使用处和普通变量一模一样,还没有"空"这个状态可判;[=] 看着像全按值拷,其实按指针捕了 this。本文用九个能编译运行的实例,讲清悬垂引用的四种来源、lambda 捕获的五种误用、什么时候该用引用什么时候不该用,附一张捕获速查表和检查清单。


Continue reading

C/C++ 内存管理方法的变迁:把纪律写进类型系统

Posted on 五 04 9月 2026 in Tech • Tagged with tech, C, C++, memory, RAII, smart-pointer, modern-cpp

从 malloc/free 到 unique_ptr,再到 span 与 pmr,C/C++ 三十年的内存管理演进有一条清晰的主线:把原来只能靠人记住的纪律,一点点搬进类型系统,让编译器去查。本文按 C、C++98、C++11、C++17/20 四个阶段讲清各自的特点与难点,配可编译运行的实例、最佳实践、常见陷阱和一张检查清单。


Continue reading

一个网关一把钥匙,三个客户端三种格式:用 cc-switch 收拢 AI 编码配置

Posted on 四 03 9月 2026 in Tech • Tagged with journal, AI, LLM, tooling, claude-code, codex, opencode, self-host

我手上就一个自建网关、一把 API key,可 Claude Code 要写进 settings.json 的 env,Codex 要写进 config.toml 加 auth.json,OpenCode 要在 opencode.json 里手搓一个 provider——同一件事写三遍,三种格式。cc-switch 把这三份配置收进一个 SQLite 当唯一数据源,托盘点一下就切。这篇讲清它是什么、为什么自建用户尤其需要它、两种接法怎么选,附上我本机三条真实链路(脱敏)和四个只有自建才会踩的坑:opencode.jsonc 会盖掉 cc-switch 的写入、网关的 /models 不是 OpenAI 形状所以自动拉模型没用、密钥两周过期后要改的地方变多了、以及 settings.json 里那个 PROXY_MANAGED 占位符是干什么的。最后是一页 cheatsheet。


Continue reading

AI 时代怎么读代码:把 AI 当导游,别当替身

Posted on 三 02 9月 2026 in AI • Tagged with journal, AI, code-reading, OpenSpec, Zed, Codex, workflow

接手陌生代码库,我用了很多年的仪式是画 mindmap、写 wiki——慢,但画完脑子里是有一张图的。现在最直接的提效办法看着是把仓库丢给 AI 要一份摘要,但"读过一份好摘要"和"脑子里有那张图"是两件事。这篇写我定下来的分工:AI 只负责找路,代码还是我自己读。附五个固定使用的 code reading prompt、四种防止被 AI 带偏的验证手段、怎么用 graphify 存结构和 PKB 存判断把地图沉淀下来(省得每个会话都从零 grep),以及怎么把唯一能自动化的那条验证做成 skill 的硬门槛。最后是读懂之后接 OpenSpec 的档位选择——"写代码这一步反而要降档"是最反直觉的一条。


Continue reading

别让 agent 再 grep 了:用 graphify 给代码库先画一张图

Posted on 三 02 9月 2026 in Tech • Tagged with journal, AI, knowledge-graph, tooling, code-intelligence, tree-sitter, agent

AI 编程助手最费钱也最不靠谱的动作,是拿着一个模糊的问题在你的仓库里反复 grep。graphify 换了个思路:先用 tree-sitter 把代码解析成一张知识图谱,之后所有问题都查图,不再翻文件。这篇我在本机真装真跑了 httpx 和 FastAPI 两个仓库——12.8 秒建图、零 token、39 倍压缩是真的,中文查询查不到、一次 update 把图从 8355 撑到 25685 个节点也是真的。另外扒了它为什么用 NetworkX 而不是 Neo4j(代价是 6.5% 的边被合并掉)、graphify-out/ 那 13 个产物里只有 5 个该进 git、怎么接自己的 LLM 网关不用 Gemini key,以及和 Aider、Serena、Potpie、GraphRAG、SCIP、Repomix 五条路线的横向对比。附可直接抄的 .gitignore.graphifyignore


Continue reading

用 SDD 写代码之后,我每天读的 Markdown 比代码多——于是写了 markpad

Posted on 二 01 9月 2026 in Tech • Tagged with journal, markdown, LLM, CLI, tooling, python, fastapi, SDD

自从用 OpenSpec 那套 spec-driven 流程做 AI 编程,proposal.md、design.md、tasks.md、spec.md 一层套一层,我一天读的 Markdown 比代码多。写这一端有 agent 帮忙,读这一端还是 cat 加 less。所以我给 markpad 又加了几刀:在任意目录敲一个命令,起一个本地 Web,左边编辑右边预览,Mermaid 和 PlantUML 直接出图,选中一段就能流式翻译,一键出摘要加思维导图。这是六月那篇介绍的续集,不讲功能清单,讲几个当时没写清的实现决定:为什么两种图表走两条完全不同的路、为什么翻译非流式不行、本地工具的安全线画在哪,以及我拿它打开自己上一篇博客时踩到的一个洞。1657 行 Python,53 个测试,可抄。


Continue reading

我写过 git cheatsheet,还是记不住——于是写了 gitman

Posted on 二 01 9月 2026 in Tech • Tagged with journal, git, LLM, CLI, tooling, python, safety

我在自己的 wiki 上写过一篇 git tips,改了 17 版,该记不住的还是记不住。于是写了 gitman:用自然语言说想干什么,它先给出一份 git 命令计划和一条从真实 diff 里长出来的 commit message,你点头它才执行。这篇不讲“AI 真神奇”,讲的是让 LLM 碰你的仓库时必须先立起来的几道护栏——argv 白名单、三级危险分类、commit message 只能来自 snapshot、默认不联网。全部代码 942 行,5 个 commit,可抄。


Continue reading

AI 时代知识到底怎么存、怎么找:一个后端工程师的知识库工作流

Posted on 一 31 8月 2026 in AI • Tagged with journal, AI, RAG, knowledge-base, knowledge-graph, embedding, pgvector, workflow

我这个博客仓库有 611 篇 Markdown、791 个文档源文件,可我问 AI “我以前是怎么讲鉴权的”,它照样答不上来。存了等于没存。这篇给一套后端工程师能长期跑下去的方案:先按“AI 知道 / AI 不知道”把知识分层,再用“源文件是唯一事实源、索引全部可重建”的四层结构去存,组织上 Tree 做骨架 Graph 做补充,检索上从目录到混合检索到图检索三级递进。附可抄的目录结构、frontmatter 规范、reindex 脚本骨架、工具三档选型,和一份精选论文清单。


Continue reading