亚信科技员工:公司确定参与Kimi Token 利润分成,我相信5G专网将在AI的推动下进入一轮爆发期,很期待(附Agent面试题)
如题,看到这样一则关于亚信的信息,还是蛮期待的。我也和一个在亚信的同学大厅确认过了,他也很期待。

讲道理,一家公司的兴衰,可能就是因为当初一件很不起眼的小事。
那 AI 时代,如果公司的业务能和 Token,能和出海,能和月之暗面这样的新兴公司关联起来,绝对是好事一桩。
事在人为嘛。
我帮大家整理了一下亚信科技的基本信息,同步给大家做个参考。

核心业务主要分三大板块。
其一是运营商核心系统,包括BSS(业务支撑系统)和OSS(网络支撑系统),前者主要负责电信运营商的计费、出账、CRM、资费套餐与订单管理等;后者负责运营商网络运维、资源调度和性能监控。
其二是智能数据运营,为金融、汽车、政企提供数智化运营和行业咨询。
其三是智能连接产品和新兴方向,聚焦5G专网、边缘智能算力底座、工业互联网和卫星互联网,2025年开始确立 AI 优先的战略方针,已获得英伟达中国区P0级 ISV 合作伙伴。
行业地位基本上可以配得上国内通信软件领域的元老或者霸主。
本质上走的是大型 ToB/ToG/ToTelco 的软件交付与运维(软件产品许可 + 定制化开发实施 + 长期系统运维服务费)。
普通研发的薪资在 10k-16k,算法能达到 20k-35k,年终奖理论上是 13薪,配套有班车、餐补、交通通讯补贴、定期体检等,但据说,每月 1000 元的综合补贴已经被取消。
还有一点就是题目里提到的,8月份,亚信科技与月之暗面正式签署了名为“登月计划”的框架合作协议,亚信科技直接成为了月之暗面(也就是Kimi)的优选前沿部署工程师(FDE)合作伙伴。
也就是企业级 Agentic AI 落地以及围绕 Token 的全链路运营体系。
从具体的 Token 业务分工来看,月之暗面主要负责输出 Kimi 大模型的底层权重、算力资源与模型能力供给;而亚信科技则把自己深耕三十多年的运营商级计费与计量看家本领,完整移植到 AI 时代。
保守估计,后面很多APP的生活缴费里就会出现给 Token 充值的选项。
如果你是一位愿意相信努力、相信过程、相信一步一个脚印、相信自己能在 AI 时代分一杯羹的人,那接下来的硬核内容,希望你能认真读一读。

(全文比较肝,保证大家能学到很多很多,系好安全带,我们粗粗发~)
content
01、介绍下你的 PaiCLI 项目,你为什么要做这样一个项目,不是已经有 Claude Code 这样的终端 Agent 了吗?
“PaiCLI 是我用 Java 写的终端 Agent 命令行工具,对标 Claude Code,支持三种执行模式。”

“ReAct 是默认模式,适合日常的短任务。Plan-and-Execute 用于复杂任务,先让模型生成一个带依赖关系的任务图,按拓扑排序执行,中途失败可以触发重新规划。Multi-Agent Team 模式是多角色协作,规划器拆任务、Worker 执行、审查器把关,审查不合格的会打回重做。”
“做这个项目的原因是,我天天用 Claude Code,用得越多越想搞清楚它底层到底怎么跑的。看文档、读博客都不够深入,得自己从头做一个,才能真正理解哪些设计是必要的,哪些才是 Agent 时代最应该掌握的技术栈,比如说Memory机制、上下文管理、摘要压缩、提示词工程、Harness等等。”

02、MySQL 索引在什么情况下会失效?
“常见的有这么几种情况。”
“第一种,在索引列上使用函数或者表达式。比如 WHERE YEAR(create_time) = 2026,优化器没办法直接用 B+树查找,因为索引存的是 create_time 的原始值,不是 YEAR() 的计算结果。改成 WHERE create_time >= '2026-01-01' AND create_time < '2027-01-01',范围查询,就能走索引了。”
“第二种,隐式类型转换。phone 字段是 varchar 类型,查询写成 WHERE phone = 13800138000,MySQL 会把 varchar 转成数字来比较,相当于在索引列上套了一个隐式的 CAST 函数,索引就用不上了。加个引号 WHERE phone = '13800138000' 就好了。”

