自然语言查询、分析数据(NL-TO-SQL)的尝试
让查数据这件事,不再是高高在上、遥不可及的技能,而是人人都能玩得转,妙趣横生的小技巧。比如“我的店上周赚了多少钱?哪个商品即将售罄?这个月卖的最多的商品是啥?”,下一秒,答案就像变魔术一样蹦出来。直接看效果
流程如下,
- 前端使用gradio,采集麦克风声音
- 后端收到声音,使用openai的speech-to-text
- 文字通过dbgpt(链接各种自定义模型),转换为sql进行数据库查询
- 返回对应数据
关键代码
让查数据这件事,不再是高高在上、遥不可及的技能,而是人人都能玩得转,妙趣横生的小技巧。比如“我的店上周赚了多少钱?哪个商品即将售罄?这个月卖的最多的商品是啥?”,下一秒,答案就像变魔术一样蹦出来。直接看效果
流程如下,
关键代码
需求如下,产品团队高频要求翻译团队给出符合标准的翻译件,比如翻译产品文档,其中又有大量的术语,比如3D结构光、扫码头、主屏、客显屏、立式等(在公司内有统一的标准叫法),使用市面通用的翻译产品需要自己修改。看效果
原理如图
openai负责文档Retrieval,flowise负责功能补充,同时做了一次封装,gradio负责提供展示页面,方便用户交互
gradio_run.py
import gradio as gr
import requests
import json
def call_api(question):
url = "https://xxxx.com/api/v1/prediction/asdasce1-5a7b-4d9e-9ed6-21a9aaaab2"
headers = {"Content-Type": "application/json"}
data = {"question": question}
response = requests.post(url, headers=headers, data=json.dumps(data))
return response.json().get("text", "No response text found.")
iface = gr.Interface(
fn=call_api,
inputs="text",
outputs="text",
)
iface.launch()
一直有个需求,企业内私有知识库RAG,“陪产假怎么申请?”,“公司发票抬头是啥?”等问题,解放行政、人事的部分人力。偶然发现钉钉“智能员工”非常契合。零代码开发、配置简单。看效果,支持单聊群聊。目前免费!
配置方式,登录钉钉开发者-数字员工,类似flowise编辑langchain的每个环节,别担心,有模板只需要简单修改!在知识库贴钉文档的链接。文档准备需要注意以下几点
产品名: No English - 不学英语 https://chat.openai.com/g/g-kkrKOWa1E-no-english
产品概览: No English - 您的个人化英语学习伙伴
产品定位:
在语言学习的长河中,No English 站在了技术与教育的交汇点,提供了一个创新的、用户友好的英语学习解决方案。我们的平台运用最新的人工智能技术,致力于提升英语学习效率,同时保持学习过程的趣味性和参与度。
核心功能:
知识资源库:
No English 配备了一系列的英语学习文件,涵盖商务英语和各类英语测试标准,如TEM-8、CET-4和CET-6,可供用户根据个人需要下载并学习。
技术能力:
用户动作与互动:
用户询问当日新闻时,会从指定接口请求,本app使用京东的汇聚新闻接口。
使用推荐:
No English 针对希望在移动设备上学习的用户进行了优化设计,特别推荐使用手机应用来体验我们的语音互动特性,这能够为用户提供更加沉浸式的学习环境。 手机端前两天还支持,现在已经不行了
相信大家或多或少体验过大模型的魅力,有一定门槛的chatGPT(包含各种套壳的chat_bot),还有文心、通义千问等等。我总结有以下小缺陷
打个比方大模型是大脑,AI agent给了模型“双手”。常见的autoGPT、babyGPT、本文介绍来自微软的autogen (https://microsoft.github.io/autogen/)
代码执行
先看效果,“请求https://www.baidu.com 50次,2秒间隔,记录每次的状态码、网络延迟,结果记录下来。并且生成图片,保存到当前目录下”
近期在尝试大数据在企业内的应用,两个需求:
两种方向:向量库+大模型、模型微调。
以下给出openai模型微调的详细过程,目前官方推荐gpt-3.5-turbo,gpt4的微调将在年底推出
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already."}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?"}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters."}]}
我的数据源是csv,第一列问题,第二列答案,用以下脚本处理
import pandas as pd
import json
def convert_csv_to_jsonl(input_csv, output_jsonl):
# Read the CSV file
df = pd.read_csv(input_csv)
with open(output_jsonl, 'w', encoding='utf-8') as f:
for _, row in df.iterrows():
jsonl_data = {
"messages": [
{"role": "system", "content": "SunSun is an internal knowledge base communication robot."},
{"role": "user", "content": row['Generated Questions']},
{"role": "assistant", "content": row['source']}
]
}
f.write(json.dumps(jsonl_data, ensure_ascii=False) + '\n')
# Usage
# convert_csv_to_jsonl('path_to_your_csv_file.csv', 'desired_output_file.jsonl')
if __name__ == "__main__":
convert_csv_to_jsonl('/Users/jixing/Downloads/export_result0925.csv',
'/Users/jixing/Downloads/export_result0925.jsonl')
import openai
# 替换你的key
openai.api_key = "sk-40LIdYxxxxxxx"
training_file = openai.File.create(
file=open("export_result0925.jsonl", "rb"),
purpose='fine-tune'
)
# 记录文件id,下一步需要使用
print(training_file.id)
import openai
# 你的key
openai.api_key = "sk-40LIdYIwxxxxx"
# 刚才的文件id
openai.FineTuningJob.create(training_file="file-0ACDKAM7xxxxxx", model="gpt-3.5-turbo")
最近在看大模型和运维行业的关联,初步想法是标记监控数据,配合混沌工程,给出故障数据进行多元线性回归,根据最佳曲线来预测故障。实际进行过程中发现困难重重,还在尝试标记数据。
最近有个很火的词儿叫“数字孪生”,又叫数字骨灰盒:),大意是通过大量的文字痕迹训练已有模型,让模型从“扮演”到“重塑”你。受启发于 https://greatdk.com/1908.html,并做了些许优化,效果还是挺好玩的,或许这才是数字世界的你?!😄
看疗效!
思路步骤:
优化项目:
python清洗脚本
import os
import re
import json
# 定义源文件夹和目标文件
source_folder = '/Users/jixing/Downloads/wechat_history'
output_file_path = '/Users/jixing/Downloads/0811output.txt'
# Regular expression patterns for extracting dates, usernames, and messages
date_pattern = re.compile(r"\((\d{4}-\d{2}-\d{2}) \d{2}:\d{2}:\d{2}\)")
user_msg_pattern = re.compile(r"^(.+?) \(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\):(.+)$")
# 遍历文件夹中的所有.txt文件
for filename in os.listdir(source_folder):
if filename.endswith('.txt'):
with open(os.path.join(source_folder, filename), 'r', encoding='utf-8') as source_file:
content = source_file.readlines()
# Parsing the chat data
conversations = []
current_date = None
current_convo = []
for line in content:
# Check for date
date_match = date_pattern.search(line)
if date_match:
date = date_match.group(1)
if current_date != date and current_convo:
conversations.append(current_convo)
current_convo = []
current_date = date
# Extracting user and message
user_msg_match = user_msg_pattern.match(line)
if user_msg_match:
user, msg = user_msg_match.groups()
if current_convo and current_convo[-1][0] == user:
current_convo[-1][5] += f",{msg.strip()}"
else:
current_convo.append([user, msg.strip()])
# Adding the last conversation if any
if current_convo:
conversations.append(current_convo)
# Formatting conversations
adjusted_conversations = []
for convo in conversations:
history = []
for i in range(0, len(convo) - 1, 2): # Increment by 2 to ensure one question and one answer
prompt = convo[i][6]
response = convo[i + 1][7] if i + 1 < len(convo) else None
if response: # Only add to the list if there's a response
adjusted_conversations.append({
"prompt": prompt,
"response": response,
"history": history.copy()
})
history.append([prompt, response])
# Appending the results to output.txt, one object per line
with open(output_file_path, 'a', encoding='utf-8') as output_file:
for convo in adjusted_conversations:
json.dump(convo, output_file, ensure_ascii=False)
output_file.write('\n')
清洗后数据,可以看到已经有非常完整的逻辑关系了
我在训练时使用了70%的训练集,30%作为测试集。3000条数据在我的2080显卡需要10小时!都去试试看效果吧:)
OPA是一种开源通用策略引擎,可在整个堆栈中实现统一的、上下文感知的策略实施。该项目于2018年4月被CNCF沙箱接受,2021年2月4日正式毕业于CNCF。来自大约 30 个组织的 90 多人为 OPA 做出了贡献,维护者来自包括 Google、Microsoft、VMware 和 Styra。
简单来说,是在服务上抽象一层,统一控制、审计,本文讨论仅限在Kubernetes中的gatekeeper,对容器创建进行安全约束,确保符合运维规范。
上次的数据库故障余波未平。老服务整改周期内仍有可能增高,有没什么方法限制单个pod只能建立一定数量的数据库连接,把事故控制在一定范围内
陷入僵局,最笨用iptables限制,但还能实时发现pod的重启更换IP,难道要复杂化,监控结合脚本的方式吗?忽然灵光一闪,initContainers阶段不是可以做很多事情嘛
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
initContainers:
- name: init-iptables
image: my-iptables-image
command: ['sh', '-c', 'iptables -A OUTPUT -p tcp --dport 3306 -m connlimit --connlimit-above 20 -j REJECT']
containers:
- name: my-container
image: my-image
😅未验证,原理可行- -
某日读写分离中间件报警,有大量非业务IP连接涌入,新连接无法建立。查询数据库连接有大量的”unauthenticated user 1.2.3.4:37414 NULL Connect NULL Reading from net NULL”。一时间大量用户报障,“登录失效”、“设备断连”、“影响产线生产”等等
解决过程倒不复杂,跳过中间件恢复。售后工程师承认是中间件设计问题,释放连接逻辑bug,也提到了有大量连接时可能触发!
反观自身,架构设计阶段把过多的压力放在主库,19年上线的读写分离中间件就是“业务迭代优先,没时间基础设施改造”、“历史包袱”背景下的缓兵之计。阿里云的问题有几点
1.中间件控制台无法显示真实IP,故障后对方研发回复“日志因升级规格消失?”
2.假死后控制台无法重启
3.控制台监控不准确,使用者无法准确选择
4.1.2版本释放连接逻辑bug
主因是内部某服务突然建立了大量连接,进而引发的故障。
开发阶段把更多的重点放在功能实现和业务迭代上,而忽略了基础设施的可扩展性。这可能会造成短期内的业务顺利进行,但长期看来,如果基础设施不能跟上业务的发展,最终可能会形成技术债务,导致在运维阶段遇到无法解决或者处理复杂度高的问题。
云服务提供商的SLA(服务等级协议)是我们选择使用其服务的一个重要依据,但是是否100%信任SLA,我们需要结合自身的业务情况和对服务提供商的了解来决定。在应急情况下,我们可能需要更具备自主的故障应对能力,而不是完全依赖服务提供商的SLA。
在对内部OS部门优化的过程中发现,服务器整体利用率很好,编译时可以将服务器所有线程打满,唯一掉链子的时候是解压缩unzip环节,只有单线程升高。简单了解了下,原来已经有了多线程的pigz工具,格式做一些微调即可。详细评测https://zhuanlan.zhihu.com/p/389817246
在翻看docker源码时,发现也会将pigz等压缩工具优先
chatGPT火爆IT圈已经几个星期了,仿佛没用过就被时代所抛弃。了解后发现,使用门槛还是挺高,需要使用海外的手机号注册openai,常见的“机场”都会被屏蔽。偶然发现接口在国内是可以访问的
接下来的事就很简单了,使用django起了个页面,调用接口就可以了,供内网体验
有效代码12行
import openai
openai.api_key = "sk-od9TZTgXar70JLTxf4K1T3BlbkFJlcQjxxxxx"
response = openai.Completion.create(
engine="text-davinci-003", # select model
prompt="人生的意义何在?",
max_tokens=512, # response tokens
temperature=1, # diversity related
top_p=0.75, # diversity related
n=1, # num of response
)
completed_text = response["choices"][0]["text"]
print(completed_text)
需求描述:对某一地址,公司网络解析至172.16.1.1,外部解析到1.1.1.1
现状:公司内无单独的DNS服务器,DHCP分配上海公共DNS 202.96.209.5/133
过程:
云解析是通过识别LOCALDNS的出口IP,来判断访问者来源。
如客户端LOCALDNS支持EDNS
因为云解析DNS支持 edns-client-subnet,所以在获取访问者来源IP时,优先获取 edns-client-subnet 扩展里携带的IP ,如果edns-client-subnet 扩展里存在IP,云解析DNS会以该IP来判断访问者的地理位置 ;如果不存在,则以LocalDNS出口ip来判断访问者的地理位置。
dig +short TXT whoami.ds.akahelp.net
不错的办法,但我的DNS出口IP带ipv6,测试下来不生效
一、一直自诩是柔性的管理者,讲情怀、谈感情、不涉及原则问题都是友善提醒。谈谈近期遇到的一位伙伴小王,他是一个月前加入,原本负责网络的同学匆忙离开。积压的问题越来越多,小王在上手之后不太能搞定,我经常提醒不要成为“沟通黑洞”,发包过去一声不吭。无奈,离开
二、会议效率降低怪象
对待故障要敬畏,要追根因。惩罚机制要恰到好处,避免大家不敢动,更应该把故障看成一份宝贵的经验包;对待历史问题不逃避。我反对把责任甩的一干二净。
正因为我这种“大包大揽”的责任感,质量部门经常莫名其妙定责给我。前天一次故障,其部门自行维护的服务单点宕机,事故前多次反复提醒仍不整改。坑惨一波又一波接任者
三、越来越像项目经理,技术上已得不到成长,离我的“专家”目标渐远
遇到一种场景,某前端服务部署在kubernetes中,有偶发的服务故障。想着健康探针重启就行,忽然想到,如果是重要的线上服务宕机,不查出来心里憋得慌,怎么让服务恢复的同时又能保留现场呢
改当前pod的标签,这样deployment会认为副本消失,自动创建。完美实现老容器保留,业务也及时恢复
kong中默认有安全插件,黑白名单限流等,限制UA暂时没找到。可以自己开发一个
-- handler.lua
local BasePlugin = require "kong.plugins.base_plugin"
local MyPluginHandler = BasePlugin:extend()
MyPluginHandler.VERSION = "1.0.0"
MyPluginHandler.PRIORITY = 10
function MyPluginHandler:new()
MyPluginHandler.super.new(self, "block-user-agent")
end
function MyPluginHandler:access(conf)
MyPluginHandler.super.access(self)
-- 检查 User-Agent 请求头
local user_agent = kong.request.get_header("User-Agent")
for i, ua in ipairs(conf.blocked_user_agents) do
if user_agent == ua then
-- 如果 User-Agent 被阻止,使用 kong.response.exit 返回响应并停止处理
return kong.response.exit(conf.response_code, { message = conf.response_message })
end
end
end
-- schema.lua
local typedefs = require "kong.db.schema.typedefs"
return {
name = "block-user-agent",
fields = {
{ consumer = typedefs.no_consumer },
{ config = {
type = "record",
fields = {
{ blocked_user_agents = { type = "array", default = {}, elements = { type = "string", }, }, },
{ response_code = { type = "number", default = 403 }, },
{ response_message = { type = "string", default = "Forbidden" }, },
},
},
},
},
}
docker启动时注意修改kong/constants.lua,在插件底部加入UA_block
docker stop kong-gateway
docker rm kong-gateway
docker run -d --name kong-gateway \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_USER=kong" \
-e "KONG_PG_PASSWORD=kongpass" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
-e "KONG_ADMIN_GUI_URL=http://localhost:8002" \
-v /data/UA-block:/usr/local/share/lua/5.1/kong/plugins/UA-block \
-v /data/constants.lua:/usr/local/share/lua/5.1/kong/constants.lua \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 8444:8444 \
-p 8002:8002 \
-p 8445:8445 \
-p 8003:8003 \
-p 8004:8004 \
kong/kong-gateway:2.6.1.0-alpine
最近忙于处理安全事故,在政府的白帽行动中,发现了误暴露在公网的konga,通过发送post请求,能够成功注册管理员进而管理所有规则。我试过两个版本都成功
屏蔽公网访问避免95%的安全问题!
近一周安全问题频发,明显是针对性的精准渗透行为,钓鱼邮件、ERP服务器被拿下、线上kubernetes集群被拿到部分权限成功部署反弹shell。从入侵轨迹来看,未做破坏但有明显的扫描内网行为,对方对安全、运维都有比较深入的了解。与政府组织的“磐石行动”时间点吻合,推测是对我们的白帽行为
云安全中心提醒还是很精准的,以容器中被运行反弹shell为例。从kubernetes审计日志,“黑客”使用被泄露账号通过暴露在公网的k8s api server进来,在进行了一系列尝试后发现有A命名空间的管理权限,具有onl的namespace 权限,查看了cm发现免密登陆,推送镜像,创建deployment ,镜像中传输数据。已关服务,wifi api server取消外网监听
过程中用到的命令
pstree -p -a #查看
docker inspect #查看pod信息
docker run -it --entrypoint /bin/sh xxxxx #启动疑似容器
查看kubernetes 审计日志
kubernetes get rolebinding -n xxx -o yaml
最新战报:
内部员工已中招,对方社工客服运行了可执行文件,导致在OA内向其他用户发送病毒文件
ERP服务器沦陷,有扫描内网的行为
CRM服务器中毒
🏳️
在一次常态的EMQ集群巡检时发现,有非周期的CPU超过80%毛刺,按照预案新增了如下防火墙规则限流(此规则验证过多次),当天为了方便使用&&将多行语句连接成一行。执行后发现连接数立刻下降,通过监控发现大量连接都变成了non-establish
# 清空INPUT链,标记RELATED,ESTABLISHED,对超出限速的REJECT
iptables -F INPUT
iptables -t filter -A INPUT -p tcp -m multiport -m state --dport 1883,8883 --state RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A INPUT -p tcp -m multiport -m state -m limit --dport 1883,8883 --limit 200/second --limit-burst 600 --state NEW -j ACCEPT
iptables -t filter -A INPUT -p tcp -m multiport --dport 1883,8883 -j REJECT --reject-with tcp-reset
service iptables save
# 当天为批量执行,简化为一条
iptables -F INPUT && iptables -t filter -A INPUT -p tcp -m multiport -m state --dport 1883,8883 --state RELATED,ESTABLISHED -j ACCEPT && iptables -t filter -A INPUT -p tcp -m multiport -m state -m limit --dport 1883,8883 --limit 200/second --limit-burst 600 --state NEW -j ACCEPT && iptables -t filter -A INPUT -p tcp -m multiport --dport 1883,8883 -j REJECT --reject-with tcp-reset && service iptables save
黄色为non-establish
经排查,在执行标记流量 --state RELATED,ESTABLISHED 会将连接当前状态写入系统内核文件 /proc/net/nf_conntrack,当时每台机器均有100000左右连接,写入磁盘需要2-3秒。用&&将命令合并=没有间隔马上执行下条命令,未写完的连接未标记完成,命中了第三条REJECT tcpreset。陷入取消限速集群扛不住,增加限速丢弃连接死循环,通过SLB限速后,原厂删除集群信息后重建恢复。结论:iptables标记流量需要考虑写盘IO,执行时慢一些