2025.07.01

SpringAI + Ollamaを使ったときにハマったこと

Spring AI と Ollama (Gemma3:12b)との組み合わせであれこれと実験していたところ、プロンプトの内容を完全に無視した応答になるという事象が。

Gemma3:12b 以外に、qwen3やllama3.1、mistralなども試してみたのですが、すべて同じ。

入力内容次第では、それなりの精度でプロンプトの内容を理解してくれますし、OllamaではなくGemini 2.5-Flash に問い合わせると欲しい結果が得られるという状況。

入力内容と結果の相関性をあれこれと考えてみると、単純に入力内容のデータが大きい時に意図しない結果が戻ってきている感じ。

Gemma3:12b の場合、Context としては 128K までサポートしているようで、入力データはさすがにそこまで大きくはないんですよね。

で、さらに調べてみると・・・ Spring AI + Ollama の場合、初期状態だとコンテキスト(パラメータ : spring.ai.ollama.chat.options.num-ctx )は 2048 になっているようで、その値を大きく(ひとまず、32768に)すると意図した結果が得られるようになりました。

Ollama で使用できるモデルのコンテキストサイズはまちまち(gemma3n : 32K, qwen3 : 40K, llama3.1 : 128K, mistral : 32K)なので、余裕を持たせて 2K を初期値にしているんですかね🤔

Gemma3:12b を使った場合、無条件で 128K とかを設定しても大丈夫なのかな・・・。

| | Comments (0)

2025.06.26

Spring AI を使用したコンソールアプリケーションを作ってみた

Spring AI を使用したコンソールアプリケーションを作ってみようとしてちょっとハマったのでメモ。

Spring Initializr で以下のような設定で新規プロジェクトを作る(ほぼほぼ初期値のまま作る)。

Springaiconsole01

プロジェクトの依存関係は以下の通り。Spring Boot バージョンは 3.4.7 を使用(3.5以降にすると SpringShell が使えなくなるので)。

  • Ollama
  • Spring Boot DevTools
  • Lombok
  • SpringShell (調べた感じだと、コンソールアプリを作る場合はこれを組み込むっぽい)

application.properties に Ollama で使用する model をセットする。

spring.ai.ollama.chat.options.model=gemma3:4b

とりあえず、問い合わせを行うソースを記述してみる。

package com.example.demo;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SpringAiConsoleTestApplication {

 public static void main(String[] args) {
  SpringApplication.run(SpringAiConsoleTestApplication.class, args);
 }

 @Bean
 public CommandLineRunner run() {
  return args -> {
   String response = chat("美味しいシュークリームの使い方は。");
   System.out.println(response);
  };
 }

 @Autowired
 private ChatClient.Builder chatClientBuilder;

 public String chat(String message) {
  ChatClient client = chatClientBuilder.build();
  String result = client
   .prompt()
   .user(message)
   .call()
   .content();
  return result;
 }
}

実行してみる。

***************************
APPLICATION FAILED TO START
***************************

Description:

Web application could not be started as there was no org.springframework.boot.web.reactive.server.ReactiveWebServerFactory bean defined in the context.

Action:

Check your application's dependencies for a supported reactive web server.
Check the configured web application type.

build.gradle をアレコレといじってみると、
  implementation 'org.springframework.ai:spring-ai-starter-model-ollama'
および
  mavenBom "org.springframework.ai:spring-ai-bom:${springAiVersion}"
があると、 Web Server を要求してしまうっぽい。

main の部分を以下のように記述すれば実行できた。

public static void main(String[] args) {
 SpringApplication application = new SpringApplication(SpringAiConsoleTestApplication.class);
 application.setWebApplicationType(WebApplicationType.NONE); // コンソールアプリケーションとして実行するため、WebApplicationTypeをNONEに設定
 application.run(args);
}

(結果の例(先頭数行を抜粋))

美味しいシュークリームの使い方はたくさんありますね!いくつかアイデアをまとめました。

**1. そのまま食べる**

* **シンプルに:** 表面の粉砂糖をはたいて、そのままでも美味しい!
* **アレンジ:**
* ブラックコーヒーや紅茶との相性は抜群。
* 季節のフルーツ(いちご、ぶどう、柑橘など)を添えても。
* ブランデーやラム酒を少量たらしても大人な味わいに。

**2. デザートとして**

Spring Framework 関連の使い方はまだまだ知識不足だなぁ・・・。
もっといろいろと勉強しないと。