“第三种,复合索引没有遵循最左前缀原则。建了一个 (a, b, c) 的复合索引,查询条件只有 WHERE b = 1,跳过了最左列 a,索引用不上。但 WHERE a = 1 AND c = 3 是可以用到 a 这一列的索引的,只是 c 的部分用不到。”
“第四种,OR 条件里有一个列没有索引。WHERE a = 1 OR b = 2,如果 b 上没建索引,优化器可能直接放弃索引走全表扫描。要么给 b 也建索引,要么改成 UNION。”
使用 LIKE 进行模糊查询时,索引什么情况下会失效?
“看通配符 % 的位置。”
“'keyword%' 这种右模糊可以走索引,'%keyword' 和 '%keyword%' 这两种左模糊走不了。”

“原因是 B+树按字典序排列。'keyword%' 等价于一个范围查询——所有以 keyword 开头的值在 B+树上是连续存放的,从 keyword 这个位置开始往右扫就行。但 '%keyword' 没有确定的起始位置,B+树的有序性用不上,只能逐行扫描。”
“如果业务上确实需要左模糊查询,可以考虑全文索引(FULLTEXT INDEX),或者把搜索功能交给 Elasticsearch 之类的专门做全文检索的引擎。”
03、消息队列在 AI Agent 系统中的作用是什么?
“第一个是异步解耦。Agent 调用外部工具的耗时差异很大。读一个本地文件可能几毫秒,调一次搜索 API 可能好几秒,跑一段代码就更慢。如果主线程同步等每一个工具返回,用户体验很差。消息队列把任务投递和结果消费解耦,投递完就可以做别的事情。”

“第二个是削峰填谷。多个用户同时发起 Agent 请求,但 LLM API 有并发和速率限制。消息队列做缓冲,请求先进队列排队,消费端按照 API 的限速逐个处理,不会因为瞬时流量把 API 打挂。”
“第三个是多 Agent 协作时的任务分发。规划器把一个大任务拆成多个子任务,通过队列分发给不同的 Worker。Worker 完成后把结果放回队列,编排器消费结果判断下一步做什么。队列天然支持这种生产者-消费者模式,扩容也方便。”
为什么不直接通过数据库通信?
“第一,延迟问题。数据库没有主动推送机制,消费端只能轮询。轮询间隔设短了数据库压力大,设长了任务处理不及时。消息队列原生支持推送,消息一进来消费端立刻就能拿到。”

“第二,锁竞争。多个 Worker 去同一张任务表抢任务,得用 SELECT ... FOR UPDATE 加锁。并发一高就成瓶颈,Worker 越多争抢越严重。消息队列的消费是无竞争的,每条消息只会被一个消费者拿到。”
04、多模态大模型的具体结构是什么样的?
“多模态大模型的结构分三个模块:视觉编码器、投影层、语言模型。”

“视觉编码器一般用 ViT(Vision Transformer)。它把一张图片切成固定大小的 patch,比如 14×14 像素一个 patch。每个 patch 生成一维向量,加上位置编码之后送进 Transformer 编码器。输出是一组视觉 token,每个 patch 对应一个向量。”
“投影层是视觉编码器和语言模型之间的桥梁。视觉编码器输出的向量维度和 LLM 的词嵌入维度通常不一样,投影层负责把视觉 token 映射到 LLM 能理解的嵌入空间里去。映射完成后,视觉 token 和文本 token 拼在一起,一起送进 LLM 做自回归生成。”
视觉编码器和语言模型的衔接方式有哪些?
“第一种是线性投影,就一个全连接层,把视觉编码器的输出维度映射成 LLM 的嵌入维度。LLaVA 第一版用的就是这种,简单直接,训练速度快。”
“第二种是 MLP 投影,两层全连接加一个激活函数。比线性投影的表达能力更强,LLaVA-1.5 升级到了 MLP,图像理解的准确率也提升了。”

“第三种是 Q-Former,BLIP-2 提出的方案。它引入一组可学习的 query token,通过交叉注意力(Cross-Attention)从视觉编码器的输出里提取信息。好处是可以控制输出的视觉 token 数量——不管输入图片多大,Q-Former 输出的 token 数是固定的,LLM 这边的计算量可控。”
“训练一般分两个阶段。第一阶段冻结视觉编码器和 LLM 的参数,只训练投影层,让它学会把视觉特征对齐到语言空间。第二阶段解冻 LLM,用图文配对的数据做端到端微调,让模型学会根据图像内容生成准确的文字描述。”
05、Redis 在 AI Agent 系统中可能有哪些应用场景?
“结合我在派聪明(RAG 知识库项目)里的实际使用,Redis 在 Agent 系统中差不多有这么几个场景。”
“第一个是会话缓存。派聪明把每个用户的对话历史存在 Redis 里,key 是 conversation:{conversationId},value 是一个 JSON 数组,最多保留最近 20 条消息,TTL 设成 7 天。每次 Agent 开始新一轮推理,先从 Redis 取出对话历史注入上下文,推理完把新消息追加进去。比查 MySQL 快得多,而且 MySQL 那边也有一份永久存储做兜底。”

