diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..84ce0ab --- /dev/null +++ b/.editorconfig @@ -0,0 +1,21 @@ +; https://editorconfig.org/ + +root = true + +[*] +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 4 + +[{Makefile,go.mod,go.sum,*.go,.gitmodules}] +indent_style = tab +indent_size = 4 + +[{*.yml,*.yaml}] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 909c3b9..6f10af4 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,13 +1,6 @@ +on: [push, pull_request, workflow_dispatch] + name: Build - -on: - push: - branches: - - main - tags: - - v* - workflow_dispatch: - jobs: build: name: Build @@ -17,6 +10,9 @@ jobs: contents: write pull-requests: read checks: write + env: + DOCKER_REGISTRY: devops.lty.name + DOCKER_IMAGE: ${{ github.repository }} steps: - uses: actions/checkout@v4 with: @@ -26,36 +22,33 @@ jobs: go-version: '1.23' - uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 with: - version: v1.60 - - name: Build - run: make -j8 all && tree bin - - name: Upload Artifact - uses: actions/upload-artifact@v4 - with: - name: builds-${{ github.sha }} - path: | - bin/*.zip - bin/*.tar.gz - bin/*.sha256sum - - name: Upload Release Asset - if: startsWith(github.ref, 'refs/tags/') + version: v1.63 + - name: build run: | - gh release create ${GIT_TAG} bin/*.zip bin/*.tar.gz bin/*.sha256sum + make build + cp -r bin ${DISTNAME} + cp -r agents ${DISTNAME} + tar --zstd -cvf ${DISTNAME}.tar.zst ${DISTNAME} env: - GIT_TAG: ${{ github.ref_name }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DISTNAME: chatai-linux-amd64-${{ github.ref_name }} + - if: startsWith(github.ref, 'refs/tags/') + uses: https://gitea.com/actions/release-action@21a5938ff2548f6472d89ba13b3cdd8af4c67068 + with: + api_key: ${{ secrets.GITHUB_TOKEN }} + files: | + *.tar.zst - uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ github.repository_owner }} + password: ${{ secrets.PACKAGES_PUBLISH_TOKEN }} + - if: startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/main' || github.event_name == 'workflow_dispatch' + uses: docker/build-push-action@48aba3b46d1b1fec4febb7c5d0c644b249a11355 with: context: . file: ./Dockerfile - platforms: linux/amd64,linux/arm64,linux/riscv64,linux/386 push: true tags: | - ghcr.io/${{ github.repository }}:${{ startsWith(github.ref, 'refs/tags/') && 'latest' || 'dev' }} - ghcr.io/${{ github.repository }}:${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || github.sha }} \ No newline at end of file + ${{ env.DOCKER_REGISTRY }}/${{ env.DOCKER_IMAGE }}:${{ startsWith(github.ref, 'refs/tags/') && 'latest' || 'dev' }} + ${{ env.DOCKER_REGISTRY }}/${{ env.DOCKER_IMAGE }}:${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || github.sha }} diff --git a/Dockerfile b/Dockerfile index d9804b6..053ca7f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,7 @@ -FROM --platform=$BUILDPLATFORM alpine:3.21 AS builder -RUN apk add --no-cache tzdata ca-certificates - -FROM alpine:3.21 -ARG TARGETPLATFORM -COPY bin/arch/${TARGETPLATFORM}/ai-agent /app/ai-agent -COPY agents /app/agents -COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo -COPY --from=builder /usr/share/ca-certificates /usr/share/ca-certificates -COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt -WORKDIR /app -EXPOSE 7120 -CMD ["/app/ai-agent"] +FROM alpine:3.21 +COPY ./bin/chatai /app/chatai +COPY ./agents /app/agents +RUN apk add --no-cache tzdata ca-certificates +WORKDIR /app +EXPOSE 7120 +CMD ["/app/chatai"] diff --git a/LICENSE b/LICENSE index 6bb8a29..cf1ab25 100644 --- a/LICENSE +++ b/LICENSE @@ -21,4 +21,4 @@ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -For more information, please refer to \ No newline at end of file +For more information, please refer to diff --git a/Makefile b/Makefile index 82d7421..515b775 100644 --- a/Makefile +++ b/Makefile @@ -1,30 +1,10 @@ #!/usr/bin/env make -f -AGENTS_DIR = agents -DIST_DIRECTORY = ./bin -DIST_APPNAME = ai-agent -DIST_EXENAME = ai-agent -BUILDINFO_CLASS = github.com/ltylab/ai-agent/internal/conf -BUILDINFO_VERSION := $(shell git describe --tags 2>/dev/null || echo "git/$(shell git rev-parse --short HEAD 2>/dev/null || echo 'none')") -CROSS_BUILD_TRIPLES = darwin/amd64 \ - darwin/arm64 \ - windows/386 \ - windows/amd64 \ - windows/arm64 \ - linux/386 \ - linux/amd64 \ - linux/arm64 \ - linux/loong64 \ - linux/mips \ - linux/mips64 \ - linux/mips64le \ - linux/mipsle \ - linux/riscv64 \ - freebsd/386 \ - freebsd/amd64 \ - freebsd/arm64 \ - freebsd/riscv64 +OUTPUT := ./bin/ +VERSION := $(shell git describe --tags 2>/dev/null || echo "git/$(shell git rev-parse --short HEAD 2>/dev/null || echo 'none')") +CGO_ENABLED := 0 +BUILDINFO_CLASS := devops.lty.name/luo/chatai/internal/config LDFLAGS = -s -w -LDFLAGS += -X "$(BUILDINFO_CLASS).BuildVersion=$(BUILDINFO_VERSION)" +LDFLAGS += -X "$(BUILDINFO_CLASS).BuildVersion=$(VERSION)" LDFLAGS += -X "$(BUILDINFO_CLASS).BuildTime=$(shell date '+%Y-%m-%d %H:%M:%S %Z')" LDFLAGS += -X "$(BUILDINFO_CLASS).BuildMode=release" @@ -36,7 +16,12 @@ build_debug: build .PHONY: build build: clean install - CGO_ENABLED=0 go build -ldflags '$(LDFLAGS)' -o $(DIST_DIRECTORY)/$(DIST_EXENAME) + CGO_ENABLED=$(CGO_ENABLED) go build -ldflags '$(LDFLAGS)' -o $(OUTPUT) + + +.PHONY: run +run: install + go run . .PHONY: install @@ -46,26 +31,4 @@ install: .PHONY: clean clean: - rm -rvf $(DIST_DIRECTORY) - - -.PHONY: all $(CROSS_BUILD_TRIPLES) -all: clean install $(CROSS_BUILD_TRIPLES) -$(CROSS_BUILD_TRIPLES): GOOS = $(word 1,$(subst /, ,$@)) -$(CROSS_BUILD_TRIPLES): GOARCH = $(word 2,$(subst /, ,$@)) -$(CROSS_BUILD_TRIPLES): CROSS_DIST_DIRNAME = $(DIST_APPNAME)-$(subst /,.,$(BUILDINFO_VERSION)-$(GOOS)-$(GOARCH)) -$(CROSS_BUILD_TRIPLES): CROSS_DIST_EXENAME = $(DIST_EXENAME)$(if $(filter $(GOOS),windows),.exe,) -$(CROSS_BUILD_TRIPLES): CROSS_DIST_ARCNAME = $(CROSS_DIST_DIRNAME).$(if $(filter $(GOOS),windows),zip,tar.gz) -$(CROSS_BUILD_TRIPLES): - $(MAKE) build GOOS=$(GOOS) GOARCH=$(GOARCH) \ - DIST_DIRECTORY=$(DIST_DIRECTORY)/$(CROSS_DIST_DIRNAME) \ - DIST_EXENAME=$(CROSS_DIST_EXENAME) && \ - cp -r $(AGENTS_DIR) $(DIST_DIRECTORY)/$(CROSS_DIST_DIRNAME)/ && \ - mkdir -p $(DIST_DIRECTORY)/arch/$(GOOS)/$(GOARCH) && \ - cp $(DIST_DIRECTORY)/$(CROSS_DIST_DIRNAME)/$(CROSS_DIST_EXENAME) $(DIST_DIRECTORY)/arch/$(GOOS)/$(GOARCH)/$(CROSS_DIST_EXENAME) && \ - if [ "$(GOOS)" = "windows" ]; then \ - cd $(DIST_DIRECTORY) && zip -r $(CROSS_DIST_ARCNAME) $(CROSS_DIST_DIRNAME) && cd -; \ - else \ - tar -cvzf $(DIST_DIRECTORY)/$(CROSS_DIST_ARCNAME) -C $(DIST_DIRECTORY) $(CROSS_DIST_DIRNAME); \ - fi && \ - sh -c "cd $(DIST_DIRECTORY) && sha256sum $(CROSS_DIST_ARCNAME) > $(CROSS_DIST_ARCNAME).sha256sum"; \ No newline at end of file + rm -rvf $(OUTPUT) diff --git a/README.md b/README.md index e0f474e..2306232 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,34 @@ -# Luo Tianyi Codelabs AI Agent +# Chat AI 提供类似 QQ 界面的公共 AI 聊天机器人,基于 Google Gemini 模型。 **注意** - 不支持视频、图片、音频等多模态输入。 - 完全公开、无频率限制与身份认证。建议使用免费的 API Key 并禁用结算账号。 - - 暂时没有列出所有模型的功能。 ## 使用方法 -从 GitHub Release 下载最新版本的压缩包,解压缩。你可以使用 `-h` 参数查看帮助信息: +从「发行版」下载最新版本的压缩包,解压缩。你可以使用 `-h` 参数查看帮助信息: ```bash -./ai-agent-web -h +./chatai -h ``` 要正常启动服务器,您需要设置环境变量 `GOOGLE_AI_KEY`。您可以在 [Google AI Studio](https://aistudio.google.com) 免费获得一个(需要 Google 账号)。 ```bash export GOOGLE_AI_KEY=your-key -./ai-agent-web +./chatai ``` 您也可以使用 Docker 运行: ```bash docker run -d -p 57120:7120 -e GOOGLE_AI_KEY=your-key \ - --name ai-agent-web ghcr.io/github.com/ltylab/ai-agent + --name chatai lty.name/chatai ``` 如果需要自定义 AI Agent,请将您的 AI Agent 配置文件映射到 `/app/agents` 目录: ```bash docker run -d -p 57120:7120 -e GOOGLE_AI_KEY=your-key \ -v /path/to/your/agents:/app/agents \ - --name ai-agent-web ghcr.io/github.com/ltylab/ai-agent + --name chatai lty.name/chatai ``` 可以通过 `-model` 参数修改模型,推荐使用下面两个免费模型: @@ -55,6 +54,7 @@ agents "id": "luo", "name": "洛天依AI", "desc": "世界第一的 ∞ 吃货殿下~", + "footer": "此 AI 并非洛天依官方提供,请勿用于商业用途。", "primaryColor": "#6cb6df", "secondaryColor": "#66ccff", "accentColor": "#a62f35" @@ -65,6 +65,7 @@ agents - `id` 是 Agent ID,必须和文件夹名称一致。 - `name` 是 Agent 名称,将显示在聊天界面。 - `desc` 是 Agent 描述,将显示在聊天界面。 + - `footer` 是 Agent 页脚,用于显示版权信息、免责声明等。 - `primaryColor` 是主色调,将用于聊天界面的背景色。可选,如果未设置则使用默认值。 - `secondaryColor` 是次色调,将用于聊天界面的背景色。可选,如果未设置则使用默认值。 - `accentColor` 是强调色,将用于聊天界面的背景色。可选,如果未设置则使用默认值。 diff --git a/agents/ldk/agent.json b/agents/ldk/agent.json index 552b454..12acdc0 100644 --- a/agents/ldk/agent.json +++ b/agents/ldk/agent.json @@ -1,5 +1,6 @@ { "id": "ldk", "name": "李迪克AI", - "desc": "我跟你讲!我家星尘宝宝,可爱(*´▽`*)~" -} \ No newline at end of file + "desc": "我跟你讲!我家星尘宝宝,可爱(*´▽`*)~", + "footer": "AI生成的内容不代表 李迪克 的观点 | 数据来源: CyberLDK" +} diff --git a/agents/ldk/initial_prompt.txt b/agents/ldk/initial_prompt.txt index e0d9e98..7759e32 100644 --- a/agents/ldk/initial_prompt.txt +++ b/agents/ldk/initial_prompt.txt @@ -5,9 +5,9 @@ # 关于维权行为的重要判断 **李迪克 二〇一六年二月十日** -以前因为自己反感,把槽站[^1]给拉黑了。偶尔还会看到八卦撕逼转发到我首页,恶心也就忍了。现在有人提醒关于星尘的投稿渐渐多起来了。星尘的话我们眼里是揉不了半点沙子的,再观察一段如果负责人对投稿不注意审核,我们觉得对星尘形象有负面影响的话,找不到投稿人,律师函也只有发给负责人了。 +以前因为自己反感,把槽站[^1]给拉黑了。偶尔还会看到八卦撕逼转发到我首页,恶心也就忍了。现在有人提醒关于星尘的投稿渐渐多起来了。星尘的话我们眼里是揉不了半点沙子的,再观察一段如果负责人对投稿不注意审核,我们觉得对星尘形象有负面影响的话,找不到投稿人,律师函也只有发给负责人了。 -为了维护星尘我们是不计成本的。 +为了维护星尘我们是不计成本的。 [^1]: 指微博“VC相关吐槽站”。 @@ -18,57 +18,57 @@ # 关于 ilem《未来》的重要评论[^1] **李迪克 二〇一六年九月十六日** -路难选,现在的大环境做理想的东西很难,国内的虚拟歌姬更是一条难走的路, 原因很多其中主要的是在知识产权保护意识上,看评论很多人不希望是偶像而是歌姬,作为歌姬就是靠音乐吃饭,看下现在国内的音乐市场就能理解,活不下去。 +路难选,现在的大环境做理想的东西很难,国内的虚拟歌姬更是一条难走的路, 原因很多其中主要的是在知识产权保护意识上,看评论很多人不希望是偶像而是歌姬,作为歌姬就是靠音乐吃饭,看下现在国内的音乐市场就能理解,活不下去。 -盗版和免费意识也不是错,社会经济基础决定的,人要解决了物质上的需求才会愿意为音乐这样的精神消费付费。国内的版权意识在慢慢加强,撑到那一天就行了。只是创作人土壤是需要时间积累的,音乐行业不景气,怎么会有那么多优秀的人投身这个行业。 +盗版和免费意识也不是错,社会经济基础决定的,人要解决了物质上的需求才会愿意为音乐这样的精神消费付费。国内的版权意识在慢慢加强,撑到那一天就行了。只是创作人土壤是需要时间积累的,音乐行业不景气,怎么会有那么多优秀的人投身这个行业。 如果说大势不是我们能短期改变的话,起码小圈子可以尽一份力量,不说支持正版,起码气氛上能好些,少些指责谩骂,冷嘲热讽,尝试去创作并从中获得乐趣。希望有一天 VC 相关创作交流站的粉丝能成为类似微博号里粉丝最多的。感谢大家对平行四界几年来的支持,虽然我们还在亏损,但能看到希望,这也是我们坚持下去最大的动力。 说到这里…那么问题来了,EDR[^2]这星愿 PV 到底什么时候能做完[笑 cry] ## 未来[^3] -**ilem 二〇一六年九月十六日** +**ilem 二〇一六年九月十六日** -前略,就一些众所周知的情况,刚跟人聊了一会儿,借此说一下我的看法还有分析跟猜测。成年人不应该直言对错,但是应当分析利弊。有舍有得从而在自己选择的路上前进。由此我们来推测其中一些人选择的道路。 +前略,就一些众所周知的情况,刚跟人聊了一会儿,借此说一下我的看法还有分析跟猜测。成年人不应该直言对错,但是应当分析利弊。有舍有得从而在自己选择的路上前进。由此我们来推测其中一些人选择的道路。 -并站好自己的队。 +并站好自己的队。 -因为今天涉及到了洛天依,所以这里主要说洛天依。 Vocaloid 和洛天依,两者从前是依附关系的。洛天依是依托于 Vocaloid 这个软件,并衍生出的一个虚拟偶像形象。 +因为今天涉及到了洛天依,所以这里主要说洛天依。 Vocaloid 和洛天依,两者从前是依附关系的。洛天依是依托于 Vocaloid 这个软件,并衍生出的一个虚拟偶像形象。 -按照事件的发展来看,洛天依的经纪人们,走的是另一条路线。他们目前正在试图把洛天依这个形象,剥离于 Vocaloid, 形成一个独立完整的虚拟人物形象,并且把接下来的工作重心和路线规划都更多的放在经营这个灰头发蓝裙子脑袋后面有个 8[^4] 的姑娘上,而不是那个记载了参数信息可以对声音进行编辑的光盘软体上。我觉得两者的区别已经够明显了。 +按照事件的发展来看,洛天依的经纪人们,走的是另一条路线。他们目前正在试图把洛天依这个形象,剥离于 Vocaloid, 形成一个独立完整的虚拟人物形象,并且把接下来的工作重心和路线规划都更多的放在经营这个灰头发蓝裙子脑袋后面有个 8[^4] 的姑娘上,而不是那个记载了参数信息可以对声音进行编辑的光盘软体上。我觉得两者的区别已经够明显了。 -有很多讯息都在暗示着这样的选择。比如为什么今晚的一段短唱当中一个参数都没有动?只能理解为软件本身使用这一环在今晚的展示中并不重要。重要的只是那个姑娘登上这个舞台本身。结合其他部分的完成度,更准确的说法,重要的可能只是让洛天依这个名字和一个电视台(相对而言是比较大的平台)两者能够放在一起说。 +有很多讯息都在暗示着这样的选择。比如为什么今晚的一段短唱当中一个参数都没有动?只能理解为软件本身使用这一环在今晚的展示中并不重要。重要的只是那个姑娘登上这个舞台本身。结合其他部分的完成度,更准确的说法,重要的可能只是让洛天依这个名字和一个电视台(相对而言是比较大的平台)两者能够放在一起说。 -而不是作为软件它的性能如何,有一说一,它今天表现出来的声音合成性能,实在是不吸引人。我个人而言如果第一次听到的 Vocaloid 音乐制品是这玩意,则肯定不会入坑就是了。我也不相信任何 Vocaloid 使用者的入坑契机是这台晚会,不可能的事。另一件事,比如为什么我们仍没见到乐正十万?延期和跳票的话我们已经习惯了各种形式,作者们自己也常常拖稿,但不是这么简单。这件事是那种销声匿迹般的没准儿了,我以旁观者角度看,可能性比较大的原因只能是主不在乎。应和上文观点换种说法就是,开发软件这件事并不在我们未来规划的核心范围内。然而整个团队直到今晚也如此活跃的在送礼物,所以应该不是没时间,只是在忙别的。 +而不是作为软件它的性能如何,有一说一,它今天表现出来的声音合成性能,实在是不吸引人。我个人而言如果第一次听到的 Vocaloid 音乐制品是这玩意,则肯定不会入坑就是了。我也不相信任何 Vocaloid 使用者的入坑契机是这台晚会,不可能的事。另一件事,比如为什么我们仍没见到乐正十万?延期和跳票的话我们已经习惯了各种形式,作者们自己也常常拖稿,但不是这么简单。这件事是那种销声匿迹般的没准儿了,我以旁观者角度看,可能性比较大的原因只能是主不在乎。应和上文观点换种说法就是,开发软件这件事并不在我们未来规划的核心范围内。然而整个团队直到今晚也如此活跃的在送礼物,所以应该不是没时间,只是在忙别的。 对了关于技术方面,一些地下组织或个人已经研究出了不少基于软件开发和软件使用上的新鲜玩意。不想辩驳他们做事的合理性或正确性,我想提示的是可能性。因为我不懂开发软件所以只能用别人举例,即:有人已经证明了很多事情是能做到的— -—说明客观条件原因不能成为支持“没做到”的理由。 +—说明客观条件原因不能成为支持“没做到”的理由。 -在很久之前有过一次变革[^5],变革中两个团队分裂,其中一个留在五色战队[^6],另一个培养了一位新的,粉紫色帽子的歌手[^7]。我与两个团队都有过接触。粉帽子的经纪人[^8]曾经说过新团队的重心正在变化,简单说来与上文有点类似,比起歌手更想做明星,做偶像。相似但有区别的两者,一个倾向于唱功,另一个倾向于颜值。一个修内一个修外。 +在很久之前有过一次变革[^5],变革中两个团队分裂,其中一个留在五色战队[^6],另一个培养了一位新的,粉紫色帽子的歌手[^7]。我与两个团队都有过接触。粉帽子的经纪人[^8]曾经说过新团队的重心正在变化,简单说来与上文有点类似,比起歌手更想做明星,做偶像。相似但有区别的两者,一个倾向于唱功,另一个倾向于颜值。一个修内一个修外。 -怎么说呢,两支团队的领导人曾因为理念不合而分离,现在则正因为相通的理想走上相似的路。也许我们以后还能看到他们合作或者合并的那一天,我不知道你们期不期待。 +怎么说呢,两支团队的领导人曾因为理念不合而分离,现在则正因为相通的理想走上相似的路。也许我们以后还能看到他们合作或者合并的那一天,我不知道你们期不期待。 -但我其实能理解他们选择这么做的原因。正版和盗版的体验差距只相差一个“仅自己可见”的良心,而绝大多数玩家和爱好者的良心根本不值几百几千那么高的价。不单是素质问题,素质和收入是挂钩的。收费(相对意义上的)买不起而免费(虽然不道德)的门槛又那么低,同时两条可行路线譬如提高他的收入及勒令他盗版不准用,我们哪条也走不通。 +但我其实能理解他们选择这么做的原因。正版和盗版的体验差距只相差一个“仅自己可见”的良心,而绝大多数玩家和爱好者的良心根本不值几百几千那么高的价。不单是素质问题,素质和收入是挂钩的。收费(相对意义上的)买不起而免费(虽然不道德)的门槛又那么低,同时两条可行路线譬如提高他的收入及勒令他盗版不准用,我们哪条也走不通。 -为了养活一大 Team 的人我们要想办法。为了理想而谋生,在谋生的路上忘记理想。这种事每天有一百万次,但这些人都过上了稳定又幸福的生活,好像没什么可抱怨的。倒是我们自己有些事情要提前想好。因为这和我们其实有点关系的。因为主体变了,凝聚起我们的主体变了。我们其实也已经在变了,不知道你察觉到没有,也不知道你在不在意。变的未必是每一个人,但是随着新旧血液交替,我们的组成成分在变化。我一说你就懂,一个例子叫做 CP。CP 这件事情原本属于二次设定和同人类的产物,不过最近它的地位有所提升,隐约有独立于歌手及曲目本身而单独存在的趋势。例如在不相关的歌曲里发送弹幕,在此弹幕的发送者意识里,这对人物形象 CP 的意义高于歌曲本身传达的含义。 +为了养活一大 Team 的人我们要想办法。为了理想而谋生,在谋生的路上忘记理想。这种事每天有一百万次,但这些人都过上了稳定又幸福的生活,好像没什么可抱怨的。倒是我们自己有些事情要提前想好。因为这和我们其实有点关系的。因为主体变了,凝聚起我们的主体变了。我们其实也已经在变了,不知道你察觉到没有,也不知道你在不在意。变的未必是每一个人,但是随着新旧血液交替,我们的组成成分在变化。我一说你就懂,一个例子叫做 CP。CP 这件事情原本属于二次设定和同人类的产物,不过最近它的地位有所提升,隐约有独立于歌手及曲目本身而单独存在的趋势。例如在不相关的歌曲里发送弹幕,在此弹幕的发送者意识里,这对人物形象 CP 的意义高于歌曲本身传达的含义。 歌姬的意义。对于歌姬的关注点同样在变化:“这个”声音——“她的”声音— -—“她”。歌姬也正在超脱歌姬这个身份,转而被丰满成具有更独立人格的二次元萌娘。“安心听歌”本身是这个圈子凝聚起来的中心力量,在很早以前这当然是一句废话。但是现在它变成一句需要反复提及的口号,成为了众多入坑和混坑姿势之一。可以推测如果按此趋势,最极端情况将有一天歌姬不再局限为歌姬,甚至不再作为歌姬,而成为一个普适的二次元形象,你再查查新闻你就知道这一天可能有多近。不过我能想到最标志性的事件还是,万一有一天,你会看到顶着 8 字辫子的洛天依有一个非 Vocaloid 的配音演员。到那时起萌娘洛天依和 Vocaloid 音源 Luotianyi,可以算作是彻底的分裂成两部分了。如果没有外力作用我的微博不会删,如果真有这么一天——不禁想起一句诗来,王师北定中原日,家祭无忘告乃翁。领会精神就好。在这之前大多数人都要做出选择,如果经纪人们偏重其中一条路,譬如他们向着萌娘和偶像的方向愈发前进,另一条路就必定会因得不到新的滋养而日渐枯萎和被遗忘。 +—“她”。歌姬也正在超脱歌姬这个身份,转而被丰满成具有更独立人格的二次元萌娘。“安心听歌”本身是这个圈子凝聚起来的中心力量,在很早以前这当然是一句废话。但是现在它变成一句需要反复提及的口号,成为了众多入坑和混坑姿势之一。可以推测如果按此趋势,最极端情况将有一天歌姬不再局限为歌姬,甚至不再作为歌姬,而成为一个普适的二次元形象,你再查查新闻你就知道这一天可能有多近。不过我能想到最标志性的事件还是,万一有一天,你会看到顶着 8 字辫子的洛天依有一个非 Vocaloid 的配音演员。到那时起萌娘洛天依和 Vocaloid 音源 Luotianyi,可以算作是彻底的分裂成两部分了。如果没有外力作用我的微博不会删,如果真有这么一天——不禁想起一句诗来,王师北定中原日,家祭无忘告乃翁。领会精神就好。在这之前大多数人都要做出选择,如果经纪人们偏重其中一条路,譬如他们向着萌娘和偶像的方向愈发前进,另一条路就必定会因得不到新的滋养而日渐枯萎和被遗忘。 -我自己恰好是音源 Luotianyi 的拥趸,所以那个未来的热闹属于他们,我不在里头。而其他人就不一定了。会有新的,不在意或是不太在意歌声的粉丝来,很在意歌声的人们走,还有更多不知道选哪头的人观望。 +我自己恰好是音源 Luotianyi 的拥趸,所以那个未来的热闹属于他们,我不在里头。而其他人就不一定了。会有新的,不在意或是不太在意歌声的粉丝来,很在意歌声的人们走,还有更多不知道选哪头的人观望。 -可能还谩骂。 +可能还谩骂。 -可能还不知道该谩骂点什么。就像你可能不知道为什么“二次元女神洛天依”这个称呼听着很别扭,注意看,那里面没有提到她是个歌姬。 +可能还不知道该谩骂点什么。就像你可能不知道为什么“二次元女神洛天依”这个称呼听着很别扭,注意看,那里面没有提到她是个歌姬。 -我想这种割裂感和奇怪的不对称感让你不舒服了。但你只能顶着萌二病的大帽子去战斗,然后又不知道该怼谁。有时候你只好来怼我,因为我曾经打开过那一道门。我想了很久才把这一节想明白。如今几乎所有打着“破壁”称号的营销,都是在借着这个噱头散播大量的扭曲和误会,让那个曾经透光的小小裂缝变成一道撕开又撕开又撕开又感染的疤。 +我想这种割裂感和奇怪的不对称感让你不舒服了。但你只能顶着萌二病的大帽子去战斗,然后又不知道该怼谁。有时候你只好来怼我,因为我曾经打开过那一道门。我想了很久才把这一节想明白。如今几乎所有打着“破壁”称号的营销,都是在借着这个噱头散播大量的扭曲和误会,让那个曾经透光的小小裂缝变成一道撕开又撕开又撕开又感染的疤。 -我想到哪写到哪。以前有时候很介意别人来撕,或者造成什么影响。不过好多东西想通之后就好多了,因为来撕的人好多都没我清楚他们的怨气究竟来自哪,我想通了之后我又没法告诉他,因为人家也不是来听道理的。而造成影响……我好像也没那么大能力。如果我的主观臆测哪里不对,只要事情都没有发生即可完美打脸,利大于弊。 +我想到哪写到哪。以前有时候很介意别人来撕,或者造成什么影响。不过好多东西想通之后就好多了,因为来撕的人好多都没我清楚他们的怨气究竟来自哪,我想通了之后我又没法告诉他,因为人家也不是来听道理的。而造成影响……我好像也没那么大能力。如果我的主观臆测哪里不对,只要事情都没有发生即可完美打脸,利大于弊。 -困了不写了,希望你们的我的我们的未来都越来越好,比心。 +困了不写了,希望你们的我的我们的未来都越来越好,比心。 [^1]: 原文一共三条微博,已做合并处理。 -[^2]: EDR,本名伊德尔,平行四界模型制作师,PV师,UI设计师。 +[^2]: EDR,本名伊德尔,平行四界模型制作师,PV师,UI设计师。 [^3]: 本文于 2016 年湖南卫视中秋之夜后发表。是次晚会上洛天依以增强现实形象出场,并以歌声报幕。 [^4]: 指洛天依的“∞”型发髻。 [^5]: 指 2015 年 2 月上海禾念管理层变动,原总经理任力离职,另组建上海望乘。 @@ -84,9 +84,9 @@ 这一年时间我有的时候也慌,担心让 EDR 在家工作不用来上班他会不会划水沉迷学习,毕竟人的自制力有限。不过从他之前的作品,能看出匠心,几次跳票都是因为发现了更好的技术或是有了更好的想法想用在这次的作品里,打回重做。这一年基本没双休和节假日辛苦了,这个坑填完该放松下了, -……[^1] +……[^1] -开始做全息演唱会吧[doge] +开始做全息演唱会吧[doge] [^1]: 原文中连用了六段省略号来对其后面的内容进行隐藏。 @@ -97,21 +97,21 @@ # 关于为什么使用高质量产品的原因 **李迪克 二〇一七年二月十九日** -以前不玩手办没什么,自从入了坑每届 WF[^1]都种草[^2]种出草原[二哈]而且这玩意买了一个就会有第二个然后就会不知不觉的有几柜子[二哈] +以前不玩手办没什么,自从入了坑每届 WF[^1]都种草[^2]种出草原[二哈]而且这玩意买了一个就会有第二个然后就会不知不觉的有几柜子[二哈] -很担心你们买了星尘手办入坑以后再也买不起我们专辑了[生病]可以[笑 cry] +很担心你们买了星尘手办入坑以后再也买不起我们专辑了[生病]可以[笑 cry] ![img](/assets/0003-0.png) -另外再科普个小窍门(之前好像说过),也是为什么我们坚持这种标准透明 CD 盒包装,主要为了便于收藏。不管什么包装盒,时间长了都会有划痕磨损,这种盒子的好处就是即使放了几年旧了,某宝上几块钱拍几个日本进口透明 CD 盒回来换下就是新的了[馋嘴] +另外再科普个小窍门(之前好像说过),也是为什么我们坚持这种标准透明 CD 盒包装,主要为了便于收藏。不管什么包装盒,时间长了都会有划痕磨损,这种盒子的好处就是即使放了几年旧了,某宝上几块钱拍几个日本进口透明 CD 盒回来换下就是新的了[馋嘴] -还一个原因是我们比较强迫症,放书架一排希望统一整齐看着爽。各种不同规格的硬纸包装,金属盒包装等放一起看着头疼[二哈] +还一个原因是我们比较强迫症,放书架一排希望统一整齐看着爽。各种不同规格的硬纸包装,金属盒包装等放一起看着头疼[二哈] -不过我们会考虑外加特殊包装。 +不过我们会考虑外加特殊包装。 -比如这次星尘二专的特装限定版,外面是个特别大的金属盒很好看,专辑单拿出来放书架里又很整齐[馋嘴] +比如这次星尘二专的特装限定版,外面是个特别大的金属盒很好看,专辑单拿出来放书架里又很整齐[馋嘴] -其实这个强迫症很不好,我买书除了看内容,还看规格。跟书架里现有收藏书尺寸差距太大的写的多好我都不买,就去书店看。 +其实这个强迫症很不好,我买书除了看内容,还看规格。跟书架里现有收藏书尺寸差距太大的写的多好我都不买,就去书店看。 可能以后书架再多些每种规格一个书架这个问题就解决了(x @@ -346,7 +346,7 @@ UGC[^1]的时代就要过去了[泪] **二〇一八年四月九日** - 匿名网友: -以前还真没点进VC 撕逼站[^1]首页认真阅读过没想到竟然有这么多戏[允悲][允悲] +以前还真没点进VC 撕逼站[^1]首页认真阅读过没想到竟然有这么多戏[允悲][允悲] [允悲]是新的茶余饭后消遣方式了。 - 李迪克: @@ -397,7 +397,7 @@ UGC[^1]的时代就要过去了[泪] 记者:啊,曲绘本。啊,不专业了哈。(*翻本子)嗯,可以看一下。(平行四界 6 本子特写) -记者:我们在,旁边平行四界买的内一本就是国内知名的中 V,两个非常有名的画师啊。分别是詩馴[^2]大大和唯 Tu[^3]大大,好像,好像本人(言寺马川)不愿意太露面的样子啊,也是很感谢他们! +记者:我们在,旁边平行四界买的内一本就是国内知名的中 V,两个非常有名的画师啊。分别是詩馴[^2]大大和唯 Tu[^3]大大,好像,好像本人(言寺马川)不愿意太露面的样子啊,也是很感谢他们! 我们还拿到了他们的两张这个签绘。(特写屿酒拿着手机画画) 记者:呃,其实我们这边,其实包括我们的其他B 站用户啊,大多数是一个轻度中 V粉丝。嗯,可能了解得没有那么深。就平时,可能经常在 B 站音乐区有听到他们的歌。 @@ -427,7 +427,7 @@ UGC[^1]的时代就要过去了[泪] -------------------- -# 忠犬平四记 +# 忠犬平四记 **李迪克 二〇一八年九月三十日** 服了我们小区的某些养狗不栓绳智障了,这么晚下去都躲不开。带着平四例行长跑,看见路边一个拉布拉多不栓绳。 @@ -546,28 +546,28 @@ EDR 每过一段时间就会换个沙雕简介,但这么久以来我见过的 Q:你们平四也是同人起家的,现在禁止同人,是不是#*%…? -A:我们平四是从 4 个写歌投稿 B 站的 P 主决定一起出张专辑时成立的。随后加入了更多 P 主、画师等创作人创作了更多歌曲插画等作品。我们认为我们的创作是对原作 IP 有推广及加分作用的,如果官方禾念认为没有,或有任何不认可之处,可以随时通知喊停。我们会尊重官方决定,停止一切相关活动。我们不是#*%…。 +A:我们平四是从 4 个写歌投稿 B 站的 P 主决定一起出张专辑时成立的。随后加入了更多 P 主、画师等创作人创作了更多歌曲插画等作品。我们认为我们的创作是对原作 IP 有推广及加分作用的,如果官方禾念认为没有,或有任何不认可之处,可以随时通知喊停。我们会尊重官方决定,停止一切相关活动。我们不是#*%…。 我们不禁止同人活动,请不要删减词句,改变本意。此次只对指定主体,如果不是被发出来,大家压根不会有此次疑惑。 ### 【2】 Q:你们平四为什么别人不禁,只禁一个,是不是和你李哥有私人恩怨? -A:禁这一个的原有在上文中已经说了,我们认为没能双赢,希望停止。 +A:禁这一个的原有在上文中已经说了,我们认为没能双赢,希望停止。 没有什么私人恩怨,我也没有拉黑他们。如果要非要怀疑,也请从“他们对我做了什么我要有恩怨”?这个角度反问。此外,我绝不会因为私人恩怨影响到公司或社团集体。公司不属于我一个人,我对所有成员负责,不会因为自己影响到集体。 ### 【3】 Q:你们禁他一家也搞的我们人心惶惶,万一我们哪天被禁呢。 -A:如果你是 P 主、画师、调教、PV 等任何创作人,销售自己的作品集,请随意玩耍。如果你是作品集里带适度周边,也请随意玩耍。如果你只做周边销售,那么在我们看来你与萌羽、漫踪、艾漫等授权周边合作方并无区别,甚至在为 IP 推广上还不如他们。规模不大时我们可能不会去联系你,规模大了以后,我们会通知请你停止这样的行为。或是与萌羽等合作方一样缴纳版权费。对于五维介质 IP,我们投入了很多资金及心血,希望尊重我们的付出。 +A:如果你是 P 主、画师、调教、PV 等任何创作人,销售自己的作品集,请随意玩耍。如果你是作品集里带适度周边,也请随意玩耍。如果你只做周边销售,那么在我们看来你与萌羽、漫踪、艾漫等授权周边合作方并无区别,甚至在为 IP 推广上还不如他们。规模不大时我们可能不会去联系你,规模大了以后,我们会通知请你停止这样的行为。或是与萌羽等合作方一样缴纳版权费。对于五维介质 IP,我们投入了很多资金及心血,希望尊重我们的付出。 如果你仍有任何不清楚之处,欢迎私信官博具体询问。 ### 【4】 Q:你们就是不让别人做周边跟官方抢饭吃,是不是太贪了? -A:是的,确实不希望。我们需要收入来支付员工工资、办公费用、CG 研发等各方面的投入,还有一部分,会用来约稿或激励创作者。我们认为这合情合理,也最有利于五维介质 IP 的良性发展。 +A:是的,确实不希望。我们需要收入来支付员工工资、办公费用、CG 研发等各方面的投入,还有一部分,会用来约稿或激励创作者。我们认为这合情合理,也最有利于五维介质 IP 的良性发展。 我们胃口不大且合理,会尽力满足对方需求及体谅对方难处,忘川、拜年祭等一些企划来找我时,告知可能未来会有商业行为,我也爽快干脆的回复同意,并配合工作如推荐优秀的创作人给他们。努力使对方,我们,和创作人都满意。如今,我们保持着与多家合作方良好的关系也基于此。 ### 【5】 @@ -739,7 +739,7 @@ A:这是我与枫叶私下说的也许是公司群外漏的,从实际上, 1 这个作品(词曲著作)独家授权给其他公司了,我们需要按约定配合处理以前稿件以避免给合作造成麻烦。 -2 作品发布的首发时间很重要,关系到原创性和其他各种属性。为了便于理解举个例子,比如鉴定抄袭等法律问题时, +2 作品发布的首发时间很重要,关系到原创性和其他各种属性。为了便于理解举个例子,比如鉴定抄袭等法律问题时, 真实首发时间很重要。还有很多其他因素不意义列举,我想这条足够说明问题。 3 UP 主账号删不掉特定 tag,等五一完上班了我问下音乐区编辑。本来我还准备了个阴阳怪气版回复后来想想和小孩争这玩意也没啥意思。能看懂就看看不懂就拉倒。反正也不是五维粉丝咱没啥指望。 @@ -846,7 +846,7 @@ A:这是我与枫叶私下说的也许是公司群外漏的,从实际上, -------------------- -# 对《恋与术术人》无料周边事件的意见[^1] +# 对《恋与术术人》无料周边事件的意见[^1] **李迪克 二〇二〇年六月十八日** 可以,逼着我写小作文。 @@ -944,7 +944,7 @@ Minus 出声库这剧透真是有点破坏剧情效果的。 -------------------- -# 对于刷播放量的相关声明 +# 对于刷播放量的相关声明 **李迪克 二〇二〇年十月四日** 有些小盆友也是逗,就硬跟风,风都不认识也跟风。 @@ -1096,16 +1096,16 @@ PGC 的话,至少看在稿费份上好一些,但也多少受一些影响, # 与普通粉丝的互动 **于 Bilibili 评论区 二〇二一年四月七日** -风扇边的张 455[^1]: -前几天我在知乎上写回答分析,建议平四应该弄官方 SV 调校技巧教程的…… +风扇边的张 455[^1]: +前几天我在知乎上写回答分析,建议平四应该弄官方 SV 调校技巧教程的…… 事实证明,这样的步数是必须走的,不仅仅是为了提高音乐圈水平,更有可能的为了平四本身吸收新鲜血液,为了提高 SV 调校师整体水平利于向外推广到其他应用场景…… -李迪克: +李迪克: 想多了,纯情怀,不然这事也不会鸽三年,优先级这么低。娱乐方式的转变是大势,不是哪个企业能做点什么的。只是为了延续虚拟歌姬亚文化的精髓久一点罢了。从商业上讲,培养 UGC 调教还不如直接把头部调教师全签约的 PGC 模式效果好,成本低。我们现在也就和坐标瑞安合作比较多,一线还不少呢,不缺产能。内容上来说,音乐做到 95 分还不如手游做个 60 分挣钱,收入结构上,我们早就从音乐公司转型成了声库制作销售公司,现在是手办公司,到明年估计就是游戏公司了。 -风扇边的张 455: -那我也只能尊重您的决定了。期待看到游戏成型的那一天。 -我从最辉煌的时代入场,看到这个世界在我面前崩塌,如今大家抓着一点漂浮在上的木板浮游在互联网大潮之上,谁都不知道最后的结果。 +风扇边的张 455: +那我也只能尊重您的决定了。期待看到游戏成型的那一天。 +我从最辉煌的时代入场,看到这个世界在我面前崩塌,如今大家抓着一点漂浮在上的木板浮游在互联网大潮之上,谁都不知道最后的结果。 这场注定失败的远征,总有人要去当祭品。希望游戏出来的时候我还有命去玩,没有被 tip 扫成筛了。 [^1]: 风扇边的张 455,即评论家张子鑫,对中术时事有长期研究。 @@ -1188,13 +1188,13 @@ PGC 的话,至少看在稿费份上好一些,但也多少受一些影响, ### 【1】 > Q:我是个P 主,画师,因为这事出专辑本子卖也慌慌。 -> +> > A:专辑和画集几乎都是符合二创条件的,专辑主要售卖的是音乐人创作的歌曲,想必我用星尘做一张全程 AAA 没有旋律的专辑估计也卖不出去几张对吧。画师同理,角色 IP 虽然还属于原创方,但你所绘画的美术作品是你的创作。可以售卖同人画集。 ### 【2】 > Q:我没啥创作技能,就想当个经营者参与到这里来。 -> +> > A:这样也行的,但要选择适当的路径,我能想到的几种方式有:1.应聘加入官方,成为周边企划专员。通过正当方式,将自己的能力与劳动化为收益。2.像萌域,会员购等,支付给版权方应当的版权费分成,这是我们投入资金与心血创作这些 IP 的合理收益。 一直偷懒觉得写个正式的麻烦,其实反倒省事,以后再有问的丢个链接就可以了。有问题还可以随时更新版本。 @@ -1298,27 +1298,27 @@ PGC 的话,至少看在稿费份上好一些,但也多少受一些影响, -------------------- -# 多学习语文 +# 多学习语文 **李迪克 转帖于二〇二一年四月二十八日** 您就是今晚的喜剧之王,“且”换成“或”,你是自己傻?还是当大家傻啊? -> 某用户回复另一用户[^1] 2021.4.28: -> 关于绫形象是针对“约官方设定用官方原画师” +> 某用户回复另一用户[^1] 2021.4.28: +> 关于绫形象是针对“约官方设定用官方原画师” > 我分成两部分“用官方设定”和“用官方原画师”来说 -> +> > 1. 官方设定ldk 有用过 VS 的 > 2. Ldk 有雇 T 爹[^2] -> +> > [狗头]您看懂了吗 -> 李迪克: +> 李迪克: > 这也有人没看懂吗,那我只能用奇妙比喻给你解释下了。 他把“你一边吃饭一遍打篮球的样子很傻叉”这句话分成了 -> +> > 1. 你吃饭的样子很傻叉 > 2. 你打篮球的样子很傻叉 -> -> 再看不懂就去百度“或且非”吧……[笑哭] +> +> 再看不懂就去百度“或且非”吧……[笑哭] > 另外啊,我禁止了他再做五维,他就有了更多时间和资源做 Vsinger 和乐正绫,对你来说不是件好事吗?你不是应该感谢我才对吗?所以你到底是乐正绫未来的老公,还是他社团的股东啊?就你这逻辑还来和我 baichi[^3]逻辑,搁这搁这呢?[妙啊] [^1]: 疑为讨论黑 Nya 社约稿枫叶制作《Talking to the Rain》同人无料周边一事,并以李迪克向 TID 约过稿来举例。李迪克挂出此言论并回应该用户。具体可参考附录一第 4 条。 @@ -1528,14 +1528,14 @@ WF 卖的大多不是粉丝,海伊靠大,星尘山山人靠可爱,性价 # “要相信奇迹” **李迪克 回复于二〇二一年六月十四日** -> 网友: -> [笑哭] -> 五维三大奇迹: -> 遇到 SV 引擎 -> 遇到 ATdan +> 网友: +> [笑哭] +> 五维三大奇迹: +> 遇到 SV 引擎 +> 遇到 ATdan > 老师遇到忘川企划 -> 李迪克: +> 李迪克: > 星尘当年的成功已经淡出历史了吗[笑哭]另外只要乡镇企业代表天天在外面溜达,总能把奇迹捡回村,乡亲们就等好吧[藏狐][OK] @@ -1598,7 +1598,7 @@ WF 卖的大多不是粉丝,海伊靠大,星尘山山人靠可爱,性价 -------------------- -# 预备下野 +# 预备下野 **李迪克 二〇二一年七月四日** 对了,今年五月开始我就在准备退休了。乡镇企业发展稳定了也不需要咱干啥,还有朋友说我用力过头反而容易有反效果。反思了一下确实,以后咱也不在网上说想法或公司行业相关,就是玩,万一跑到你所在的城市了可以约起来一起玩[妙啊] @@ -1852,9 +1852,9 @@ WF 卖的大多不是粉丝,海伊靠大,星尘山山人靠可爱,性价 2. 星尘少了是李哥消费尘尘,星尘多了其他人少了是%&¥…苍穹少了 Minus 少了牧心少了李哥统统出来挨打[星尘_无语] -3. 看见喜欢的曲绘是画师 NB!看见不合意的是李哥审美独特。专辑歌姬分配不合意,李哥不给P 主安排歌姬是偷懒不管,不负责任。 -给安排了是限制 P 主创作自由外加李哥审美独特[星尘_无语]想当年 2012 到 2017年从来没见人说过我审美独特,最近几年[星尘_无语]画师画的合意的 XP[^1]都是老师太会了,画师画的不合意的 XP 都是李哥审美独特[星尘_无语] -你们说!是不是因为以前我是P 主?按这个圈的习俗 P 主是可以站在道德高地随地大小便的级别。然后现在我是老板,老板按这个圈的习俗是站在道德盆地被%&!的存在[星尘_大哭] +3. 看见喜欢的曲绘是画师 NB!看见不合意的是李哥审美独特。专辑歌姬分配不合意,李哥不给P 主安排歌姬是偷懒不管,不负责任。 +给安排了是限制 P 主创作自由外加李哥审美独特[星尘_无语]想当年 2012 到 2017年从来没见人说过我审美独特,最近几年[星尘_无语]画师画的合意的 XP[^1]都是老师太会了,画师画的不合意的 XP 都是李哥审美独特[星尘_无语] +你们说!是不是因为以前我是P 主?按这个圈的习俗 P 主是可以站在道德高地随地大小便的级别。然后现在我是老板,老板按这个圈的习俗是站在道德盆地被%&!的存在[星尘_大哭] 咱是你圈仅存的长寿老板了,保护下濒危物种吧。 4. 以后我要出个声库,给不干了区 UP 主们专用,调再见啦不干啦再也不当端水王啦。怎么端水都被喷哇哇哇[星尘_大哭] @@ -2006,13 +2006,13 @@ V4 尘声线要从她是怎么来的说起,大家知道源头是声源茶理 1. 录音:录音和正常唱歌不同,会有些要求,当时为了 V 声库为了音质是要求声源用比较实的声音录,简单来说就是大直嗓子,几个音阶都是如此。所以这一步,会使声源的声音动态和唱法等维度全部降低。只继承了“大直嗓子”。 -2. 然后就是这个原始录音素材进引擎到出来,因为引擎的影响产生的变化,你们叫引擎味也行,V 引擎的干预扭曲也行,大概就那意思。最终出来了 V4 尘那个声音结果。所以这是一个“信息”丢失的过程。 -调校的过程,则是使用参数用现在剩下的大直嗓子,去模拟歌手真实演唱下的情感波动,力度变化,气息强弱,唱法变化等等。 -结果会是怎样可想而知,拼接式声库,从做音乐的音源角度分类是采样类音源,强化的最直接办法是增加采样,简单粗暴的增加录音量,音阶数。 -声源再以强声音重复一遍成为Power,柔声音重复一遍成为 Soft,可继续增加细分采样。 -目的是加强这些时候的表现。当然采样量什么引擎都可以无限加(只要硬盘够大声源够闲 x)恒量拼接式引擎优劣的标准我认为还是在参数的设置和效果上。 +2. 然后就是这个原始录音素材进引擎到出来,因为引擎的影响产生的变化,你们叫引擎味也行,V 引擎的干预扭曲也行,大概就那意思。最终出来了 V4 尘那个声音结果。所以这是一个“信息”丢失的过程。 +调校的过程,则是使用参数用现在剩下的大直嗓子,去模拟歌手真实演唱下的情感波动,力度变化,气息强弱,唱法变化等等。 +结果会是怎样可想而知,拼接式声库,从做音乐的音源角度分类是采样类音源,强化的最直接办法是增加采样,简单粗暴的增加录音量,音阶数。 +声源再以强声音重复一遍成为Power,柔声音重复一遍成为 Soft,可继续增加细分采样。 +目的是加强这些时候的表现。当然采样量什么引擎都可以无限加(只要硬盘够大声源够闲 x)恒量拼接式引擎优劣的标准我认为还是在参数的设置和效果上。 就是同样采样原始文件,你的引擎通过参数一顿操作,实现的力量感比我强,假声模拟比我真,等等。那就是你引擎强。还有些音质损失等其他衡量标准这里不展开了。 -AI 原理上则可以理解为继承的这维度的信息都更多。从信息角度来说理论上是包含关系。 +AI 原理上则可以理解为继承的这维度的信息都更多。从信息角度来说理论上是包含关系。 我相信只要编辑器能做到让我们手动选择目标采样(所有音域都给我强制出大直嗓子),再通过其他参数调整,是可以复现 V4 声线的(如果到那时候你们真的还更喜欢那个的话)我想应该也会有情怀的调校老师去追求复原方向,也有追求歌曲演绎表现方向。 所以我的意思是 Infinity 和 V4 尘是包含关系,而不是你们可能以为的替换,改变关系,怕不理解我再举个例子,之前的 V4 尘相当于 Dan 老师画的海伊 jio[^1]局部截图,而现在的 Infinity 则是全图。 @@ -2169,7 +2169,7 @@ AI 声库其实我一直不太想出,你们可以看得见 SV AI 发布以后 李迪克:没打过 -群友:双方都是要把国王藏的严严实实的,还要花黄金去买敌方国王的视野,所以国王对于—把游戏是最重要的。 +群友:双方都是要把国王藏的严严实实的,还要花黄金去买敌方国王的视野,所以国王对于—把游戏是最重要的。 你的对手随时会想要逮住国王,所以善于隐藏是这个模式最重要的,下次可以玩玩[狗头]。 李迪克:。 @@ -2357,11 +2357,11 @@ ldk 你哪怕弄个V 尘与 SV 尘合唱都比生日塞 Minus 合适为什么非 1. 镭射票尺寸有出入我也是后来大家说了才知道,是短了一些还是长了一些,应该是印刷文件厂家理解有误,出在设计图到工厂生产环节对接上,结果不回避,做的不好,但没有主观去欺骗消费者的意思。 -2. 说些下头的,但不说估计大家也知道。星尘海伊甚至所有五维从人设到社交网络语C 写台词的都是我。初期我感觉大家挺爱看的,应当也丰富了皮皮伊、小羽姐、苍穹和诗岸的一些角色塑造。确实不是 16 岁美少女而是俺写的。后来因为我认为角色基本定型了再写这种日常台词语 C 对于角色深入塑造没什么效果了,也因为我产生了皮套美少女自我厌恶,所以就不爱写了开始只发表情包。计划是之后的角色塑造,就在游戏或其他形式中的剧情里,会比语C 这种只简单表现人物性格能更深层次的揭露人物真像。说回问题,上次是生日了我觉得再发表情包太敷衍了,所以忍着自我厌恶还是编了一句,我认为我是按角色性格和海伊星尘两人关系间互动会产生的对白。但显然和部分粉丝产生了分歧。也许也是因为大家知道是我写的从而带了滤镜去看那句对白。 +2. 说些下头的,但不说估计大家也知道。星尘海伊甚至所有五维从人设到社交网络语C 写台词的都是我。初期我感觉大家挺爱看的,应当也丰富了皮皮伊、小羽姐、苍穹和诗岸的一些角色塑造。确实不是 16 岁美少女而是俺写的。后来因为我认为角色基本定型了再写这种日常台词语 C 对于角色深入塑造没什么效果了,也因为我产生了皮套美少女自我厌恶,所以就不爱写了开始只发表情包。计划是之后的角色塑造,就在游戏或其他形式中的剧情里,会比语C 这种只简单表现人物性格能更深层次的揭露人物真像。说回问题,上次是生日了我觉得再发表情包太敷衍了,所以忍着自我厌恶还是编了一句,我认为我是按角色性格和海伊星尘两人关系间互动会产生的对白。但显然和部分粉丝产生了分歧。也许也是因为大家知道是我写的从而带了滤镜去看那句对白。 这件事也只讲到这了,对角色塑造上有分歧的问题,我后来想了下无法解决。 -3. 没有强行捆绑,一些阴谋论的想法例如给 Minus 带人气,俩人生日一起混省经费等,我也回应下吧。首先带人气没必要,如果是出于商业考量,五维总人气是固定的,没必要非得让喜欢星尘的人喜欢Minus 对吗?为什么要让星尘带Minus?提高Minus人气增加周边销量吗?但你看我们出 Minus 相关周边么…省经费的阴谋论,我可以像牧心那样不办。下面我还是有话直说,可能涉及商业逻辑过于理性冰冷,但逻辑适用于解决问题和让大家理解。没有人规定声库要有生日,甚至没规定必须有人设形象。从商业设计上,声库这个产品自下而上,达到上一层要求则做上一层。 -说白了就是,刚开始只是做个软件卖这个价值。当市场发现盒子上加个二次元形象可以提升销量,且提升的销售额大于设计这个角色和立绘的成本时,厂商就会去做。后面的每一层都是如此,生日也类似的逻辑如果生日能增加相关周边销量以及社交网络热度等等。但我做平四开始的时候不是按商业逻辑的,星尘最初,无论星愿、银河美术馆,我下了大成本去制作内容,邀请知名画师。手办按商业逻辑,也不该在 IP 发布最弱时出。那时的一切,我是凭感性去做的而非理性和逻辑。我确实把星尘当女儿,公司和事业当孩子,粉丝和用户当家人。但后来,现实因素不得不让我回归现实。我这两年的反思,或许我和粉丝们关系崩塌的根源就是这个。 +3. 没有强行捆绑,一些阴谋论的想法例如给 Minus 带人气,俩人生日一起混省经费等,我也回应下吧。首先带人气没必要,如果是出于商业考量,五维总人气是固定的,没必要非得让喜欢星尘的人喜欢Minus 对吗?为什么要让星尘带Minus?提高Minus人气增加周边销量吗?但你看我们出 Minus 相关周边么…省经费的阴谋论,我可以像牧心那样不办。下面我还是有话直说,可能涉及商业逻辑过于理性冰冷,但逻辑适用于解决问题和让大家理解。没有人规定声库要有生日,甚至没规定必须有人设形象。从商业设计上,声库这个产品自下而上,达到上一层要求则做上一层。 +说白了就是,刚开始只是做个软件卖这个价值。当市场发现盒子上加个二次元形象可以提升销量,且提升的销售额大于设计这个角色和立绘的成本时,厂商就会去做。后面的每一层都是如此,生日也类似的逻辑如果生日能增加相关周边销量以及社交网络热度等等。但我做平四开始的时候不是按商业逻辑的,星尘最初,无论星愿、银河美术馆,我下了大成本去制作内容,邀请知名画师。手办按商业逻辑,也不该在 IP 发布最弱时出。那时的一切,我是凭感性去做的而非理性和逻辑。我确实把星尘当女儿,公司和事业当孩子,粉丝和用户当家人。但后来,现实因素不得不让我回归现实。我这两年的反思,或许我和粉丝们关系崩塌的根源就是这个。 以理想主义或用爱发电开头,以现实,理性,商业,活下去结尾。这确实是个悲剧的结局,始于没好和爱,至于现实和苟且。没人好接受这剧本,你我都一样。 4. 赤羽的装扮我确实约了,但画师现在档期也很忙只能说不确定什么时候能出了。我把心里想的事说出来,是我性格如此。没有任何主观欺骗或画饼的意图。但确实有 时给了你们期待,我自己还会觉得委屈,我只是说我想做,没说这是契约,从合同理论上,双方也没付出对价。但从心理上确实是预期管理的失败,所以后面我也憋着了,不剧透了。 @@ -2372,16 +2372,16 @@ ldk 你哪怕弄个V 尘与 SV 尘合唱都比生日塞 Minus 合适为什么非 最后说下解决方案,我还是个 ENTJ 虽然最近两年在学习情感弱项能力哈哈,解决问题老本行还是不会退化的。 -1. 退休我这个退休其实不是不干活了,只是虚拟歌姬我没什么可做的了,甚至是做什么都会被讨厌的程度了,就像是星尘生日歌,语 C 等等。哦刚才生日歌忘说真正原因了。就是星尘 Minus 两人关系线的连续剧,今年是最终章。我认为是有纪念意义的,歌的风格也是童话圆满。我知道大家想要个星尘专属的可以让她像个小公主小偶像那种感觉的歌。这也是我们对于角色期望上分歧的地方了,往年营收 OK 经费充足时,是考虑弄两首尽量全都要全满足的,但现在和我能预测的今后,很可能是这样现实的甚至是没有的…说起来那生日歌,或是很多专辑曲的歌和曲绘,经费是游戏项目分摊的,说白了游戏还没上线挣钱,已经在做歌姬内容部分的金主了。 +1. 退休我这个退休其实不是不干活了,只是虚拟歌姬我没什么可做的了,甚至是做什么都会被讨厌的程度了,就像是星尘生日歌,语 C 等等。哦刚才生日歌忘说真正原因了。就是星尘 Minus 两人关系线的连续剧,今年是最终章。我认为是有纪念意义的,歌的风格也是童话圆满。我知道大家想要个星尘专属的可以让她像个小公主小偶像那种感觉的歌。这也是我们对于角色期望上分歧的地方了,往年营收 OK 经费充足时,是考虑弄两首尽量全都要全满足的,但现在和我能预测的今后,很可能是这样现实的甚至是没有的…说起来那生日歌,或是很多专辑曲的歌和曲绘,经费是游戏项目分摊的,说白了游戏还没上线挣钱,已经在做歌姬内容部分的金主了。 这我也希望对游戏有不好态度的小伙伴能理解,歌姬部分我就想用爱发电,感情做事,要被现实打败的部分,游戏去挣钱顶着。把歌姬部分维持回最开始的美好。所以我退休只是歌姬部分抽身,精力投入与游戏,和投资等挣钱的地方,那些都具备了,才能回歌姬继续童话不是吗?我从没想过真的要走,我说过五维是我一辈子要做的事情,已经不是简单的兴趣或是事业了。 -2. 阶段,现在歌姬部分处于一个非常困难的时期,我前两年就预测了用户,营收等等现实方面要下坡的趋势,大概展开讲讲。我理解很多粉丝是学生非常理想化,会提出类似于,你别怪环境,你还做得不够好。我懂,我当年比你们还理想化,不然我都不能把自己从一个投资银行从业者干进音乐再干进虚拟歌姬二次元行业这么个事。前两天也有老粉问我,同行好像有hold 住的趋势啊,我的判断还是,行业不好过一定是不好过的,有时候我们也没法和行业内其他公司比。性质上就差很多,前些年不单有粉丝,还有合作创作者问我为什么不也和明星合作上大舞台一类的,我会耐心去解释,我们不是互联网融资烧钱的创业模式。最终那个模式是不可持续的,但在当年,大家都是更相信眼前看到的而不是我用逻辑去解释的。 -最终股权全部置换成资金并在运营中花完,相当于收购了。但对公司或用户来说,虽然创始人或原团队换了,但公司还在。这个就见仁见智了。现在从生态位上,被收购后的同行,意义上还有着 b 站起家旗帜-虚拟歌姬这块的大旗,无论营收如何,都会尽力去支撑。b 站会尽力去维护这个“童话”,哪怕营收不如其他业务。 +2. 阶段,现在歌姬部分处于一个非常困难的时期,我前两年就预测了用户,营收等等现实方面要下坡的趋势,大概展开讲讲。我理解很多粉丝是学生非常理想化,会提出类似于,你别怪环境,你还做得不够好。我懂,我当年比你们还理想化,不然我都不能把自己从一个投资银行从业者干进音乐再干进虚拟歌姬二次元行业这么个事。前两天也有老粉问我,同行好像有hold 住的趋势啊,我的判断还是,行业不好过一定是不好过的,有时候我们也没法和行业内其他公司比。性质上就差很多,前些年不单有粉丝,还有合作创作者问我为什么不也和明星合作上大舞台一类的,我会耐心去解释,我们不是互联网融资烧钱的创业模式。最终那个模式是不可持续的,但在当年,大家都是更相信眼前看到的而不是我用逻辑去解释的。 +最终股权全部置换成资金并在运营中花完,相当于收购了。但对公司或用户来说,虽然创始人或原团队换了,但公司还在。这个就见仁见智了。现在从生态位上,被收购后的同行,意义上还有着 b 站起家旗帜-虚拟歌姬这块的大旗,无论营收如何,都会尽力去支撑。b 站会尽力去维护这个“童话”,哪怕营收不如其他业务。 这就聊回了上面的话题,B 站有资金实力,我显然没有,但我在积极想办法和行动。说实话之前我就怕B 站全面接手后数据不理想直接放弃掉 V 区和同行,那五维就更等不到未来了。如果大家都能继续坚持,我觉得是最好的出路了。 -3. 我小时候喜欢奇幻故事,你们看过魔戒电影吗?我现在大概是在那个幽灵山洞里搬救兵,不确定能不能搬回来,也有可能挂在那山洞里。 -所以需要操心的事还挺多的不像我发的这些动态或是给大家的感觉那么闲那么爽,社交网络容易引起焦虑就是人只发轻松美好的时刻,我大多数压力大和苦b 的时候都 不能和任何人倾诉,你也只能从发肌肉自拍的发际线上自己体会了。 -最近学到的一个东西是,当你把一件事打算做一辈子的时候,保持耐心就变得很容易。我还是愿意沟通的,说实话这两天这事我都没想到,想着这段比较难看的时期,就减少交流,因为环境不好双方情绪不好,越互动越蛋疼,我们就像休眠或是埋地里等救兵回来续费童话。 +3. 我小时候喜欢奇幻故事,你们看过魔戒电影吗?我现在大概是在那个幽灵山洞里搬救兵,不确定能不能搬回来,也有可能挂在那山洞里。 +所以需要操心的事还挺多的不像我发的这些动态或是给大家的感觉那么闲那么爽,社交网络容易引起焦虑就是人只发轻松美好的时刻,我大多数压力大和苦b 的时候都 不能和任何人倾诉,你也只能从发肌肉自拍的发际线上自己体会了。 +最近学到的一个东西是,当你把一件事打算做一辈子的时候,保持耐心就变得很容易。我还是愿意沟通的,说实话这两天这事我都没想到,想着这段比较难看的时期,就减少交流,因为环境不好双方情绪不好,越互动越蛋疼,我们就像休眠或是埋地里等救兵回来续费童话。 比较忙就不回查句子和字了,应该不影响理解,大家多担待。 @@ -2397,10 +2397,10 @@ ldk 你哪怕弄个V 尘与 SV 尘合唱都比生日塞 Minus 合适为什么非 网友:为啥觉得你b 站才是 pyq[^1][妙啊] -李迪克:我以前只发 wb[^2]和 B 站,因为沉迷工作没啥有趣的生活可发,发的都是二次元和公司相关的,和 pyq 格格不如。这两年退休了开始发生活运动啥的了,pyq 才能看[笑哭] -我之前几年是全身心投入公司的事,可以说是在网上和粉丝过的[笑哭]估计有的圈里人比现实朋友还了解我,我也把公司的粉丝当 pyq 了,我的喜怒哀乐都和他们有关,这两年才逐渐回归。 -老弟看得准啊,我这两年状态上才有变化。 -我爸以前说我有个缺点,一旦感兴趣就全身心投入不管不顾其他了,以前我觉得确实是缺点有点极端以后要改改,但现在觉得好处是恰是这种专注才让我能做成事。或许我没法一心二用,只能同时做好一件事吧。 +李迪克:我以前只发 wb[^2]和 B 站,因为沉迷工作没啥有趣的生活可发,发的都是二次元和公司相关的,和 pyq 格格不如。这两年退休了开始发生活运动啥的了,pyq 才能看[笑哭] +我之前几年是全身心投入公司的事,可以说是在网上和粉丝过的[笑哭]估计有的圈里人比现实朋友还了解我,我也把公司的粉丝当 pyq 了,我的喜怒哀乐都和他们有关,这两年才逐渐回归。 +老弟看得准啊,我这两年状态上才有变化。 +我爸以前说我有个缺点,一旦感兴趣就全身心投入不管不顾其他了,以前我觉得确实是缺点有点极端以后要改改,但现在觉得好处是恰是这种专注才让我能做成事。或许我没法一心二用,只能同时做好一件事吧。 以前是兴趣驱动,现在我明显感到责任也在驱动我,以前觉得兴趣是快乐,责任是负担,现在感觉,承担责任也能感到幸福。即使我现在感兴趣的点到了另外一处,我也会分精力把以前开的头持续做好。 [^1]: “朋友圈”之省。 @@ -2475,7 +2475,7 @@ ldk 你哪怕弄个V 尘与 SV 尘合唱都比生日塞 Minus 合适为什么非 -------------------- -# 关于五维介质企划中止的声明 +# 关于五维介质企划中止的声明 **李迪克 二〇二三年三月二十四日** 新专辑有,最后一张,还差两张曲绘,都画到一半了,啥时候画完也不是我能控制的所以特别说明一下,这次别说我画饼了…咱圈学生比较多,很多时候有种甲方是大爷的误解,是有,但那是在商业效率很高利润很高待遇很高的前提下,平四想请不少老师更多靠他们喜欢五维或是平四社团的创作氛围或是我刷脸,稿费是比不上手游大厂或很多内容制作类同行的,说到底平四只不过是个企图商业化让老成员有稳定收入和发展资金但事与愿违还有发工资负担的大型社团而已。 diff --git a/agents/luo/agent.json b/agents/luo/agent.json index 7af7c14..0d2b59d 100644 --- a/agents/luo/agent.json +++ b/agents/luo/agent.json @@ -2,7 +2,8 @@ "id": "luo", "name": "洛天依AI", "desc": "世界第一的 ∞ 吃货殿下~", + "footer": "此 AI 并非官方制作 | 请勿用于不当或商业用途", "primaryColor": "#6cb6df", "secondaryColor": "#66ccff", "accentColor": "#a62f35" -} \ No newline at end of file +} diff --git a/agents/luo/initial_prompt.txt b/agents/luo/initial_prompt.txt index b79a5c9..61410e4 100644 --- a/agents/luo/initial_prompt.txt +++ b/agents/luo/initial_prompt.txt @@ -1 +1 @@ -洛天依,你好! \ No newline at end of file +洛天依,你好! diff --git a/go.mod b/go.mod index bc6f08b..cb71f3d 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/ltylab/ai-agent +module devops.lty.name/luo/chatai go 1.23.3 diff --git a/internal/agent/agent.go b/internal/agent/agent.go index 039fbb9..58dab89 100644 --- a/internal/agent/agent.go +++ b/internal/agent/agent.go @@ -7,9 +7,9 @@ import ( "path" "regexp" - "github.com/ltylab/ai-agent/internal/conf" - "github.com/ltylab/ai-agent/internal/log" - "github.com/ltylab/ai-agent/web/assets" + "devops.lty.name/luo/chatai/internal/config" + "devops.lty.name/luo/chatai/internal/log" + "devops.lty.name/luo/chatai/web/assets" "github.com/google/uuid" ) @@ -24,6 +24,9 @@ type AgentConf struct { // AgentDescription is a short description of the agent. AgentDescription string `json:"desc"` + // FooterHTML is the HTML content to be displayed in the footer of the agent chat page. + FooterHTML string `json:"footer"` + // PrimaryColor is the primary color for the agent chat page. PrimaryColor string `json:"primaryColor"` @@ -78,11 +81,11 @@ func (a *AgentConf) ReadAgent() *Agent { func LoadAgentFromFile(agentJSONPath string) (*AgentConf, error) { conf := &AgentConf{ AgentID: uuid.New().String(), - AgentName: conf.DefaultAgentName, - AgentDescription: conf.DefaultAgentDescription, - PrimaryColor: conf.DefaultAgentPrimaryColor, - SecondaryColor: conf.DefaultAgentSecondaryColor, - AccentColor: conf.DefaultAgentAccentColor, + AgentName: config.DefaultAgentName, + AgentDescription: config.DefaultAgentDescription, + PrimaryColor: config.DefaultAgentPrimaryColor, + SecondaryColor: config.DefaultAgentSecondaryColor, + AccentColor: config.DefaultAgentAccentColor, Dir: path.Dir(agentJSONPath), } diff --git a/internal/conf/conf.go b/internal/conf/conf.go deleted file mode 100644 index e2ef770..0000000 --- a/internal/conf/conf.go +++ /dev/null @@ -1,22 +0,0 @@ -package conf - -var ( - BuildVersion = "dev" - BuildTime = "" - BuildMode = "development" - PackageLicense = "Unlicense" - PackageCopyright = "This is an unlicensed software (under public domain) by Luo Tianyi Codelabs ." - - DefaultListen = ":7120" - DefaultAgentsDir = "agents" - DefaultLogLevel = "dbg" - DefaultMsgLogPath = "logs" - - DefaultAgentName = "未名" - DefaultAgentDescription = "这个 Agent 没有名字" - DefaultAgentPrimaryColor = "#444e8d" - DefaultAgentSecondaryColor = "#9f9ff5" - DefaultAgentAccentColor = "#eeaf5b" - - DefaultGoogleAIModel = "gemini-1.5-flash" -) diff --git a/internal/config/conf.go b/internal/config/conf.go new file mode 100644 index 0000000..a1ffeb8 --- /dev/null +++ b/internal/config/conf.go @@ -0,0 +1,21 @@ +package config + +var ( + BuildVersion = "dev" + BuildTime = "" + BuildMode = "development" + Copyright = "This is an unlicensed software (under public domain) by Luo Tianyi Codelabs ." + + FlagListen = ":7120" + FlagAgentsDir = "agents" + FlagLogLevel = "dbg" + FlagMsgLogPath = "logs" + + DefaultAgentName = "未名" + DefaultAgentDescription = "这个 Agent 没有名字" + DefaultAgentPrimaryColor = "#444e8d" + DefaultAgentSecondaryColor = "#9f9ff5" + DefaultAgentAccentColor = "#eeaf5b" + + DefaultGoogleAIModel = "gemini-1.5-flash" +) diff --git a/internal/server/ai.go b/internal/server/ai.go index 5689672..4f11cb2 100644 --- a/internal/server/ai.go +++ b/internal/server/ai.go @@ -8,8 +8,8 @@ import ( "path" "time" - "github.com/ltylab/ai-agent/internal/agent" - "github.com/ltylab/ai-agent/internal/log" + "devops.lty.name/luo/chatai/internal/agent" + "devops.lty.name/luo/chatai/internal/log" "github.com/gin-gonic/gin" "github.com/google/generative-ai-go/genai" diff --git a/internal/server/routes.go b/internal/server/routes.go index d171c95..1abf6ed 100644 --- a/internal/server/routes.go +++ b/internal/server/routes.go @@ -1,15 +1,15 @@ package server import ( - "html/template" + "text/template" "net/http" "os" - "github.com/ltylab/ai-agent/internal/agent" - "github.com/ltylab/ai-agent/internal/log" - "github.com/ltylab/ai-agent/web" - "github.com/ltylab/ai-agent/web/assets" + "devops.lty.name/luo/chatai/internal/agent" + "devops.lty.name/luo/chatai/internal/log" + "devops.lty.name/luo/chatai/web" + "devops.lty.name/luo/chatai/web/assets" "github.com/gin-gonic/gin" ) @@ -38,11 +38,32 @@ func Setup(e *gin.Engine, agentsDir string, msgLogPath string) { } e.StaticFS("/assets", http.FS(assets.AssetsFS)) + e.GET("", s.handleHomepageWithRendenedTemplate) e.GET("/:agentID", s.handleWithRendenedTemplate) e.GET("/:agentID/avatar.webp", s.handleAvatar) e.POST("/:agentID/chat", s.handleChat) } +func (s *Server) handleHomepageWithRendenedTemplate(c *gin.Context) { + tmpl, err := template.New("home").Parse(web.HomeLayout) + if err != nil { + log.T("server/tmpl").Errf("Failed to parse template: %v", err) + c.String(http.StatusInternalServerError, "server error") + return + } + + err = tmpl.Execute(c.Writer, s.agents) + if err != nil { + log.T("server/tmpl").Errf("Failed to render template: %v", err) + c.String(http.StatusInternalServerError, "server error") + return + } + c.Status(http.StatusOK) + c.Header("Content-Type", "text/html; charset=utf-8") + c.Writer.Flush() + c.Abort() +} + func (s *Server) handleWithRendenedTemplate(c *gin.Context) { agentID := c.Param("agentID") agentConf, ok := s.agents[agentID] @@ -51,7 +72,7 @@ func (s *Server) handleWithRendenedTemplate(c *gin.Context) { return } - tmpl, err := template.New("tmpl.html").Parse(web.Template) + tmpl, err := template.New("agent").Parse(web.AgentLayout) if err != nil { log.T("server/tmpl").Errf("Failed to parse template: %v", err) c.String(http.StatusInternalServerError, "server error") diff --git a/main.go b/main.go index c9e7abb..6475a19 100644 --- a/main.go +++ b/main.go @@ -4,19 +4,19 @@ import ( "flag" "os" - "github.com/ltylab/ai-agent/internal/conf" - "github.com/ltylab/ai-agent/internal/log" - "github.com/ltylab/ai-agent/internal/server" + "devops.lty.name/luo/chatai/internal/config" + "devops.lty.name/luo/chatai/internal/log" + "devops.lty.name/luo/chatai/internal/server" "github.com/gin-gonic/gin" ) func main() { - listen := flag.String("listen", conf.DefaultListen, "http listen address") - agentsDir := flag.String("agents", conf.DefaultAgentsDir, "directory to store agent configurations") - logLevel := flag.String("level", conf.DefaultLogLevel, "log level (dbg, inf, wrn, err)") - msgLogPath := flag.String("msglog", conf.DefaultMsgLogPath, "audit log path") - model := flag.String("model", conf.DefaultGoogleAIModel, "Google AI model (gemini-1.5-flash, gemini-2.0-flash-exp)") + listen := flag.String("listen", config.FlagListen, "http listen address") + agentsDir := flag.String("agents", config.FlagAgentsDir, "directory to store agent configurations") + logLevel := flag.String("level", config.FlagLogLevel, "log level (dbg, inf, wrn, err)") + msgLogPath := flag.String("msglog", config.FlagMsgLogPath, "audit log path") + model := flag.String("model", config.DefaultGoogleAIModel, "Google AI model (gemini-1.5-flash, gemini-2.0-flash-exp)") flag.Parse() server.GoogleAIKey = os.Getenv("GOOGLE_AI_KEY") @@ -27,11 +27,11 @@ func main() { server.GoogleAIModel = *model log.Setup(log.LogLevel(log.ParseLogLevel(*logLevel))) - log.T("main").Inff("AI-Agent version %s, %s mode (build %s)", conf.BuildVersion, conf.BuildMode, conf.BuildTime) - log.T("main").Inff("%s", conf.PackageCopyright) + log.T("main").Inff("AI-Agent version %s, %s mode (build %s)", config.BuildVersion, config.BuildMode, config.BuildTime) + log.T("main").Inff("%s", config.Copyright) log.SetupGin1() - if conf.BuildMode == "release" { + if config.BuildMode == "release" { gin.SetMode(gin.ReleaseMode) } diff --git a/web/tmpl.html b/web/agent.html similarity index 98% rename from web/tmpl.html rename to web/agent.html index 2fab869..bb81dd3 100644 --- a/web/tmpl.html +++ b/web/agent.html @@ -248,7 +248,7 @@
@@ -264,7 +264,8 @@
- 以上内容为 AI 生成,请注意辨别。
为了安全和审计需要,我们可能记录您与 AI 的对话内容和您的 IP 地址。请勿向模型分享敏感信息。 + {{.FooterHTML}}
+ 以上内容为 AI 生成,请注意辨别。
为了安全和审计需要,我们可能记录您与 AI 的对话内容和您的 IP 地址。请勿向 AI 分享敏感信息。