| | Comments (0)

2025.06.01

Spring AIを試してみた(with Ollama)

環境は Pleiades All in One Eclipse 2025-03.20250319

何はともあれ、 Spring スタータープロジェクトを作成。依存関係として、 AI > Ollama を選択(なお、 Spring Boot バージョンとしては3.4以上が必要となる模様(3.3の場合、AIを選択することができない))。Ollama は特に設定を変更せずに標準ポートでリクエストを受け付けるようにしています。

application.yml に使用するモデルを記述する(今回は gemma3:4b を使ってみる)。

spring.ai.ollama.chat.options.model=gemma3:4b

コントローラーを作成する(雑・・・)

@Controller
public class AITestController {
 @Autowired
 private AITestChatService aiTestChatService;

 @RequestMapping(path = { "/chat" })
 @ResponseBody
 public String chat(@RequestParam("message") String message) {
  return aiTestChatService.chat(message);
 }
}

サービスを作成する(これも雑・・・)

@Service
public class AITestChatService {
 @Autowired
 private ChatClient.Builder chatClient;
 public String chat(String message) {
  return chatClient.build().prompt(message).call().content();
 }
}

試してみる

Springaitest

 

今回は Ollama を使ってみましたが、ChatGPTなどいろんなモデルに切り替えることができるようです(アプリケーション実装側が何を使っているか? というのをあまり意識しなくても良いようになってます)。

上手く作っていくと、いい感じの(LLMを活用した)アプリケーションを作るのがラクになるかもしれませんね。

| | Comments (0)

2025.03.23

Linuxで外部への通信をブロックしたい

Linux環境において、何らかの理由で外部への通信をブロックしたい場合のメモ

 

接続先ポート番号を指定してブロックする場合の例

firewall-cmd --direct --add-rule ipv4 filter OUTPUT 1 -p tcp --dport 8080 -o eth0 -j DROP

 

接続先ポートの範囲を指定してブロックする場合の例

firewall-cmd --direct --add-rule ipv4 filter OUTPUT 1 -p tcp --dport 20000:60000 -o eth0 -j DROP

 

設定内容を確認する

firewall-cmd --direct --get-all-rules

 

その他メモ

  • 複数指定する場合は OUTPUT のあとで指定する番号で優先順位を指定
  • インタフェースの指定は -o のあとで指定(上記の場合はeth0)
  • 範囲指定したあと、特定のポートのみを許可する場合は -j ACCEPT で指定

 

なお、sshで接続している場合、接続元側のポート番号をブロックするとsshが繋がらなくなりますので、範囲指定する場合は注意が必要(接続元側のポート番号は不定ですので)。

接続先IPアドレスを指定してブロックすることも可能なはずですが、試してません。。。

| | Comments (0)

2025.03.20

PostgreSQL 17 と Mattermost 10 の組み合わせでの日本語検索

久しぶり(4年ちょいぶり)に Mattermost の環境を作る機会があったので。

MattermostのDBとして PostgreSQL を使用した場合、特に何もしなければ日本語での検索は使い物にならないのは有名な話(?)。

以前は DB として MySQL を使用することで日本語での検索の設定をしやすかったのですが、 Mattermost v8.0 から、PostgreSQL を基本とするようになったことを考えると、やはり PostgreSQL で環境を構築しておいた方が良いかな、と。

となると、PostgreSQLでの日本語検索の話なのですが、いくつかのWebサイトを調べて環境を構築したときのメモをまとめました。

実験的な機能として Bleve を用いた検索のさせ方があるようなのですが、近いうちに削除されそうな感じ?

長らくメンテナンスされていない textsearch_ja ですが、PostgreSQL17の環境でも動くようなので、これを使うことにしました。なお、Mattermostとしても、PostgreSQLの default_text_search_config を前提とした動作になっているとのこと(以前のバージョンでは一部正しくない動作をしていたようなのですが、v10.6 では問題ないようです)。

MIRACLE LINUX 9 の環境で構築

 

PostgreSQLのインストール

  • PostgreSQL17を入れるためにリポジトリを追加。
    # dnf install https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
  • develパッケージをインストールするために、PowerToolsを有効化する(これを有効化しておかないと perl(IPC::Run) が見つからない、ということでインストールに失敗してしまう)
    # dnf config-manager --set-enabled 9-latest-PowerTools
  • インストール
    # dnf install postgresql17 postgresql17-server postgresql17-contrib postgresql17-devel
  • データベースの初期設定(ユーザーの追加やMattermost用の設定)は省略

 