“第二个是限流。LLM API 调用有成本,不能让单个用户无限制地发请求。派聪明用 Redis 做用户级限流,聊天消息限制 30 次/分钟,Embedding 批量请求限制 60 次/分钟、每天 2000 次。Redis 的原子递增操作和过期机制做滑动窗口限流很方便,几行代码就能搞定。”
“第三个是用户反馈注入。用户对 Agent 回答的点赞、点踩、纠正,存在 Redis Hash 里,key 是 feedback:{userId}。每次构建系统提示词的时候,取最近 5 条反馈注入进去,让 Agent 逐步适应用户的偏好。”
“第四个是语义缓存。相似的问题如果之前回答过,可以直接返回缓存的答案,省掉一次 LLM 调用。实现思路是把用户问题做 Embedding,和缓存池里的向量做相似度计算,超过阈值就命中缓存。”
如何设计缓存策略?
“TTL 要分级。会话缓存 7 天就够了,用户一周都没用说明这轮对话已经结束了。反馈缓存可以设长一点,30 天。语义缓存的 TTL 看知识库更新频率——知识库一天一更新,语义缓存就设成 1 天。”

“主动失效也得做。知识库有新文档入库或者旧文档更新的时候,要主动清除相关的语义缓存。光靠 TTL 自然过期,会有一段时间用户拿到的是过时的答案。”
“还有降级策略。Redis 挂了不能影响核心流程。会话缓存降级到 MySQL 查询(派聪明的对话历史在 MySQL 也有一份),限流降级到本地计数器,语义缓存降级到直接调用 LLM。服务可以慢,但不能因为缓存层出问题就整个不可用。”
06、RAG 流程中为什么要引入父子索引?
“父子索引解决的是一个核心矛盾,检索需要小块,理解需要大块。”
“检索的时候,块越小越精确。一个 512 字符的小块里如果命中了关键词,说明这段内容大概率和查询相关。但如果是一个 5000 字符的大块,里面可能只有一两句和查询有关,其他内容都是噪音,检索排序就不准了。”
“但 LLM 生成答案的时候又需要大块。512 字符往往只有一个知识点的片段,缺少上下文,模型可能理解不完整。”

“父子索引的做法是:用小块做检索,命中之后把小块所属的大块送给 LLM。在派聪明的实现里,子 chunk 是 512 字符,切分逻辑是先按段落(两个换行符)分割,段落太长再按句子切,不足 100 字符的短块合并到前一个块里去。相邻块之间留 100 字符的重叠,保证语义不会在切分点断裂。父 chunk 设成 1MB,用流式解析处理,防止大文件一次性加载导致内存溢出。”
BM25 和向量检索如何融合?
“派聪明用的是两阶段融合——先向量召回,再 BM25 重排序。”
“第一阶段是向量检索。用户的查询通过阿里 DashScope 的 text-embedding-v4 模型转成 2048 维向量,在 Elasticsearch 里做 KNN 搜索。召回窗口设成 topK 的 30 倍,如果最终要 5 条结果,先召回 150 条候选,保证不会漏掉好的内容。”

“第二阶段是 BM25 重排序。在候选集上跑 BM25 关键词匹配,用 ES 的 rescore 机制。权重配比是 KNN 0.2、BM25 1.0,BM25 占绝对主导。”
“知识库场景里,用户的查询通常包含明确的关键词,比如产品名、技术术语、错误代码。关键词精确匹配比语义相似度更可靠。向量检索的价值在于召回阶段的广度——语义相近但用词不同的内容也能被找到——但最终排序还是靠关键词匹配靠谱。”
“还有一个降级策略:如果 Embedding API 超时导致向量生成失败,自动降级为纯 BM25 检索,不会直接报错给用户。”
07、ReAct 框架的工程实现细节,消息格式如何设计?
“ReAct 的工程实现就是一个 while(true) 循环。PaiCLI 里面每一轮循环做四件事情。”
“第一步,检查退出条件,有没有被取消、token 预算还够不够。第二步,检查对话历史要不要压缩,有 LSP 诊断信息的话也在这一步注入。第三步,把当前的对话历史和工具定义一起发给 LLM。第四步,看 LLM 返回的结果里有没有工具调用。”

