前军教程网

中小站长与DIV+CSS网页布局开发技术人员的首选CSS学习平台

分享我的AI应用开发经验

打算在这篇文章分享我平时开发AI应用的经验,会持续更新。头条的规则是不允许已发布的文件有大幅修改,所以后面的更新会发表成新的文章,在评论里面放链接。


20250417:

今天注册了一个域名myaiweb.cn。 阿里云有活动,两年39块钱,送dns解析。 本来以为实名审核要很麻烦,但没想到填了点个人信息,很快申请下来了。 欢迎大家使用我的大五人格性格分析工具
https://www.myaiweb.cn/five.html

boss直聘会员才送一次大五人格性格测试,而我这个是免费的。测试完后还可以让ai针对你性格进一步分析,给出更有针对性的建议。

同时也申请了一个免费的测试证书,部署到了nginx。有效期3个月,等到期了再考虑买个付费的证书。

考虑到后面还要再搭个rag,可能还要再买一台机部署postgres,2核4g内存,一年700来块钱。不过暂时不着急


今天调试网页中,无意发现百度在首页的控制台里面,输出了百度校园招聘的广告,挺有技术情节的。 百度2025校园招聘简历投递:
https://talent.baidu.com/jobs/list 以后也许可以多翻一下网页源代码,也许有意外收获。


分享我最近写的,将ai返回的markdown格式内容转换成html格式输出的代码 (后面我考虑做成一个独立的网页),代码有些乱,因为主体是AI写的,我负责调试修改bug。

 	function processAIResponse(data) {
                // 增强的 markdown 解析逻辑
                let formattedResult = data.result
                // 先处理分隔线
                    .replace(/^[-]{3,}/gm, '<hr>');
                console.log('----- 分隔符处理后 -----', formattedResult);
                //处理表格(调整后的正则表达式)
                formattedResult = formattedResult
                .replace(/(\|[^\n]+\|[\s]*[\r\n]+)(\|[\s\-|:]+\|[\s]*[\r\n]+)((\|[^\n]+\|[\s]*[\r\n]*)+)/gm,
                (match, header, divider, rows) => {
                    // match: 完整匹配的表格字符串(从 | 表头 | 到 | 最后一行 | 的全部内容)
                    // header: 第一个捕获组 ([^\|]+?) - 表头行的内容(包含首尾的 |)
                    // divider: 第二个捕获组 ([\s\-:|]+) - 分隔线行的内容(包含首尾的 |)
                    // rows: 第三个捕获组 ((?:\|.*\|[\r\n]*)+) - 所有数据行的合并字符串
                    
                    // 示例表格结构:
                    // | Header1 | Header2 | <- 这是header
                    // |---------|---------| <- 这是divider
                    // | Row1Col1| Row1Col2| <- 从这是rows
                    // | Row2Col1| Row2Col2|

                    console.log('----- 发现表格内容 -----');
                    console.log('发现表格结构 原始内容:', match.substring(0, 50));

                    const processCell = (cell) => {
                        // 保留换行符并移除首尾空格
                        return cell.trim().replace(/\n/g, '<br>');
                    };

                    // 处理表头
                    const headerRow = header.split('\n')[0]; // 取第一行作为表头
                    const headerCells = headerRow.split('|')
                        .slice(1, -1)
                        .map(cell => `<th>${processCell(cell)}</th>`)
                        .join('');

                    // 处理数据行
                    const bodyRows = rows.split('\n')
                        .filter(line => line.trim().startsWith('|'))
                        .map(row => {
                            return `<tr>${
                                row.split('|')
                                    .slice(1, -1)
                                    .map(cell => `<td>${processCell(cell)}</td>`)
                                    .join('')
                            }</tr>`;
                        })
                        .join('');

                    const finalTable = `<table class="analysis-table">
                        <thead><tr>${headerCells}</tr></thead>
                        <tbody>${bodyRows}</tbody>
                    </table>\n`;
                    return finalTable;
                });

                // console.log('----- 表格处理后 -----', formattedResult);
                // 2. 处理标题(增加严格边界匹配)
                formattedResult = formattedResult.replace(/^#{1,6}\s+([^\n]+)/gm, (match, p1) => {
                    console.log('处理标题:', match.trim());
                    const level = match.match(/^#+/)[0].length;
                    return `<h${level}>${p1.trim()}</h${level}>`;
                });

                console.log('----- 标题处理后 -----', formattedResult);
                formattedResult = formattedResult
                // 修改列表项匹配正则表达式,支持中文格式
                .replace(/^([-*+]|\s+[-*+]|\u2022|\u25E6|\u25AA)\s(.+)$/gm, (match, bullet, content) => {
                    console.log('发现列表项:', match);
                    return `<li>${content}</li>`;
                })
                // 加粗和斜体
                .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
                .replace(/\*(.+?)\*/g, '<em>$1</em>')
                // 代码块
                .replace(/```([\s\S]*?)```/g, '<pre><code>$1</code></pre>')
                // 行内代码
                .replace(/`(.+?)`/g, '<code>$1</code>')
                // 链接和图片
                .replace(/!\[(.*?)\]\((.*?)\)/g, '<img alt="$1" src="$2">')
                .replace(/\[(.*?)\]\((.*?)\)/g, '<a href="$2">$1</a>')
                // 引用
                .replace(/^\>\s(.+?)$/gm, '<blockquote>$1</blockquote>')
                // 4. 包裹无序列表(增加边界检测)
                .replace(/(<li>[\s\S]*?<\/li>)+/g, match => {
                    return /<\/?h\d>/.test(match) ? match : `<ul>${match}</ul>`;
                })
                // 5. 最后处理换行(排除表格和列表中的换行)
                .replace(/(?<!<\/td>|[>-])\n/g, '<br>');
                formattedResult += "<br>";
        
                console.log("formattedResult = ", formattedResult);
                //document.getElementById('ai-result').innerHTML = formattedResult;
            }

