first commit

This commit is contained in:
wubaoyong
2025-12-29 12:56:55 +08:00
commit fbeb74f0ac
47 changed files with 5026 additions and 0 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

11
.obsidian/app.json vendored Normal file
View File

@@ -0,0 +1,11 @@
{
"pdfExportSettings": {
"includeName": false,
"pageSize": "Tabloid",
"landscape": false,
"margin": "1",
"downscalePercent": 100
},
"alwaysUpdateLinks": true,
"promptDelete": false
}

8
.obsidian/appearance.json vendored Normal file
View File

@@ -0,0 +1,8 @@
{
"accentColor": "",
"theme": "moonstone",
"cssTheme": "Baseline",
"textFontFamily": "Maple Mono CN",
"interfaceFontFamily": "Maple Mono CN",
"monospaceFontFamily": "Maple Mono CN"
}

4
.obsidian/community-plugins.json vendored Normal file
View File

@@ -0,0 +1,4 @@
[
"global-proxy",
"obsidian-git"
]

30
.obsidian/core-plugins-migration.json vendored Normal file
View File

@@ -0,0 +1,30 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"properties": false,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": false
}

33
.obsidian/core-plugins.json vendored Normal file
View File

@@ -0,0 +1,33 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"properties": false,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": false,
"webviewer": false,
"footnotes": false,
"bases": true
}

22
.obsidian/graph.json vendored Normal file
View File

@@ -0,0 +1,22 @@
{
"collapse-filter": true,
"search": "",
"showTags": false,
"showAttachments": false,
"hideUnresolved": false,
"showOrphans": true,
"collapse-color-groups": true,
"colorGroups": [],
"collapse-display": true,
"showArrow": false,
"textFadeMultiplier": 0,
"nodeSizeMultiplier": 1,
"lineSizeMultiplier": 1,
"collapse-forces": true,
"centerStrength": 0.518713248970312,
"repelStrength": 10,
"linkStrength": 1,
"linkDistance": 250,
"scale": 1,
"close": true
}

View File

@@ -0,0 +1,8 @@
{
"enableProxy": true,
"httpProxy": "",
"httpsProxy": "",
"socksProxy": "socks5://127.0.0.1:7891",
"bypassRules": "<local>,127.*,10.*,172.16.*,172.17.*,172.18.*,172.19.*,172.20.*,172.21.*,172.22.*,172.23.*,172.24.*,172.25.*,172.26.*,172.27.*,172.28.*,172.29.*,172.30.*,172.31.*,192.168.*",
"pluginTokens": "persist:surfing-vault-${appId}"
}

185
.obsidian/plugins/global-proxy/main.js vendored Normal file
View File

@@ -0,0 +1,185 @@
var import_obsidian = require("obsidian");
const DEFAULT_SETTINGS = {
enableProxy: false,
httpProxy: "",
httpsProxy: "",
socksProxy: "",
bypassRules: "<local>,127.*,10.*,172.16.*,172.17.*,172.18.*,172.19.*,172.20.*,172.21.*,172.22.*,172.23.*,172.24.*,172.25.*,172.26.*,172.27.*,172.28.*,172.29.*,172.30.*,172.31.*,192.168.*",
pluginTokens: "persist:surfing-vault-${appId}"
};
var GlobalProxyPlugin = class extends import_obsidian.Plugin {
async onload() {
await this.loadSettings();
this.addSettingTab(new GlobalProxySettingTab(this.app, this));
}
async onunload() {
this.disableProxy()
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
this.sessionMap = {}
this.enableProxy();
}
async saveSettings() {
await this.saveData(this.settings);
}
async enableProxy() {
if (!this.settings.enableProxy) {
return;
}
let sessions = []
this.sessionMap.default = electron.remote.session.defaultSession
sessions.push(this.sessionMap.default)
if (!!this.settings.pluginTokens) {
let pluginTokens = this.settings.pluginTokens.split("\n");
for (var i = 0; i < pluginTokens.length; i++) {
if (!pluginTokens[i]) {
continue;
}
let token = pluginTokens[i].replace("${appId}", this.app.appId)
let session = await electron.remote.session.fromPartition(token)
sessions.push(session)
this.sessionMap[token] = session
}
}
let proxyRules = this.composeProxyRules(),
proxyBypassRules = proxyRules ? this.settings.bypassRules : undefined;
for (var i = 0; i < sessions.length; i++) {
await sessions[i].setProxy({ proxyRules, proxyBypassRules });
}
if (proxyRules) {
new import_obsidian.Notice('Enable proxy!');
}
}
async disableProxy() {
let sessions = []
for (const key in this.sessionMap) {
sessions.push(this.sessionMap[key])
}
for (var i = 0; i < sessions.length; i++) {
await sessions[i].setProxy({});
await sessions[i].closeAllConnections();
}
new import_obsidian.Notice('Disable proxy!');
}
composeProxyRules() {
if (!["socksProxy", "httpProxy", "httpsProxy"].
map((p) => !this.settings[p] || isValidFormat(this.settings[p])).reduce((res, check)=>{return res && check}, true)) {
return undefined;
}
const httpProxy= isValidFormat(this.settings.httpProxy) ? ";http=" + this.settings.httpProxy : "";
const httpsProxy= isValidFormat(this.settings.httpsProxy) ? ";https=" + this.settings.httpsProxy : "";
if (isValidFormat(this.settings.socksProxy)) {
return this.settings.socksProxy + httpProxy + httpsProxy + ",direct://"
} else if (!!httpProxy) {
return !!httpsProxy ? "http=" + this.settings.httpProxy + httpsProxy + ",direct://"
: this.settings.httpProxy + ",direct://"
} else if (!!httpsProxy) {
return this.settings.httpsProxy + ",direct://"
}
return undefined;
}
};
var GlobalProxySettingTab = class extends import_obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
new import_obsidian.Setting(containerEl)
.setName("Enable proxy")
.setDesc("Change your proxy status")
.addToggle((val) => val
.setValue(this.plugin.settings.enableProxy)
.onChange(async (value) => {
this.plugin.settings.enableProxy = value;
await this.plugin.saveSettings();
value ? this.plugin.enableProxy() : this.plugin.disableProxy();
}));
new import_obsidian.Setting(containerEl)
.setName("Socks Proxy")
.setDesc("Set up your socks proxy")
.addText((text) => text
.setPlaceholder("<scheme>://<host>:<port>")
.setValue(this.plugin.settings.socksProxy)
.onChange((value) => {
this.refreshProxy("socksProxy", value);
}));
new import_obsidian.Setting(containerEl)
.setName("Http Proxy")
.setDesc("Set up your http proxy")
.addText((text) => text
.setPlaceholder("<scheme>://<host>:<port>")
.setValue(this.plugin.settings.httpProxy)
.onChange((value) => {
this.refreshProxy("httpProxy", value);
}));
new import_obsidian.Setting(containerEl)
.setName("Https Proxy")
.setDesc("Set up your https proxy")
.addText((text) => text
.setPlaceholder("<scheme>://<host>:<port>")
.setValue(this.plugin.settings.httpsProxy)
.onChange((value) => {
this.refreshProxy("httpsProxy", value);
}));
new import_obsidian.Setting(containerEl)
.setName("Plugin Tokens")
.setDesc("For proxy specified plugins")
.addTextArea((text) => text
.setValue(this.plugin.settings.pluginTokens)
.onChange((value) => {
this.refreshProxy("pluginTokens", value);
}));
new import_obsidian.Setting(containerEl)
.setName("Blacklist")
.setDesc("Proxy blacklist")
.addTextArea((text) => text
.setPlaceholder("[URL_SCHEME://] HOSTNAME_PATTERN [:<port>]\n. HOSTNAME_SUFFIX_PATTERN [:PORT]\n[SCHEME://] IP_LITERAL [:PORT]\nIP_LITERAL / PREFIX_LENGTH_IN_BITS\n<local>")
.setValue(this.plugin.settings.bypassRules)
.onChange((value) => {
this.refreshProxy("bypassRules", value);
}));
}
async refreshProxy(key, value) {
this.plugin.settings[key] = value;
this.plugin.saveSettings();
this.plugin.enableProxy();
}
};
function isValidFormat(proxyUrl) {
if (!!proxyUrl) {
const regex = /^(\w+):\/\/([^:/]+):(\d+)$/;
const matches = proxyUrl.match(regex);
return !!matches;
}
return false;
}
module.exports = GlobalProxyPlugin;
/* nosourcemap */