“如果 LLM 返回了 tool_calls,就执行工具,把结果追加到对话历史,进入下一轮循环。如果没有返回 tool_calls,说明模型认为任务完成了,循环结束,把最终的文本回复返回给用户。”
消息格式用了四种角色:system、user、assistant、tool。
assistant 消息可以同时带文本内容和工具调用请求:
{
"role": "assistant",
"content": "我来读一下这个文件",
"tool_calls": [
{
"id": "call_abc123",
"function": {
"name": "read_file",
"arguments": "{\"path\": \"src/Main.java\"}"
}
}
]
}工具执行完之后,结果用 tool 角色传回,通过 tool_call_id 和上面的调用一一关联:
{
"role": "tool",
"tool_call_id": "call_abc123",
"content": "文件内容..."
}
“LLM 一次可以返回多个 tool_calls,PaiCLI 支持并行执行,最多 4 个同时跑,结果按原始顺序追加到对话历史,保证消息序列的稳定。”
08、tool response 应该用什么角色传回?
“用 tool 角色,通过 tool_call_id 和 assistant 消息里的 tool_calls 一一关联。”

“这个设计在 OpenAI、Anthropic、GLM 的 API 规范里都是一样的。tool 是一个独立的消息角色,专门用来传递工具执行结果。”
为什么不用 user 或 assistant 角色?
“用 user 角色传回,模型会把工具的执行结果当成用户说的话。后续对话里模型可能会去回应这段‘用户输入’,而不是把它当作工具返回的数据来用。多轮对话一长,工具结果和真实的用户输入混在一起,模型越来越分不清谁在说什么。”

“用 assistant 角色传回,模型会认为这段内容是自己说过的话。它的自我认知就乱了。明明不是自己产出的内容被记成了自己的发言,后续推理可能建立在错误的前提上。”
“tool 角色专门为这个场景设计。模型看到 tool 角色的消息加上 tool_call_id,就明确知道‘这是我之前调用某个工具返回的执行结果’,不会和用户输入或自己的回复搞混。语义隔离干净,多轮对话里也不会出问题。”
09、Agentic CPT、SFT、RL 三阶段训练流程分别是什么?
“三个阶段解决三个不同层次的问题,是递进关系。”

CPT 是持续预训练(Continual Pre-Training),目标是让模型“知道”工具和领域知识的存在。做法是在基座模型的基础上继续做无监督预训练,语料里加入大量的 API 文档、工具调用格式定义、函数签名、领域知识文档。训完之后,模型知道了 function calling 的 JSON Schema 长什么样,知道各种工具的名称和参数含义,但还不会正确地使用它们。
SFT 是监督微调(Supervised Fine-Tuning),目标是让模型“会用”工具。训练数据是人工标注或者合成的专家级工具调用轨迹——给定一个用户请求,正确的做法是先调什么工具、参数怎么填、拿到结果后怎么决策下一步。

RL 是强化学习(Reinforcement Learning),目标是让模型“用得更好”。SFT 教的是正确的做法,RL 优化的是更高效的做法。定义一个奖励函数——任务完成给正奖励,失败给负奖励,每多用一步工具调用给一点小的负奖励,鼓励模型用更少的步骤完成任务。模型在真实或者模拟的环境里反复尝试,通过奖励信号不断调整自己的策略。训完之后,模型会倾向于选择步骤更少、成功率更高的工具调用路径。
“三者的关系:CPT 打基础认知,SFT 教标准动作,RL 优化决策质量。跳过 CPT 直接做 SFT,模型连工具格式都不认识,学不动。跳过 SFT 直接做 RL,模型没有基本的行为模式,探索空间太大。”
10、Agent 的记忆机制怎么设计?

“第一层是短期记忆,就是当前会话的对话历史。一个消息列表,每轮 LLM 调用都完整带上。问题是越聊越长,token 预算会超。”
“每条长期记忆有 id、content、type 和 metadata。metadata 里标注了 scope(是全局的还是项目级的)和来源。触发方式有两种:用户主动说‘记住这个’或者用 /save 命令,Agent 调用 save_memory 工具写入文件。”

“检索目前用的是关键词匹配。每轮 LLM 调用前,根据用户的输入提取关键词,在记忆库里做匹配,命中的记忆注入系统提示词。”
ending
GPT-6 正式发布,不知不觉,老大哥的版本已经到 6 时代了。
真的很不可思议。
AGI 能不能来,我很关心,但我更关心到底能对我们的实际生活和工作带来多大的提升。
时代越来越快,而你我更需要关注思想,关注属于你的 body。
抛开偏见,去接纳身边的每一个人,每一家公司,每一个业务,每一个模型,每一个 Agent,每一个 Token。
踏踏实实的活着,自由自在的活过。
在变化如此快的AI时代,留下浓墨淡彩的一页。