20250416:

今天把前几天用ai写的网页工具部署到web端,发现一个问题。之前我在开发环境用的是npm run dev启动服务的,在浏览器访问时可以正常访问。

但是上传到linux环境时,因为加了个前缀(我上面部署了几个不同工具,通过nginx分发),访问时就会出现问题了,在操作网页过程中,浏览器地址栏会变化,导致前缀丢失。

今天查了一下,说要把一个函数换了就行

const router = createRouter({

history: createWebHashHistory(import.meta.env.BASE_URL), // 修改这一行 从createWebHistory改成createWebHashHistory就能自适应所有目录

routes

});

不过这样网址会有#结果,例如:
http://www.myaiweb.cn/prod_frontend/index.html#/

难怪上家公司我们前端同事开发的web页面网址也是有#,之前没问过他原因,还以为是故意的


昨天安装openai新版本失败,今天查了一下,说可能是python版本太低。所以我从网上下载了一个3.12版本的代码包,按ai提示安装了依赖,居然一次编译过了。之后尝试更新openai版本,果然顺利升级成功。

20250415:

今天买了一个阿里云服务器,打算在上面跑一个python脚本,转发前端调用deepseek的请求(前端直接发起请求会因为跨域问题失败)。程序在我windows机器上跑起来还是比较顺利的,但在服务器运行就报错,提示找不到OpenAI

查了一下,是因为openai包的版本太低了。但不知道为什么,无论我怎么升级,它都只能升级到0.8版本,而根据ai回答,OpenAI最低要1.0。

后来只能放弃用openai包,自己写http请求代替,,贴个代码,跟大家分享一下,说不定哪天有人需要

def send_messages(messages):

	headers = {

	"Authorization": "Bearer sk-", # 这里是要填从deepseek那里创建的密钥

	"Content-Type": "application/json"

	}

	data = {

	"model": "deepseek-chat",

	"messages": messages

	}

	response = requests.post(

	"https://api.deepseek.com/v1/chat/completions",

	headers=headers,

	json=data

	)

	response.raise_for_status()

	# 打印响应状态和结果

	print(f"API响应状态码: {response.status_code}")

	print(f"API响应内容: {response.text}")

	result = response.json()

	print(f"解析后的JSON结果: {json.dumps(result, indent=2, ensure_ascii=False)}")

	# 返回给前端自行解析

	return response.text

	#return result['choices'][0]['message']

阿里云服务器默认是没放开80端口的,先要在机器上把80端口添加到防火墙白名单,然后在阿里云控制台也配置放开80端口。(443端口也一样)。我因为之前踩过这个坑,这次把防火墙放开后端口还是不能访问,立即就想到要到控制台修改路由规则。相信应该建站的新人会踩我这个坑,记录一下。


20250414:

今天尝试写一个网页工具,调用deepseek的api,发现一些问题。

1 直接在网页上调用deepseek的api请求会报错

five.html:1 Access to fetch at 'https://api.deepseek.com/' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No '
Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.了解此错误

five.html:773

POST https://api.deepseek.com/ net::ERR_FAILED

估计是官方服务器没配置支持跨域查询,需要自己搞一台服务器转发才行

2 deepseek r1官方api,返回的回答结果在content,思考过程在reasoning_content,而有一些本地部署的模型却是把思考过程放在<think></think>中

3 腾讯的r1模型费用特别高,一年要10万3千元(不限量),所以我没用,直接到官网充了10块钱,生成了一个测试的api-key。

不过目前有个问题,官网没有账户管理概念,所有api-key共用一个金额,暂时不知道怎么处理。按我想法最好是不同的api-key可以有不同的余额。


20250114:

做rag需要到向量数据库查询知识时,需要注意先将问题改写后,再到数据库查,否则查询结果会很不精确。

例如用户对话是这样的:

user: 你们公司有什么特色技术吗

system: 我们公司在能源管理和安防上有优势

user:还有没?<-- 这里如果不改写,直接到向量数据库查询,会找不到数据。需要先使用大模型结合上下文 将这个问题改写成:你们公司除了能源管理和安防外,还有哪些特色技术

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言