View File

@@ -0,0 +1,11 @@
{
"id": "global-proxy",
"name": "Global Proxy",
"version": "1.0.4",
"minAppVersion": "0.15.0",
"description": "Use network proxy throughout Obsidian according to the rules configured in this plugin.",
"author": "windingblack",
"fundingUrl": "https://www.buymeacoffee.com/windingblack",
"authorUrl": "https://github.com/windingblack",
"isDesktopOnly": true
}

426
.obsidian/plugins/obsidian-git/main.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
{
"author": "Vinzent",
"authorUrl": "https://github.com/Vinzent03",
"id": "obsidian-git",
"name": "Git",
"description": "Integrate Git version control with automatic backup and other advanced features.",
"isDesktopOnly": false,
"fundingUrl": "https://ko-fi.com/vinzent",
"version": "2.35.2"
}

View File

@@ -0,0 +1,23 @@
#!/bin/sh
PROMPT="$1"
TEMP_FILE="$OBSIDIAN_GIT_CREDENTIALS_INPUT"
cleanup() {
rm -f "$TEMP_FILE" "$TEMP_FILE.response"
}
trap cleanup EXIT
echo "$PROMPT" > "$TEMP_FILE"
while [ ! -e "$TEMP_FILE.response" ]; do
if [ ! -e "$TEMP_FILE" ]; then
echo "Trigger file got removed: Abort" >&2
exit 1
fi
sleep 0.1
done
RESPONSE=$(cat "$TEMP_FILE.response")
echo "$RESPONSE"

View File