textsearch_ja のビルド&組み込み

  • Mecabおよび ipadic などをインストールする
    # dnf install rpm-build mecab mecab-devel mecab-ipadic
  • textsearch_ja のソースを zip形式でダウンロードし、展開する(ここでは /work ディレクトリにダウンロードして作業する)
    # cd /work
    # unzip master.zip
    # cd textsearch_ja-master/
    # make PG_CONFIG=/usr/pgsql-17/bin/pg_config
    # export PATH="${PATH}:/usr/pgsql-17/bin"
    # make install
  • PostgreSQL で textsearch_ja を使えるようにする
    # psql -U postgres -f textsearch_ja--42.sql
  • PostgreSQL で Mattermost のデータベースに対して textsearch_ja を有効化する
    # psql -U postgres mattermost
    mattermost=# create extension textsearch_ja;
    mattermost=# CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_posts_message_txt_japanese ON posts USING gin(to_tsvector('japanese', message));
    mattermost=# DROP INDEX CONCURRENTLY IF EXISTS idx_posts_message_txt;
    mattermost=# ALTER INDEX idx_posts_message_txt_japanese RENAME TO idx_posts_message_txt;
  • PostgreSQL の設定ファイル (あえてディレクトリを変更していなければ /var/lib/pgsql/17/data/postgresql.conf になる)の default_text_search_config を設定する
    default_text_search_config = 'pg_catalog.japanese'
  • PostgreSQL を再起動

 

参考にしたURLなど

  • Mattermost公式サイト
  • PostgreSQL公式サイト
  • Migration guidelines from MySQL to PostgreSQL
    • From Mattermost v8.0, PostgreSQL is our database of choice for Mattermost to enhance the platform’s performance and capabilities.
  • Bleve search (experimental)
    • Bleve is a search engine that uses Lucene-style full-text search and indexing. This style of search and indexing helps overcome limitations of the default database search such as challenges with characters and advanced search capabilities.
    • Deprecate Bleve
      • We are looking to deprecate the Bleve Search functionality.
  • textsearch_ja
    • 形態素解析を使用した日本語全文検索の、PostgreSQL組み込み型モジュール。
    • 公式のものから派生したバージョン
      • PostgreSQL で配布されている最新版 : textsearch_ja-9.0.0
      • http://textsearch-ja.projects.pgfoundry.org/textsearch_ja.html が公式サイトだったようだが、現時点でページが存在しない・・・
  • PostgreSQL で textsearch_ja を使った日本語の全文検索
    • PostgreSQL で textsearch_ja を使って日本語のテキストを全文検索する方法のメモ。
    • ここでは Groonga リポジトリを追加していたが、私が構築した環境ではこのリポジトリは特に必要なかった(ディストリビューションによるものと思われる)
    • git clone を実行してソースコードを取得しているが、私は zip で取得
  • PostgreSQL installation troubleshooting
    • PostgresSQL full-text search fails to use indexes with non-english default_text_search_config
    • Mattermost uses default_text_search_config for full-text search in PostgresSQL databases, as opposed to a hardcoded text search config. However, indexes are still created with a hardcoded text search config (english) and as a result, full-text search may never use the indexes.
  • Mattermostバージョンアップにおける問題対応
    • Mattermost v6.2.2 の頃の内容
    • v5.35.2 において、 textsearch_ja が意図した動作をしなくなっているということで、原因となっているソースコードを記載
      // v5.35.2
      searchClause := fmt.Sprintf("to_tsvector('english', %s) @@ to_tsquery('english', :Terms)", searchType)
    • 今回対応するにあたって、念のため v10.6.0 のソースコードを確認したところ、上記の部分が以下のようになっていたので、textsearch_ja も問題なく動作する
      searchClause := fmt.Sprintf("to_tsvector('%[1]s', %[2]s) @@ to_tsquery('%[1]s', ?)", s.pgDefaultTextSearchConfig, searchType)

※リンク先の情報(および、参考にした情報)は 2025.03.20 時点での内容となります。将来的に、リンク切れが発生していたり、リンク先の内容が更新されていたりして、ここの記載内容と一致しない可能性があります。

※余談ですが、某AIに問い合わせてみると、pg_mecab というPostgreSQL用の拡張モジュールを使うと良い、という回答が得られました。Googleで検索しても全く見つからないのですが、どこかに存在する拡張モジュールなんですかね・・・??

