누군가 이걸 로컬에서 ollama와 함께 작동하게 해 본 적이 있나요?
저도 ollama와 함께 작동하도록 시도해 보고 있습니다. Discourse AI 플러그인이 사용하는 API가 Ollama과 호환되지 않는 것 같고, 설정을 어떻게 변경해도 API 요청이 바뀌지 않습니다.
ollama에서 정상적으로 작동하는 요청은 다음과 같습니다:
curl http://192.168.1.2:11434/api/generate -d '{
"model": "llama3.2",
"prompt": "Why is the sky blue?"
}'
그리고 위와 같은 요청 유형이 플러그인이 시도하는 유일한 것 같습니다. 즉,
curl http://192.168.1.2:11434/ \
-X POST \
-H 'Content-Type: application/json' \
-d '{"inputs":"<s>[INST] What is your favourite condiment? [/INST] Well, Im quite partial to a good squeeze of fresh lemon juice. It adds just the right amount of zesty flavour to whatever Im cooking up in the kitchen!</s> [INST] Do you have mayonnaise recipes? [/INST]","parameters":{"max_new_tokens":500, "temperature":0.5,"top_p": 0.9}}'
AI 챗봇은 ollama을 지원한다고 하지만, 이쪽에서도 응답을 받아낼 수 없습니다.
그러니까, 혹시 ollama과 함께 작동하게 만든 분이 있다면 어떤 설정을 사용했는지 공유해 주세요!
아마도 내가 너무 앞서 나간 것 같습니다. Discourse AI 플러그인에 설정을 하나도 하지 않은 상태에서 이 게시물의 RAG 지침을 따랐더니, Ollama에서 AI 챗봇 응답을 받을 수 있었거든요!
ollama와 함께 잘 작동합니다. 팀에서 여러 사람이 사용하고 있습니다.
좋네요. 구현 방법을 따라 할 수 있는 가이드가 어딘가에 있을까요?
채팅봇보다는 요약 및 기타 기능에 더 관심이 있습니다.
ETA: 이 설정은 작동하지 않습니다:
(여기서 호스트의 IP 주소를 마스킹했습니다.)
"Run Test"를 클릭하면 Internal Server Error가 발생합니다.
/logs에서 다음을 확인했습니다:
NameError (undefined local variable or method `tokenizer' for an instance of DiscourseAi::Completions::Dialects::ChatGpt)
app/controllers/application_controller.rb:427:in `block in with_resolved_locale'
app/controllers/application_controller.rb:427:in `with_resolved_locale'
lib/middleware/omniauth_bypass_middleware.rb:35:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
lib/middleware/anonymous_cache.rb:409:in `call'
lib/middleware/csp_script_nonce_injector.rb:12:in `call'
config/initializers/008-rack-cors.rb:14:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
lib/middleware/enforce_hostname.rb:24:in `call'
lib/middleware/processing_request.rb:12:in `call'
lib/middleware/request_tracker.rb:385:in `call'
선택하는 토크나이저에 관계없이 항상 이 문제가 발생합니다. 3.5.0beta1-dev (c1ee4e120e)에서 테스트하고 있습니다.
URL을 http://localhost:11434/v1/chat/completions으로 설정하세요
테스트는 여전히 내부 서버 오류로 실패하며, 로그 메시지도 동일합니다. 'tokenizer’가 정의되지 않은 로컬 변수라는 NameError가 발생하고 있습니다.
모델을 그대로 저장한 후, 페이지를 새로고침하고 LLM 편집 버튼을 통해 다시 들어와 새 테스트를 실행해 보세요.
결과가 동일합니다 - 몇 번이나 반복해 보았지만, 방금 다시 시도해 보았습니다.
일반적인 방식으로 설치를 진행했습니다 - app.yml 파일에 추가하고 ./launcher rebuild app을 실행했습니다.
추가한 줄은 다음과 같습니다:
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- sudo -E -u discourse git clone https://github.com/discourse/discourse-ai.git
(다른 플러그인들은 목록에서 제거했지만, 이 항목이 yml 파일에서 어디에 위치하는지 확인할 수 있도록 yml 구성 요소는 그대로 두었습니다.)
내일 로컬 Ollama 설정을 복구해서 여기서 보고하겠습니다.
다음과 같이 실행했습니다:
ollama serve
ollama run phi4
# 테스트
curl http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "phi4",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "How much is 1+1?"
}
]
}' -s | jq .choices[].message.content
"The sum of 1 + 1 is 2. \n\nIn basic arithmetic, when you add one unit to another single unit, the total number becomes two units. This operation is part of fundamental addition principles used in mathematics. Is there anything else I can help with regarding math or any other topic?"
Helper에서 테스트했습니다
테스트해 주셔서 감사합니다.
제 설정에는 추가 옵션(스트리밍 완료 비활성화)이 있는 것 같습니다. 모델 선택 때문에 문제가 발생하는 것일까요? (deepseek-r1:32b를 설치해 두었습니다.)
curl http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-r1:32b",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "How much is 1+1?"
}
]
}' -s | jq .choices[].message.content
"<think>\nAlright, I'm trying to figure out how much 1 plus 1 equals. Okay, so let's break this down step by step even though it seems simple.\n\nFirst, I know that addition is combining two numbers to get a total sum. So, when we say 1 + 1, we're essentially putting together one object and another object to see how many we have in total.\n\nLet me visualize it: imagine I have one apple in my left hand and another apple in my right hand. If I put them together, how many apples do I have? It should be two apples, right?\n\nAnother way to think about it is using a number line. Starting at the number 1, if I move forward by one more step, where do I land? That's right, on the number 2.\n\nI can also use my fingers to count. Hold up one finger on my left hand and another on my right. Now, count them all: one, two. So that gives me a total of two fingers, which means 1 + 1 = 2.\n\nMaybe I should check if there's another perspective or method. For instance, in binary, the number system used by computers, 1 + 1 equals 10 because it carries over after reaching 2 (which is represented as 10). But that's a different context. In standard base-10 arithmetic, which we use daily, 1 + 1 remains 2.\n\nLet me also consider the concept of sets. If I have a set containing one element and another set with one element, combining them would result in a set with two elements. That reinforces that 1 + 1 equals 2.\n\nI might wonder if there's any scenario where 1 + 1 doesn't equal 2. But within the realm of basic arithmetic and mathematics as we learn it, the answer is consistently two.\n\nTo make sure I'm not missing anything, maybe I should look into some mathematical proofs or principles that confirm this. For example, in Peano axioms, which form the foundation of arithmetic, the idea of adding 1 to 1 would follow the axiom that every natural number has a successor, and 2 is defined as the successor of 1.\n\nTherefore, putting all these thoughts together—visualizing objects, using a number line, counting fingers, considering sets, and even touching on mathematical axioms—it all points towards 1 + 1 equaling 2.\n\n\nThe result of adding 1 and 1 together is 2. This can be seen in simple arithmetic and various ways of visualizing the problem.\n\n**Answer:** \n$1 + 1 = \\boxed{2}$"
비슷한 결과를 얻었습니다. 다만 이 특정 모델에서는 <think> 태그가 출력되네요. 따라서 이 용도에 이 모델이 적합하지 않을 수 있습니다.
방금 제 설치를 다시 구축(즉, ./launcher rebuild app)하고 모든 것이 최신 상태인지 확인했습니다. 업데이트 페이지에 "모두 최신 상태"라고 표시됩니다.
deepseek-r1:32b나 phi4(이것도 설치하고 테스트했습니다)를 선택하더라도 브라우저에서 여전히 내부 서버 오류 응답을 받습니다.
하지만 로그에서 새로운 무언가를 발견했습니다.
FinalDestination::SSRFDetector::DisallowedIpError (FinalDestination: all resolved IPs were disallowed) lib/final_destination/ssrf_detector.rb:105:in 'lookup_and_filter_ips' lib/final_destination/http'
lib/final_destination/ssrf_detector.rb:105:in `lookup_and_filter_ips'
lib/final_destination/http.rb:15:in `connect'
net-http (0.6.0) lib/net/http.rb:1642:in `do_start'
net-http (0.6.0) lib/net/http.rb:1631:in `start'
net-http (0.6.0) lib/net/http.rb:1070:in `start'
plugins/discourse-ai/lib/completions/endpoints/base.rb:105:in `perform_completion!'
plugins/discourse-ai/lib/completions/endpoints/open_ai.rb:44:in `perform_completion!'
plugins/discourse-ai/lib/completions/llm.rb:281:in `generate'
plugins/discourse-ai/lib/configuration/llm_validator.rb:36:in `run_test'
plugins/discourse-ai/app/controllers/discourse_ai/admin/ai_llms_controller.rb:128:in `test'
actionpack (7.2.2.1) lib/action_controller/metal/basic_implicit_render.rb:8:in `send_action'
actionpack (7.2.2.1) lib/abstract_controller/base.rb:226:in `process_action'
actionpack (7.2.2.1) lib/action_controller/metal/rendering.rb:193:in `process_action'
actionpack (7.2.2.1) lib/abstract_controller/callbacks.rb:261:in `block in process_action'
activesupport (7.2.2.1) lib/active_support/callbacks.rb:121:in `block in run_callbacks'
app/controllers/application_controller.rb:427:in `block in with_resolved_locale'
i18n (1.14.7) lib/i18n.rb:353:in `with_locale'
app/controllers/application_controller.rb:427:in `with_resolved_locale'
activesupport (7.2.2.1) lib/active_support/callbacks.rb:130:in `block in run_callbacks'
activesupport (7.2.2.1) lib/active_support/callbacks.rb:141:in `run_callbacks'
actionpack (7.2.2.1) lib/abstract_controller/callbacks.rb:260:in `process_action'
actionpack (7.2.2.1) lib/action_controller/metal/rescue.rb:27:in `process_action'
actionpack (7.2.2.1) lib/action_controller/metal/instrumentation.rb:77:in `block in process_action'
activesupport (7.2.2.1) lib/active_support/notifications.rb:210:in `block in instrument'
activesupport (7.2.2.1) lib/active_support/notifications/instrumenter.rb:58:in `instrument'
activesupport (7.2.2.1) lib/active_support/notifications.rb:210:in `instrument'
actionpack (7.2.2.1) lib/action_controller/metal/instrumentation.rb:76:in `process_action'
actionpack (7.2.2.1) lib/action_controller/metal/params_wrapper.rb:259:in `process_action'
activerecord (7.2.2.1) lib/active_record/railties/controller_runtime.rb:39:in `process_action'
actionpack (7.2.2.1) lib/abstract_controller/base.rb:163:in `process'
actionview (7.2.2.1) lib/action_view/rendering.rb:40:in `process'
rack-mini-profiler (3.3.1) lib/mini_profiler/profiling_methods.rb:115:in `block in profile_method'
actionpack (7.2.2.1) lib/action_controller/metal.rb:252:in `dispatch'
actionpack (7.2.2.1) lib/action_controller/metal.rb:335:in `dispatch'
actionpack (7.2.2.1) lib/action_dispatch/routing/route_set.rb:67:in `dispatch'
actionpack (7.2.2.1) lib/action_dispatch/routing/route_set.rb:50:in `serve'
actionpack (7.2.2.1) lib/action_dispatch/routing/mapper.rb:32:in `block in <class:Constraints>'
actionpack (7.2.2.1) lib/action_dispatch/routing/mapper.rb:62:in `serve'
actionpack (7.2.2.1) lib/action_dispatch/journey/router.rb:53:in `block in serve'
actionpack (7.2.2.1) lib/action_dispatch/journey/router.rb:133:in `block in find_routes'
actionpack (7.2.2.1) lib/action_dispatch/journey/router.rb:126:in `each'
actionpack (7.2.2.1) lib/action_dispatch/journey/router.rb:126:in `find_routes'
actionpack (7.2.2.1) lib/action_dispatch/journey/router.rb:34:in `serve'
actionpack (7.2.2.1) lib/action_dispatch/routing/route_set.rb:896:in `call'
lib/middleware/omniauth_bypass_middleware.rb:35:in `call'
rack (2.2.11) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.2.11) lib/rack/conditional_get.rb:27:in `call'
rack (2.2.11) lib/rack/head.rb:12:in `call'
actionpack (7.2.2.1) lib/action_dispatch/http/permissions_policy.rb:38:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
lib/middleware/anonymous_cache.rb:409:in `call'
lib/middleware/csp_script_nonce_injector.rb:12:in `call'
config/initializers/008-rack-cors.rb:14:in `call'
rack (2.2.11) lib/rack/session/abstract/id.rb:266:in `context'
rack (2.2.11) lib/rack/session/abstract/id.rb:260:in `call'
actionpack (7.2.2.1) lib/action_dispatch/middleware/cookies.rb:704:in `call'
actionpack (7.2.2.1) lib/action_dispatch/middleware/callbacks.rb:31:in `block in call'
activesupport (7.2.2.1) lib/active_support/callbacks.rb:101:in `run_callbacks'
actionpack (7.2.2.1) lib/action_dispatch/middleware/callbacks.rb:30:in `call'
actionpack (7.2.2.1) lib/action_dispatch/middleware/debug_exceptions.rb:31:in `call'
actionpack (7.2.2.1) lib/action_dispatch/middleware/show_exceptions.rb:32:in `call'
logster (2.20.1) lib/logster/middleware/reporter.rb:40:in `call'
railties (7.2.2.1) lib/rails/rack/logger.rb:41:in `call_app'
railties (7.2.2.1) lib/rails/rack/logger.rb:29:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
actionpack (7.2.2.1) lib/action_dispatch/middleware/request_id.rb:33:in `call'
lib/middleware/enforce_hostname.rb:24:in `call'
rack (2.2.11) lib/rack/method_override.rb:24:in `call'
actionpack (7.2.2.1) lib/action_dispatch/middleware/executor.rb:16:in `call'
rack (2.2.11) lib/rack/sendfile.rb:110:in `call'
rack-mini-profiler (3.3.1) lib/mini_profiler.rb:334:in `call'
lib/middleware/processing_request.rb:12:in `call'
message_bus (4.3.9) lib/message_bus/rack/middleware.rb:60:in `call'
lib/middleware/request_tracker.rb:385:in `call'
actionpack (7.2.2.1) lib/action_dispatch/middleware/remote_ip.rb:96:in `call'
railties (7.2.2.1) lib/rails/engine.rb:535:in `call'
railties (7.2.2.1) lib/rails/railtie.rb:226:in `public_send'
railties (7.2.2.1) lib/rails/railtie.rb:226:in `method_missing'
rack (2.2.11) lib/rack/urlmap.rb:74:in `block in call'
rack (2.2.11) lib/rack/urlmap.rb:58:in `each'
rack (2.2.11) lib/rack/urlmap.rb:58:in `call'
unicorn (6.1.0) lib/unicorn/http_server.rb:634:in `process_client'
unicorn (6.1.0) lib/unicorn/http_server.rb:739:in `worker_loop'
unicorn (6.1.0) lib/unicorn/http_server.rb:547:in `spawn_missing_workers'
unicorn (6.1.0) lib/unicorn/http_server.rb:143:in `start'
unicorn (6.1.0) bin/unicorn:128:in `<top (required)>'
vendor/bundle/ruby/3.3.0/bin/unicorn:25:in `load'
vendor/bundle/ruby/3.3.0/bin/unicorn:25:in `<main>'
이 Discourse 설치 환경은 비교적 최신이며, IP 주소 차단 설정을 한 적도 없습니다. 또한 유일한 사용자입니다. ollama는 Docker 컨테이너에서 실행하고 있지만, 이는 문제가 되지 않을 것입니다. 다른 Docker 컨테이너의 open-webui를 이 인스턴스와 함께 사용하고 있으며 정상적으로 작동합니다. “localhost” 대신 로컬 IP 주소를 사용하고 있지만, "localhost"를 사용해도 동작이 다르지 않습니다.
여기서 무슨 일이 일어나고 있는지 파악하는 데 시간을 내어 도와주셔서 감사합니다.
ETA: Discourse Docker 컨테이너에 jq를 설치하고 curl 명령을 실행했습니다(localhost 대신 제 로컬 IP 주소를 사용). 그 결과 실행이 성공적으로 이루어졌습니다. 따라서 컨테이너 간 연결성은 확보되어 있고 URL도 정확합니다.
이것은 우리의 기본 SSRF 보호 기능이 작동하고 있다는 의미입니다. DISCOURSE_ALLOWED_INTERNAL_HOSTS 환경 변수를 통해 예외를 추가할 수 있습니다.
Discourse가 내부로 간주되는 IP에 도달하려고 할 때 트리거됩니다.
좋아요, 그걸로 해결됐네요. ENV 변수 대신 설정에서 처리했는데, 이제 테스트가 통과했어요. 도움 주셔서 다시 한번 감사드립니다!