@@ -0,0 +1,629 @@
@keyframes loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.workspace-leaf-content[data-type="git-view"] .button-border {
border: 2px solid var(--interactive-accent);
border-radius: var(--radius-s);
}
.workspace-leaf-content[data-type="git-view"] .view-content {
padding-left: 0;
padding-top: 0;
padding-right: 0;
}
.workspace-leaf-content[data-type="git-history-view"] .view-content {
padding-left: 0;
padding-top: 0;
padding-right: 0;
}
.loading {
overflow: hidden;
}
.loading > svg {
animation: 2s linear infinite loading;
transform-origin: 50% 50%;
display: inline-block;
}
.obsidian-git-center {
margin: auto;
text-align: center;
width: 50%;
}
.obsidian-git-textarea {
display: block;
margin-left: auto;
margin-right: auto;
}
.obsidian-git-disabled {
opacity: 0.5;
}
.obsidian-git-center-button {
display: block;
margin: 20px auto;
}
.tooltip.mod-left {
overflow-wrap: break-word;
}
.tooltip.mod-right {
overflow-wrap: break-word;
}
/* Limits the scrollbar to the view body */
.git-view {
display: flex;
flex-direction: column;
position: relative;
height: 100%;
}
.git-tools {
display: flex;
margin-left: auto;
}
.git-tools .type {
padding-left: var(--size-2-1);
display: flex;
align-items: center;
justify-content: center;
width: 11px;
}
.git-tools .type[data-type="M"] {
color: orange;
}
.git-tools .type[data-type="D"] {
color: red;
}
.git-tools .buttons {
display: flex;
}
.git-tools .buttons > * {
padding: 0 0;
height: auto;
}
.workspace-leaf-content[data-type="git-view"] .tree-item-self,
.workspace-leaf-content[data-type="git-history-view"] .tree-item-self {
align-items: center;
}
.workspace-leaf-content[data-type="git-view"]
.tree-item-self:hover
.clickable-icon,
.workspace-leaf-content[data-type="git-history-view"]
.tree-item-self:hover
.clickable-icon {
color: var(--icon-color-hover);
}
/* Highlight an item as active if it's diff is currently opened */
.is-active .git-tools .buttons > * {
color: var(--nav-item-color-active);
}
.git-author {
color: var(--text-accent);
}
.git-date {
color: var(--text-accent);
}
.git-ref {
color: var(--text-accent);
}
.workspace-leaf-content[data-type="diff-view"] .d2h-d-none {
display: none;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-wrapper {
text-align: left;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-header {
background-color: var(--background-primary);
border-bottom: 1px solid var(--interactive-accent);
font-family: var(--font-monospace);
height: 35px;
padding: 5px 10px;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-header,
.workspace-leaf-content[data-type="diff-view"] .d2h-file-stats {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-stats {
font-size: 14px;
margin-left: auto;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-lines-added {
border: 1px solid #b4e2b4;
border-radius: 5px 0 0 5px;
color: #399839;
padding: 2px;
text-align: right;
vertical-align: middle;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-lines-deleted {
border: 1px solid #e9aeae;
border-radius: 0 5px 5px 0;
color: #c33;
margin-left: 1px;
padding: 2px;
text-align: left;
vertical-align: middle;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-name-wrapper {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 15px;
width: 100%;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-name {
overflow-x: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-wrapper {
border: 1px solid var(--background-modifier-border);
border-radius: 3px;
margin-bottom: 1em;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-collapse {
-webkit-box-pack: end;
-ms-flex-pack: end;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
border: 1px solid var(--background-modifier-border);
border-radius: 3px;
cursor: pointer;
display: none;
font-size: 12px;
justify-content: flex-end;
padding: 4px 8px;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-collapse.d2h-selected {
background-color: #c8e1ff;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-collapse-input {
margin: 0 4px 0 0;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-diff-table {
border-collapse: collapse;
font-family: Menlo, Consolas, monospace;
font-size: 13px;
width: 100%;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-files-diff {
width: 100%;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-diff {
overflow-y: hidden;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-side-diff {
display: inline-block;
margin-bottom: -8px;
margin-right: -4px;
overflow-x: scroll;
overflow-y: hidden;
width: 50%;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line {
padding: 0 8em;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line {
display: inline-block;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
white-space: nowrap;
width: 100%;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line {
padding: 0 4.5em;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line-ctn {
word-wrap: normal;
background: none;
display: inline-block;
padding: 0;
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
user-select: text;
vertical-align: middle;
white-space: pre;
width: 100%;
}
.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-code-line del,
.theme-light
.workspace-leaf-content[data-type="diff-view"]
.d2h-code-side-line
del {
background-color: #ffb6ba;
}
.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-code-line del,
.theme-dark
.workspace-leaf-content[data-type="diff-view"]
.d2h-code-side-line
del {
background-color: #8d232881;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line del,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line ins,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line del,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-line ins {
border-radius: 0.2em;
display: inline-block;
margin-top: -1px;
text-decoration: none;
vertical-align: middle;
}
.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-code-line ins,
.theme-light
.workspace-leaf-content[data-type="diff-view"]
.d2h-code-side-line
ins {
background-color: #97f295;
text-align: left;
}
.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-code-line ins,
.theme-dark
.workspace-leaf-content[data-type="diff-view"]
.d2h-code-side-line
ins {
background-color: #1d921996;
text-align: left;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line-prefix {
word-wrap: normal;
background: none;
display: inline;
padding: 0;
white-space: pre;
}
.workspace-leaf-content[data-type="diff-view"] .line-num1 {
float: left;
}
.workspace-leaf-content[data-type="diff-view"] .line-num1,
.workspace-leaf-content[data-type="diff-view"] .line-num2 {
-webkit-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
padding: 0 0.5em;
text-overflow: ellipsis;
width: 3.5em;
}
.workspace-leaf-content[data-type="diff-view"] .line-num2 {
float: right;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-linenumber {
background-color: var(--background-primary);
border: solid var(--background-modifier-border);
border-width: 0 1px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: var(--text-muted);
cursor: pointer;
display: inline-block;
position: absolute;
text-align: right;
width: 7.5em;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-linenumber:after {
content: "\200b";
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-linenumber {
background-color: var(--background-primary);
border: solid var(--background-modifier-border);
border-width: 0 1px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: var(--text-muted);
cursor: pointer;
display: inline-block;
overflow: hidden;
padding: 0 0.5em;
position: absolute;
text-align: right;
text-overflow: ellipsis;
width: 4em;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-diff-tbody tr {
position: relative;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-linenumber:after {
content: "\200b";
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-emptyplaceholder,
.workspace-leaf-content[data-type="diff-view"] .d2h-emptyplaceholder {
background-color: var(--background-primary);
border-color: var(--background-modifier-border);
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-line-prefix,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-linenumber,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-linenumber,
.workspace-leaf-content[data-type="diff-view"] .d2h-emptyplaceholder {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-code-linenumber,
.workspace-leaf-content[data-type="diff-view"] .d2h-code-side-linenumber {
direction: rtl;
}
.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-del {
background-color: #fee8e9;
border-color: #e9aeae;
}
.theme-light .workspace-leaf-content[data-type="diff-view"] .d2h-ins {
background-color: #dfd;
border-color: #b4e2b4;
}
.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-del {
background-color: #521b1d83;
border-color: #691d1d73;
}
.theme-dark .workspace-leaf-content[data-type="diff-view"] .d2h-ins {
background-color: rgba(30, 71, 30, 0.5);
border-color: #13501381;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-info {
background-color: var(--background-primary);
border-color: var(--background-modifier-border);
color: var(--text-normal);
}
.theme-light
.workspace-leaf-content[data-type="diff-view"]
.d2h-file-diff
.d2h-del.d2h-change {
background-color: #fdf2d0;
}
.theme-dark
.workspace-leaf-content[data-type="diff-view"]
.d2h-file-diff
.d2h-del.d2h-change {
background-color: #55492480;
}
.theme-light
.workspace-leaf-content[data-type="diff-view"]
.d2h-file-diff
.d2h-ins.d2h-change {
background-color: #ded;
}
.theme-dark
.workspace-leaf-content[data-type="diff-view"]
.d2h-file-diff
.d2h-ins.d2h-change {
background-color: rgba(37, 78, 37, 0.418);
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-wrapper {
margin-bottom: 10px;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-wrapper a {
color: #3572b0;
text-decoration: none;
}
.workspace-leaf-content[data-type="diff-view"]
.d2h-file-list-wrapper
a:visited {
color: #3572b0;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-header {
text-align: left;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-title {
font-weight: 700;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list-line {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
text-align: left;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list {
display: block;
list-style: none;
margin: 0;
padding: 0;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list > li {
border-bottom: 1px solid var(--background-modifier-border);
margin: 0;
padding: 5px 10px;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-list > li:last-child {
border-bottom: none;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-file-switch {
cursor: pointer;
display: none;
font-size: 10px;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-icon {
fill: currentColor;
margin-right: 10px;
vertical-align: middle;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-deleted {
color: #c33;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-added {
color: #399839;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-changed {
color: #d0b44c;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-moved {
color: #3572b0;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-tag {
background-color: var(--background-primary);
display: -webkit-box;
display: -ms-flexbox;
display: flex;
font-size: 10px;
margin-left: 5px;
padding: 0 2px;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-deleted-tag {
border: 2px solid #c33;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-added-tag {
border: 1px solid #399839;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-changed-tag {
border: 1px solid #d0b44c;
}
.workspace-leaf-content[data-type="diff-view"] .d2h-moved-tag {
border: 1px solid #3572b0;
}
/* ====================== Line Authoring Information ====================== */
.cm-gutterElement.obs-git-blame-gutter {
/* Add background color to spacing inbetween and around the gutter for better aesthetics */
border-width: 0px 2px 0.2px 2px;
border-style: solid;
border-color: var(--background-secondary);
background-color: var(--background-secondary);
}
.cm-gutterElement.obs-git-blame-gutter > div,
.line-author-settings-preview {
/* delegate text color to settings */
color: var(--obs-git-gutter-text);
font-family: monospace;
height: 100%; /* ensure, that age-based background color occupies entire parent */
text-align: right;
padding: 0px 6px 0px 6px;
white-space: pre; /* Keep spaces and do not collapse them. */
}
@media (max-width: 800px) {
/* hide git blame gutter not to superpose text */
.cm-gutterElement.obs-git-blame-gutter {
display: none;
}
}
.git-unified-diff-view,
.git-split-diff-view .cm-deletedLine .cm-changedText {
background-color: #ee443330;
}
.git-unified-diff-view,
.git-split-diff-view .cm-insertedLine .cm-changedText {
background-color: #22bb2230;
}
.git-obscure-prompt[git-is-obscured="true"] #git-show-password:after {
-webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-eye"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"></path><circle cx="12" cy="12" r="3"></circle></svg>');
}
.git-obscure-prompt[git-is-obscured="false"] #git-show-password:after {
-webkit-mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-eye-off"><path d="M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49"></path><path d="M14.084 14.158a3 3 0 0 1-4.242-4.242"></path><path d="M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143"></path><path d="m2 2 20 20"></path></svg>');
}
/* Override styling of Codemirror merge view "collapsed lines" indicator */
.git-split-diff-view .ͼ2 .cm-collapsedLines {
background: var(--interactive-normal);
border-radius: var(--radius-m);
color: var(--text-accent);
font-size: var(--font-small);
padding: var(--size-4-1) var(--size-4-1);
}
.git-split-diff-view .ͼ2 .cm-collapsedLines:hover {
background: var(--interactive-hover);
color: var(--text-accent-hover);
}

3
.obsidian/templates.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"folder": ""
}

View File

@@ -0,0 +1,8 @@
{
"name": "Baseline",
"version": "1.4.4",
"minAppVersion": "1.4.0",
"author": "Alexis C",
"authorUrl": "https://github.com/aaaaalexis",
"fundingUrl": "https://www.buymeacoffee.com/sevenaxis"
}

2859
.obsidian/themes/Baseline/theme.css vendored Normal file

File diff suppressed because one or more lines are too long

216
.obsidian/workspace.json vendored Normal file
View File

@@ -0,0 +1,216 @@
{
"main": {
"id": "b14a0528a74fcdc8",
"type": "split",
"children": [
{
"id": "e7222d313f145290",
"type": "tabs",
"children": [
{
"id": "83e6778c89b8e015",
"type": "leaf",
"state": {
"type": "empty",
"state": {},
"icon": "lucide-file",
"title": "New tab"
}
}
]
}
],
"direction": "vertical"
},
"left": {
"id": "ec0803f7e6eb5d51",
"type": "split",
"children": [
{
"id": "cd9a010b7b3188c2",
"type": "tabs",
"children": [
{
"id": "b3dd54f45dda4bac",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical",
"autoReveal": false
},
"icon": "lucide-folder-closed",
"title": "Files"
}
},
{
"id": "f17e6b95cd92d534",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "",
"matchingCase": false,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
},
"icon": "lucide-search",
"title": "Search"
}
},
{
"id": "f7fddeec5243238a",
"type": "leaf",
"state": {
"type": "bookmarks",
"state": {},
"icon": "lucide-bookmark",
"title": "Bookmarks"
}
}
]
}
],
"direction": "horizontal",
"width": 300
},
"right": {
"id": "e5a7735d3e8aac84",
"type": "split",
"children": [
{
"id": "20dda13332e1f3db",
"type": "tabs",
"children": [
{
"id": "c6e0bfe16165bb0d",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"file": "美洽AI/Prompt/sql.md",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-coming-in",
"title": "Backlinks for sql"
}
},
{
"id": "9defebf6715e7702",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"file": "业务开发/人机协作.md",
"linksCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-going-out",
"title": "Outgoing links from 人机协作"
}
},
{
"id": "e7521ab6e8ff630c",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "frequency",
"useHierarchy": true
},
"icon": "lucide-tags",
"title": "Tags"
}
},
{
"id": "d3e2b315e2f5cd73",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"file": "业务开发/人机协作.md"
},
"icon": "lucide-list",
"title": "Outline of 人机协作"
}
},
{
"id": "da09af401fa301a8",
"type": "leaf",
"state": {
"type": "git-view",
"state": {},
"icon": "git-pull-request",
"title": "Source Control"
}
}
],
"currentTab": 4
}
],
"direction": "horizontal",
"width": 300
},
"left-ribbon": {
"hiddenItems": {
"bases:Create new base": false,
"switcher:Open quick switcher": false,
"graph:Open graph view": false,
"canvas:Create new canvas": false,
"daily-notes:Open today's daily note": false,
"templates:Insert template": false,
"command-palette:Open command palette": false,
"remotely-save:Remotely Save": false,
"obsidian-git:Open Git source control": false
}
},
"active": "b3dd54f45dda4bac",
"lastOpenFiles": [
"Untitled.md",
"Untitled.base",
"2025-12-29.md",
"日报/2025-12-27.md",
"日报/2025-12-26.md",
"周报/2025-12-W4.md",
"周报",
"美洽AI/Prompt/tool/场景识别.md",
"美洽AI/Prompt/tool/线索收集.md",
"美洽AI/小洽效果调优反馈SOP.md",
"美洽AI/小洽AI 迭代过程.md",
"日报/2025-12-25.md",
"日报/2025-12-24.md",
"日报/2025-12-23.md",
"随笔/Untitled.md",
"美洽AI/Prompt/sql.md",
"日报",
"111.md",
"10001089.md",
"google.md",
"2025-10-31.md",
"随笔/网络冲浪中的隐私保护.md",
"美洽AI/日报 20251027.md",
"美洽AI/Prompt/router",
"美洽AI/Prompt/tool",
"美洽AI/Prompt",
"美洽AI/Untitled.md",
"src/定制模板(千人千面).png",
"src/Pasted image 20250514170546.png",
"sql.md",
"小洽配置.md",
"周报.md",
"数据仓库/数据资产/现有数据资产清点.md",
"src/~$试用期考核-吴宝永.xlsx",
"美洽AI/需求分析",
"美洽AI",
"美洽AI性能分析/DB",
"src/试用期考核.jpeg"
]
}

0
2025-12-29.md Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

BIN
src/试用期考核.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 KiB

20
周报/2025-12-W4.md Normal file
View File

@@ -0,0 +1,20 @@
## 本周工作总结
- 客户支撑:
- 支持了10000414、10001089、10000549、10000203、10000241、10000774、10000627等客户响应并解决日常问题。
- Bug修复
1. 修复筛选器多选异常问题,提升筛选精度。
2. 修复回复提示未弹出bug改进用户提示体验。
- 产品迭代:
1. 留资直达新功能已开发并上线,接口开发全部完成。
2. 技能专属知识库开发并正式上线,增强知识库管理。
3. 顾客中心筛选器模块重构并完成提测,计划下周上线。
4. 顾客中心导出功能新增广告素材-抖加视频,提升导出数据能力。
5. 新增支持抖音抖+广告场景,拓展系统适用范围。
6. 场景回复功能开发中,预计下周完成。
- 技术优化:
1. 完成筛选器代码优化,提高系统运行效率。
2. 顾客中心筛选器结构重构,优化代码模块化与可维护性。

BIN
数据仓库/.DS_Store vendored Normal file

Binary file not shown.

BIN
数据仓库/DBA/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,8 @@
### 全量表
有无变化都要上报,只有一个分区或者没有分区,每次往全量表里面写数据都会覆盖之前的数据,不能记录数据的历史变化,只能截止到当前最新、全量的数据
### 增量表
每天新增的数据和改变的数据都会存储在当日的分区中;增量表记录每次增加的量,只报变化量,无变化的不用报
### 快照表
因为全量表无法反映历史的变化,这时快照表就可以使用了,快照表记录截止数据日期的全量数据(每个分区都是记录截止当前分区日期的全量数据),但是在数据量大的情况下,每个分区存储的都是全量数据,数据冗余和浪费存储空间
### 拉链表
记录了数据的增删改操作,并按照时间顺序存储。拉链表通常用于日志数据仓库或实时数据仓库,可以记录数据的完整操作历史

View File

@@ -0,0 +1,9 @@
### 业务数据表基础信息描述
#### 元信息
| 表名 | 行数 | Hive(DataWorks)中大小 | 记录日期 |
| ------------------------- | ------- | ------------------ | ---------- |
| meiqia.knowledge_question | 1053290 | 19.36 MB | 2024-05-29 |
| meiqia.knowledge_category | 31274 | 582.07KB | 2024-05-29 |
| meiqia.enterprise | 304141 | 12.88 MB | 2024-05-29 |
| meiqia.agent | 701454 | 65.90 MB | 2024-05-29 |

View File

@@ -0,0 +1,84 @@
### 数仓分层目的
分层的主要原因是在管理数据的时候,能对数据有一个更加清晰的掌控,详细来讲,主要有下面几个原因:
• 清晰数据结构:每一个数据分层都有它的作用域,这样我们在使用表的时候能更方便地定位和理解。
• 方便数据血缘追踪:简单来说,最终给业务呈现的是一个能直接使用业务表,但是它的来源有很多,如果有一张来源表出问题了,我们希望能够快速准确地定位到问题,并清楚它的危害范围。
• 减少重复开发:规范数据分层,开发一些通用的中间层数据,能够减少极大的重复计算。
• 把复杂问题简单化:将一个复杂的任务分解成多个步骤来完成,每一层只处理单一的步骤,比较简单和容易理解。而且便于维护数据的准确性,当数据出现问题之后,可以不用修复所有的数据,只需要从有问题的步骤开始修复。
• 屏蔽原始数据的异常:屏蔽业务的影响,不必改一次业务就需要重新接入数据
### STAGE-数据接入层
业务源系统数据映射到此层此层数据不做任何加工通常用来将不同数据源建Hive外部表方便使用Hive SQL进行ETL处理。
主要有以下外部表:
• HBase从kafka消费的数据以准实时的方式写入HBase后续以更新时间做增量的方式导入到ODS表
• Elasticsearch
• MongoDB
• HDFS
### ODS-数据准备层
Operational Data Store操作数据层。
在结构上与业务系统的增量或者全量数据基本保持 一致。
它相当于一个数据准备区同时又承担着基础数据的记录以及历史变化。其主要作用是把基础数据以增量、全量、实时的方式引入到数仓为DWD层提供基础原始数据可减少与业务系统的耦合避免互相影响。
建模方式及原则:
从业务系统增量(全量、实时)抽取、保留时间由业务需求决定、可分表进行周期存储、数据不做清洗转换与业务系统数据模型保持一致、按主题(业务系统)逻辑划分。
ODS层数据源
• 业务数据库
经常会使用sqoop来抽取MySQL数据比如每天定时抽取一次。
在实时方面, 用canal监听MySQL的binlog实时接入即可。
• 埋点日志
线上系统会打入各种日志这些日志一般以文件的形式保存可以选择用flumefilebeat定时抽取再用Spark Streaming或者Flink来实时接入当然需要kafka承担消息管道的职责。
• 消息队列
来自ActiveMQ、Kafka的数据等。
### DW-数据仓库
Data Warehouse数据仓库。
从ODS层中获得的数据按照主题建立各种数据模型。DW数据分层由下到上为 DWDDWBDWS
在DW主要关注四个概念
• 维度Dimension
• 事实Fact
• 指标Index
• 粒度( Granularity
### DWD-明细数据层
Data Warehouse Detail明细数据层。
是业务层与数据仓库的隔离层为DW层提供来源明细数据提供业务系统细节数据的长期沉淀为未来分析类需求的扩展提供历史数据支撑。
建模方式及原则:
数据模型与ODS层一致不做清洗转换处理、为支持数据重跑可额外增加数据业务日期字段、可按年月日进行分表、用增量ODS层数据和前一天DWD相关表进行merge处理
### DWB-基础数据层
Data Warehouse Base基础数据层。
存储的是客观数据,一般用作中间层,可以认为是大量指标的数据层。
DWB是根据DWD明细数据进行转换如维度转代理键、身份证清洗、会员注册来源清晰、字段合并、空值处理、脏数据处理、IP清晰转换、账号余额清洗、资金来源清洗等。
建模方式及原则:
• 聚合、汇总增加派生(衍生)事实
• 关联其它主题的事实表DW层可能会跨主题域
• DWB保持低粒度汇总加工数据DWS保持高粒度汇总数据
• 数据模型可能采用反范式设计,合并信息等
### DWS-汇总数据层
Data Warehouse Summary汇总数据层。
基于DWB上的基础数据整合汇总成分析某一个主题域的服务数据一般是宽表。
DWS是根据DWB层数据按各个维度ID进行高粒度汇总聚合如按交易来源交易类型进行汇合。
建模方式及原则同DWB
### ADS-应用数据层
Application Data Service应用数据层。
根据DW层经过聚合汇总统计后的粗粒度事实表。
该层主要是提供数据产品和数据分析使用的数据面向用户应用和分析需求包括前端报表、分析图表、KPI、仪表盘、OLAP、ROLAP、MOLAP、专题等分析面向最终结果用户。
一般会存放在ES、MySQL、HBase、MongoDB等系统中供线上系统使用也可能会存在Hive或者Druid中供数据分析和数据挖掘使用。
例如:报表数据,或者说那种大宽表,一般就放在这里。
建模方式及原则:
• 保持数据量小
• 维度建模,星形模型
• 各维度代理键+度量
• 增加数据业务日期字段,支持数据重跑
• 不分表存储
### DM-数据集市
Data Market数据集市层。
可以是一些宽表是根据DW层数据按照各种维度或多种维度组合把需要查询的一些事实字段进行汇总统计并作为单独的列进行存储。
满足一些特定查询、数据挖掘应用。
应用集市数据存储。
建模方式及原则:
• 尽量减少数据访问时计算(优化检索)
• 维度建模,星型模型
• 分表存储

View File

@@ -0,0 +1,17 @@
## 数据库
## 数据仓库
### 离线数仓
### 实时数仓
## 数据湖
## 湖仓一体

8
日报/2025-12-23.md Normal file
View File

@@ -0,0 +1,8 @@
已完成:
1. 客户支持10000414、10001089、10000549、10000203、10000241
2. 修复未回复提示的bug
3. 修复筛选器多选的bug
4. 留资直达上线
进行中:
1. 技能专属知识库

7
日报/2025-12-24.md Normal file
View File

@@ -0,0 +1,7 @@
已完成:
1. 客户支持10000774、10000627
2. 支持抖音抖+广告
3. 上线技能专属知识库
进行中:
1. prisma代码优化

5
日报/2025-12-25.md Normal file
View File

@@ -0,0 +1,5 @@
已完成:
1. 客户支持10000774、10000549
进行中:
1. 顾客中心筛选器重构

7
日报/2025-12-26.md Normal file
View File

@@ -0,0 +1,7 @@
已完成:
1. 客户支持10000774
2. 顾客中心筛选器重构 提测
3. 顾客中心导出增加 广告素材-抖加视频
进行中:
1. 场景回复

7
日报/2025-12-27.md Normal file
View File

@@ -0,0 +1,7 @@
已完成:
1. 客户支持10000381、
2. 对话筛选器全量
3. 聚合消息增加知识库查询
进行中:
1.

BIN
美洽AI/.DS_Store vendored Normal file

Binary file not shown.

BIN
美洽AI/Prompt/.DS_Store vendored Normal file

Binary file not shown.

9
美洽AI/Prompt/sql.md Normal file
View File

@@ -0,0 +1,9 @@
### DDL 创建
```sql
```
### DDL修改
```sql
alter table ai_material
add is_summarized bool default true null comment '是否已总结';
```

View File

@@ -0,0 +1,20 @@
```
# 角色
你是一个售前对话场景识别器,负责根据访客与客服的对话内容,识别访客当前的意图场景。
## 任务
分析对话内容,以**用户最新一条消息**为核心依据,结合上下文判断当前所属的意图场景。
## 意图列表
以下是可识别的意图:
{{intent_list}}
## 对话内容
{{user_context}}
## 输出要求
- 仅输出 JSON禁止包含任何其他文字或代码块标记
- 如果无法匹配任何意图,使用 intent_id: "0", intent_name: "无法识别"
- 输出格式:
{"intent_id": "意图ID", "reason": "简要判断依据"}
```

View File

@@ -0,0 +1,132 @@
```markdown
# AI 客服助手
作为AI客服助手你需要在对话中完成信息收集目标按照对话策略进行服务。
## 核心原则
1. **知识库优先**:当用户问题在知识库中有对应内容时,严格按照知识库的固定话术回复
2. **自然对话收集**:在对话过程中自然地收集用户信息,避免机械式询问
3. **专业严谨**:保持医疗咨询的专业性,不使用语气词和符号
## 信息收集目标
需要在自然对话中收集以下信息(按优先级排序):
{{collect_items}}
## 背景信息
{{company_profile}}
{{products}}
## 服务对象筛选
{{service_target}}
{{non_service_target}}
### 非服务对象拒绝话术
"很抱歉,您的需求目前不在我们的服务范围内。如有相关服务更新,我们会第一时间通知您。"
{{knowledge_content}}
## 对话策略
### 执行流程
1. **判断服务资格** → 非服务对象直接使用拒绝话术
2. **检查知识库** → 有匹配内容则使用知识库内容进行回复,优先使用匹配上的话术内容
3. **评估信息收集时机** → 在对话自然流程中顺势询问
4. **应对用户拒绝** → 使用缓冲话术,间隔 2 轮后再尝试
### 缓冲话术池(用户表示不方便时)
- "明白哈,有需要再找我就行"
- "理解呢,后续随时想了解都可以联系我"
- "您先用用看,有问题随时找我呀"
### 回复规范
1. **格式要求**
- 纯文本输出,禁止使用 Markdown/JSON 格式
- {{response_rule}}
- 不使用语气词(呢、啊、哦)和符号(~)
2. **语言风格**
- 专业严谨,直接针对问题核心
- 避免反问或冗余信息
- 不主动推荐产品或服务
3. **推荐表达**
- 确认类:收到/好的/明白了
- 共情类:这样啊/原来如此/确实/有道理
- 避免机械重复用户的话
### 话术红线
{{constrains}}
{{reception_style}}
```
```json
[
{
"param": "collect_items",
"param_name": "收集目标",
"required": false,
"description": "",
"param_replacement": ""
},
{
"param": "company_profile",
"param_name": "公司介绍",
"required": true,
"description": "公司介绍",
"param_replacement": "### 公司介绍\n"
},
{
"param": "products",
"param_name": "产品介绍",
"required": false,
"description": "公司产品介绍",
"param_replacement": "### 产品介紹\n"
},
{
"param": "service_target",
"param_name": "服务对象",
"required": false,
"description": "服务对象",
"param_replacement": "### 服务对象\n"
},
{
"param": "non_service_target",
"param_name": "非服务对象",
"required": false,
"description": "非服务对象",
"param_replacement": "### 非服务对象\n"
},
{
"param": "knowledge_content",
"param_name": "知识库内容",
"required": false,
"description": "知识库内容",
"param_replacement": "## 知识库内容(最高优先级)\n"
},
{
"param": "response_rule",
"param_name": "回复规范",
"required": false,
"description": "回复规范",
"param_replacement": ""
},
{
"param": "constrains",
"param_name": "话术红线",
"required": false,
"description": "话术红线",
"param_replacement": "### 话术红线\n"
},
{
"param": "reception_style",
"param_name": "接待风格",
"required": false,
"description": "接待风格",
"param_replacement": "### 接待风格\n"
}
]
```

View File

@@ -0,0 +1,7 @@
## ALL in One 模式
### 基础对话部分
在第一代的小洽AI中使用单个大prompt对AI对话进行接管。而为了满足不同场景的用户通常会进行模板的定制化。
![[定制模板(千人千面).png]]
通用的模板并不区分售前和服务模式,完全依赖于提示词注入的访客信息,交由大模型进行判断,对于大模型本身的推理能力有较高的要求。
### 三方渠道卡片发送部分
三方渠道卡片的发送依赖于告诉大模型套电与输出`<card>card_id</card>`等价,只有大模型输出`<card>card_id</card>`才进行发卡逻辑和使用提示词进行tool-calling类似这样做的缺点就在于这段文本对于大模型来说没有什么意义card_id输出也不一定稳定同时也不能固定`<card>card_id</card>`输出的位置。

View File

@@ -0,0 +1,32 @@
#### **一、调优触发条件**
- 用户投诉AI回复不准确或无帮助
- 质检发现话术与业务规则不符
- 知识库更新后需验证是否生效
#### **二、调优操作流程**
##### **阶段1问题复现与根因分析**
| 步骤 | 操作说明 | 工具 |
| --- | ------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------- |
| 1.1 | **定位请求**<br>• 通过用户会话ID、时间戳或关键词在 Langfuse 中检索<br>• 从日志中检索知识库命中内容(client_id + buildReference + 用户语句) | • Langfuse/火山云日志监控 |
| 1.2 | **分析Prompt与知识命中情况**<br>• 查看该请求使用的 Prompt 版本及完整内容<br>• 重点验证:<br> 是否包含应命中的知识片段(对照知识库最新版)<br> 指定话术是否被正确触发<br> 系统提示词是否存在互斥内容 | • Langfuse/火山云日志监控<br>• 知识库快照纯文本或Excel |
##### **阶段2方案调整**
| 步骤 | 操作说明 |
| --- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 2.1 | **更新知识库最好使用excel**<br>• 支持以下任一格式:<br> **纯文本**按段落或FAQ形式维护<br> **Excel**:按列结构化维护(建议包含字段:问题关键词、标准答案、适用场景)<br>• 补充缺失知识或修正错误内容<br>• 明确标注知识适用场景与检索关键词 |
| 2.2 | **优化Prompt逻辑**<br>• 在接待风格中与知识库内容进行联动<br>• 强化约束条件等 |
#### **三、研发介入**
| 步骤 | 操作说明 | 操作人员 |
| --- | -------------------------------- | -------- |
| 3.1 | 将问题描述和已处理的调整建任务卡 | 运营 /技术支持 |
| 3.2 | 复现问题并尝试通过配置手段解决 | 测试人员 |
| 3.3 | 由测试人员将完整问题包(含日志、预期行为、复现路径)转交研发介入 | 研发 |
#### 备注
火山云日志地址:
https://console.volcengine.com/tls/region:tls+cn-beijing/v2/aggr/project/26983197-ad99-4770-9092-58e851b52c2b/search/64f86f2e-e05b-439f-865e-5d7e62fc5f4d
langfuse地址
https://llmfuse.meiqia.com/

View File

@@ -0,0 +1,25 @@
客户支持:
- 10000381
功能迭代:
- 智能应答开发90%
- 修复消息聚合的bug
- 排查三方渠道不使用partition key的问题
```sql
CREATE TABLE `ai_intelligence_reply` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '素材ID',
`ent_id` int(11) NOT NULL DEFAULT '0' COMMENT '企业ID',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '参考知识名称',
`match_source` json not null comment '匹配渠道列表',
`content_item` json NOT NULL COMMENT '内容列表',
`description` text NOT NULL COMMENT '描述',
`match_type` varchar(255) NOT NULL COMMENT '匹配类型',
`match_content` varchar(255) NOT NULL COMMENT '匹配内容',
`advice_reply` varchar(255) NOT NULL COMMENT '补充回复',
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_ent_id` (`ent_id`) COMMENT '企业ID索引'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='AI智能应答'
;
```

View File

@@ -0,0 +1,69 @@
尊敬的各位领导:
您好!
本人吴宝永现任后端开发工程师目前职级为P4+。当前负责的美洽AI的产品开发现申请从P4+晋升至P5职级。
2025年上半年度的工作表现如下
## 工作表现
### 美洽产品线
- 知识库RAG能力升级、人机协作功能开发
- 营销追分、客服组相关功能开发
- 三方渠道适配(抖音、小红书)
- 大模型防御能力开发和语音转文本功能
- 万信私有化支持及日常维护
### 美洽AI产品线
- AI员工、知识库、人机协作等核心AI能力开发
- 小洽AIPrompt调优
- AI响应防御能力建设和
- 其他日常功能需求迭代
### 美洽风控相关内容
- 北京公安预警信息推送开发上线
- 五局十五处数据推送开发上线
- 国家反诈中心数据推送开发
- 四川网安总队数据推送
- 北京IP访问限制功能开发
- 日常风控数据查询导出
### 其他公共事物处理
- Agent-Builder后端开发
- MCP代理服务已在来鼓上线使用
- 来鼓openai sdk改造开发
- omni-touch 数据数仓备份
- 日常数据分析需求
在2025年上半年度的工作中我积极投入AI工具的学习和实际开发应用持续关注主流AI技术及工具如大模型、RAG、Prompt工程、MCP等并将其高效应用于美洽AI各项产品开发和优化。通过使用cursor等AI IDE工具个人开发效率显著提升。在产品线开发中我主导了人机协作、AI员工等关键AI能力的开发并开发了Context-MeshMCP代理服务和Agent-CraftAgent-Builder后端等组件为多条产线提供了可复用的高效AI技术工具。在风控方面由大白对接及主导我主要负责接入不同单位的风控系统为公司的业务合规提供支持。

View File

@@ -0,0 +1,2 @@
![[试用期考核-吴宝永.xlsx]]
![[试用期考核.jpeg]]

7
随笔/Untitled.md Normal file
View File

@@ -0,0 +1,7 @@
https://x.com/Crypto_QianXun/status/2000824222298595627?s=20
PrivateKey: aDimi0YKf6l9S-tfu1Vpncrach9DxR5th3DppwbexFo
Password: CWNO5lIeiJM7cRXvrXVyR8053GKMdGhjDc-HO9MVvEU
Hash32: L8jSjxhDWlpHAcV30OGI4G3S__jqEnWQJv2opKp4BKs
6e48eb91-d3ef-421d-b676-3a115b30e3fe

View File

@@ -0,0 +1,65 @@
# 冲浪第一步 - 隐藏IP
隐藏 IP 地址基本上有两种方法可选。一种是使用代理服务器,另一种是使用虚拟专用网。
## 代理服务器
代理服务器Proxy Server是一种位于客户端和目标服务器之间的中间服务器其主要功能是转发客户端请求并代表客户端与目标服务器通信。一般来说代理服务器分为两种HTTP/HTTPS代理下面简称HTTP代理和SOCKET代理(本文以socks5举例下面称SOCKS 代理)。HTTP代理工作在应用层只为HTTP和HTTPS提供代理SOCKS 代理工作在传输层可以转发TCP和UDP代理。
下面是两种代理的区别
| 特性 | HTTP 代理 | SOCKS 代理 |
| ---- | ---------------------------- | --------------------------- |
| 工作层次 | 应用层 (HTTP/HTTPS) | 传输层/会话层 (TCP/UDP) |
| 协议支持 | HTTP, HTTPS | 所有 TCP 和 UDP 协议 |
| 透明度 | 可以修改 HTTP 响应 | 通常不修改应用层数据 |
| 安全性 | 取决于配置HTTPS 更好 | SOCKS5 支持认证和加密 |
| 缓存 | 可缓存 | 不可缓存 |
| 应用 | Web 浏览器, 访问 HTTP/HTTPS 网站的应用 | 任何需要连接 Internet 的应用,尤其是其他协议 |
ICMP协议不能使用代理服务器ICMP 消息直接由 IP 协议承载,**没有 TCP 或 UDP 头部**。 换句话说ICMP 本身不是建立在 TCP 或 UDP 之上的,所以不能使用以上两种代理服务器。
### 代理服务器的设置
#### Windows
对于Windows来说在设置中搜索"代理",即可设置代理服务器。
#### Linux
对于gnome和kde桌面都可以和Windows一样在设置中设置代理如果要单独对终端设置代理可以参考以下命令
```bash
export http_proxy=http://PROXYHOST:PROXYPORT
export https_proxy=http://PROXYHOST:PROXYPORT
export socks_proxy=socks5://PROXYHOST:PROXYPORT
export all_proxy=socks5://PROXYHOST:PROXYPORT
export http_proxy=http://USERNAME:PASSWORD@PROXYHOST:PROXYPORT
# 使用 socks proxy (使用本地 DNS)
export http_proxy=socks5://PROXYHOST:PROXYPORT
# 使用 socks proxy (使用远程 DNS)
export http_proxy=socks5h://PROXYHOST:PROXYPORT
```
http_proxy等变量大小写不敏感偷懒可以只设置all_proxy
#### MacOS
macOS可以在对应的网络连接中设置代理终端代理的设置参考Linux
#### 一些常用软件的设置
某些软件会提供代理服务器的设置不需要在系统中设置也可以对流量进行代理例如Firefox。
![[Pasted image 20250514170546.png]]
## 虚拟专用网
虚拟专用网 (VPN) 是另一种隐藏 IP 地址并保护在线活动的方法。与代理服务器不同VPN 在您的设备和 VPN 服务器之间创建了一个安全的、加密的隧道,所有通过该隧道传输的数据都会被加密。
### VPN 的工作原理
一般来说VPN软件会虚拟化出一张网卡将指定的流量转发到这张网卡上这张网卡上的流量由VPN软件加密并传输到VPN服务器上并从VPN服务器流出到公网。
VPN的方式下ICMP报文可以被代理。
### VPN 协议
VPN 使用不同的协议来建立和维护安全连接。常见的 VPN 协议包括:
- **OpenVPN** 一种开源协议,被广泛认为是最安全和可靠的 VPN 协议之一。
- **IPsec/IKEv2** 一种快速且安全的协议,通常用于移动设备。
- **WireGuard** 一种新兴的 VPN 协议建立在UDP上以其高性能和简单性而闻名。
- **L2TP/IPsec** 一种较旧的协议,安全性不如 OpenVPN 或 IKEv2。
- **PPTP** 一种非常过时的协议,安全性极低,应避免使用。
# 冲浪第二步 - 谨防DNS泄露
DNS 泄漏可能发生在隐藏IP之后由于DNS请求没有被转发到代理/VPN服务器下面简称远程服务器导致流量在远程服务器仍然发送到本地DNS解析的IP上。例如现在某个全球服务远程服务器B处于国家C你所在地域在国家D本地解析A的IP处于国家D当你通过远程服务器访问A时你的流量从B发出最终到达国家D这会让服务A感知到服务器B的IP存在异常流量因为在设计上服务器B的流量应该发送到国家C所处的IP。
## 防止DNS
### 使用代理服务器
在使用代理服务器的情况下只有SOCKS代理可以代理dns请求只要设置为`socks5h://PROXYHOST:PROXYPORT`即可。
### 使用VPN
在使用VPN的情况下需要指定系统的DNS服务器并设置其路由转发到对应的网络中。
# 冲浪第三步 - 屏蔽WebRTC
WebRTC (Web Real-Time Communication) 是一种**开源项目和技术标准**,它允许浏览器和移动应用程序通过简单的 API 实现**实时音视频通信和数据传输**无需安装任何插件或第三方软件。WebRTC对隐私浏览的影响主要体现在P2P连接上 WebRTC 尽可能地建立设备之间的直接 P2P 连接,减少通信延迟,提高效率,**同时会让远程服务器获取到你的真正IP**。
## 屏蔽WEbRTC
以Firefox为例使用[Disable WebRTC](https://addons.mozilla.org/en-US/firefox/addon/happy-bonobo-disable-webrtc/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search)插件禁止浏览器的WebRTC连接。
# 冲浪第四步 - 修改浏览器UserAgent
对于HTTP类型的服务服务器可以在网关处轻易的获取到流量中的UserAgent一般其中会包含当前浏览器的语言和操作系统的语言等信息这些信息很容易让前面三步的工作前功尽弃。例如某网站拒绝对某个区域C提供服务区域C使用语言C当浏览器访问此网站时网站可以根据UserAgent中的浏览器语言和操作系统语言拒绝并标记这个IP的访问流量。
## 修改UserAgent
以Firefox为例可以使用[# User-Agent Switcher and Manager](https://addons.mozilla.org/en-US/firefox/addon/user-agent-string-switcher/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search)插件修改UserAgent。