| | Comments (0)

2023.06.14

ファイルの更新日をExif情報内の撮影日時に変更する(PowerShell)

PowerShellを使って、現在のフォルダ内にあるjpgファイルにおいて、ファイルの更新日を Exif の撮影日時に変更する。

ちょっと力業。

Add-Type -AssemblyName System.Drawing;
$files = Get-Item *.jpg;
foreach ($f in $files) {
$img = New-Object Drawing.Bitmap($f.FullName);
$byteAry = ($img.PropertyItems | Where-Object{$_.Id -eq 36867}).Value;
$img.Dispose();
$time = [System.Text.Encoding]::ASCII.GetString($byteAry);
$timeAry = $time.Split(": ");
$createTime = [String]::Format("{0}/{1}/{2} {3}:{4}:{5}",$timeAry[0],$timeAry[1],$timeAry[2],$timeAry[3],$timeAry[4],$timeAry[5]);
Set-ItemProperty $f -name LastWriteTime -value $createTime;
}

(実際には1行で・・・)

Add-Type -AssemblyName System.Drawing; $files = Get-Item *.jpg; foreach ($f in $files) { $img = New-Object Drawing.Bitmap($f.FullName); $byteAry = ($img.PropertyItems | Where-Object{$_.Id -eq 36867}).Value; $img.Dispose(); $time = [System.Text.Encoding]::ASCII.GetString($byteAry); $timeAry = $time.Split(": "); $createTime = [String]::Format("{0}/{1}/{2} {3}:{4}:{5}",$timeAry[0],$timeAry[1],$timeAry[2],$timeAry[3],$timeAry[4],$timeAry[5]); Set-ItemProperty $f -name LastWriteTime -value $createTime; }

 

CD-Rに焼いて店頭でプリントしようと思った際に、デフォルトのソート順が「更新日順」だったので、わかりやすいように更新日を撮影日に置き換えてしまえ、と・・・(普段はWeb経由でプリントを依頼するのですが、CD-Rに焼いて配布する必要が生じまして)。ちなみに選択できるソート順が「更新日(降順)」「更新日(昇順)」「ファイル名」でした。

多分、これでファイルを探しやすくなったのではないかな、と。

 

(参考)PowerShellメモ 画像のExif情報を読み込む

 

| | Comments (0)

2017.06.13

Kanboard

Kanban Project Management Software

ちょっと、面白そう。

今度試してみようかな。

そういえば、昔、Tugboat.GTDを少しだけ試してみたことがあったのを思いだした(^^;

|

2017.06.11

XML parsing failed : (413 Request Entity Too Large)

svn update(厳密には、TortoiseSVNからの作業)を行おうとすると、こんなエラーが。。。

XML parsing failed: (413 Request Entity Too Large)

文字通り、リクエストデータのxmlがデカすぎるってことのようなのですが、同様の報告は過去にもあったようで、413 Request Entity Too Largeの内容で一発で解決。

Subversionのリポジトリを割り当てているLocationディレクティブ内に、

LimitXMLRequestBody 0

を記述してApacheを再起動すると解決。

どの程度の大きさのデータをリクエストしてエラーになったのかが分からなかったので、いったん、チェックをしない設定にしました。ただ、セキュリティ等のことを考えると、実際にはチェックを行うようにすべきなんでしょうね。

参考) LimitXMLRequestBody ディレクティブ

|

2017.06.10

Fess

めっちゃひさしぶりに更新(笑

オープンソース全文検索サーバー Fess

5 分で簡単に構築可能な全文検索サーバー と記載されていますが、確かに、サクッと構築することができました(笑)。
Apache Solr で構築しようと考えていたのですが、セットアップやら、フロントエンドは自前で作る必要があったりするなど、そこそこ時間がかかりそう。その昔、Apache Luceneを作って、某アプリケーションに組み込む検索機能を構築したことはあるのですが、今はとにかくサクッと環境を構築したかったので。

» Continue reading

|

2013.01.31

0x82

Shift-JISにおいて 0x82 で始まる2バイト文字には、アルファベット、数字、ふりがなが含まれるんですね。

つまり、「ひらがな」というデータは、その気になれば(?)8バイトではなく4バイトで格納出来るってことに(笑

| | Comments (0) | TrackBack (0)

«KVMでネットワークをNATにしている場合